diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cc59e97
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,108 @@
+
+# Created by https://www.gitignore.io/api/java,intellij+iml
+# Edit at https://www.gitignore.io/?templates=java,intellij+iml
+
+### Intellij+iml ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij+iml Patch ###
+# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
+
+*.iml
+modules.xml
+.idea/misc.xml
+*.ipr
+
+### Java ###
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# End of https://www.gitignore.io/api/java,intellij+iml
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..eae676c
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..a156f52
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
new file mode 100644
index 0000000..1c65975
--- /dev/null
+++ b/dependency-reduced-pom.xml
@@ -0,0 +1,116 @@
+
+
+ 4.0.0
+ net.seanomik
+ energeticstorage
+ EnergeticStorage
+ 0.1-SNAPSHOT
+
+ clean package
+
+
+ true
+ src/main/resources
+
+
+
+
+ maven-compiler-plugin
+ 3.7.0
+
+
+ ${java.version}
+
+
+
+ maven-shade-plugin
+ 3.1.0
+
+
+ package
+
+ shade
+
+
+ D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.2_\plugins\EnergeticStorage-MC-v1.15.X-v${project.version}.jar
+ false
+
+
+
+
+
+ maven-shade-plugin
+ 3.2.1
+
+
+ shade
+ package
+
+ shade
+
+
+
+
+
+
+ de.tr7zw.changeme.nbtapi
+ de.tr7zw.nbtapi
+
+
+
+
+
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+ sonatype
+ https://oss.sonatype.org/content/groups/public/
+
+
+ codemc-repo
+ https://repo.codemc.org/repository/maven-public/
+
+
+ maven-repository
+ file:///${project.basedir}/maven-repository
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.15.2-R0.1-SNAPSHOT
+ provided
+
+
+ commons-lang
+ commons-lang
+
+
+ guava
+ com.google.guava
+
+
+ gson
+ com.google.code.gson
+
+
+ bungeecord-chat
+ net.md-5
+
+
+ snakeyaml
+ org.yaml
+
+
+
+
+
+ 1.8
+ UTF-8
+
+
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.jar.md5 b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.jar.md5
new file mode 100644
index 0000000..5ea4d67
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.jar.md5
@@ -0,0 +1 @@
+7afa199ad36692812fb6cb1dd0d4a6c3
\ No newline at end of file
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.jar.sha1 b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.jar.sha1
new file mode 100644
index 0000000..53790d7
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.jar.sha1
@@ -0,0 +1 @@
+1e4cb543315c99cf8407fcaa7de27cfb24a5bd11
\ No newline at end of file
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom
new file mode 100644
index 0000000..64bfe21
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom
@@ -0,0 +1,8 @@
+
+
+ 4.0.0
+ com.github.shynixn.headdatabase
+ hdb-api
+ 1.0
+
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom.md5 b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom.md5
new file mode 100644
index 0000000..761579d
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom.md5
@@ -0,0 +1 @@
+8b707a9cd5cbdae2e4f38859f256bf56
\ No newline at end of file
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom.sha1 b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom.sha1
new file mode 100644
index 0000000..bc5c170
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/1.0/hdb-api-1.0.pom.sha1
@@ -0,0 +1 @@
+ffd4d3695ad218788c4ec4d687498d34f5afadce
\ No newline at end of file
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml b/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml
new file mode 100644
index 0000000..f8d5aaa
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml
@@ -0,0 +1,12 @@
+
+
+ com.github.shynixn.headdatabase
+ hdb-api
+
+ 1.0
+
+ 1.0
+
+ 20200331035834
+
+
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml.md5 b/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml.md5
new file mode 100644
index 0000000..c34ba6f
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml.md5
@@ -0,0 +1 @@
+f1670febb88bf8bc170ef0ba7ea24075
\ No newline at end of file
diff --git a/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml.sha1 b/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml.sha1
new file mode 100644
index 0000000..d19bf9f
--- /dev/null
+++ b/maven-repository/com/github/shynixn/headdatabase/hdb-api/maven-metadata.xml.sha1
@@ -0,0 +1 @@
+542b3d81e8887008a78abf7c14fb2b498fd89877
\ No newline at end of file
diff --git a/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.jar.md5 b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.jar.md5
new file mode 100644
index 0000000..78340b1
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.jar.md5
@@ -0,0 +1 @@
+0ac17404662c14763681fa66966d78e3
\ No newline at end of file
diff --git a/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.jar.sha1 b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.jar.sha1
new file mode 100644
index 0000000..f386abb
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.jar.sha1
@@ -0,0 +1 @@
+47d3169c630ba6ffe89c0529728a16917f4d7461
\ No newline at end of file
diff --git a/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom
new file mode 100644
index 0000000..bdfef67
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom
@@ -0,0 +1,8 @@
+
+
+ 4.0.0
+ me.darkolythe
+ customrecipeapi
+ 1.2.3
+
diff --git a/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom.md5 b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom.md5
new file mode 100644
index 0000000..cdfd226
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom.md5
@@ -0,0 +1 @@
+e824dc420f2a4d99de3ff215cb7059eb
\ No newline at end of file
diff --git a/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom.sha1 b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom.sha1
new file mode 100644
index 0000000..62d5720
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/1.2.3/customrecipeapi-1.2.3.pom.sha1
@@ -0,0 +1 @@
+33e68e43923055db023fb67dbdd08b7857a9276d
\ No newline at end of file
diff --git a/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml b/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml
new file mode 100644
index 0000000..de99d01
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml
@@ -0,0 +1,12 @@
+
+
+ me.darkolythe
+ customrecipeapi
+
+ 1.2.3
+
+ 1.2.3
+
+ 20200403192517
+
+
diff --git a/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml.md5 b/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml.md5
new file mode 100644
index 0000000..11353d4
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml.md5
@@ -0,0 +1 @@
+8f5304e0de19ce4868b10abb2804f858
\ No newline at end of file
diff --git a/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml.sha1 b/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml.sha1
new file mode 100644
index 0000000..9426da6
--- /dev/null
+++ b/maven-repository/me/darkolythe/customrecipeapi/maven-metadata.xml.sha1
@@ -0,0 +1 @@
+33bb53f687e7a2cf59509d398341828bee14c9df
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..16d37e8
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,123 @@
+
+
+ 4.0.0
+
+ net.seanomik
+ energeticstorage
+ 0.1-SNAPSHOT
+ jar
+
+ EnergeticStorage
+
+
+ 1.8
+ UTF-8
+
+
+
+ clean package
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.7.0
+
+
+ ${java.version}
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.1.0
+
+
+ shade
+ package
+
+ shade
+
+
+ D:\Code\java\spigotPlugins\_TEST_SERVER_1.15.2_\plugins\EnergeticStorage-MC-v1.15.X-v${project.version}.jar
+ false
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.1
+
+
+ shade
+ package
+
+ shade
+
+
+
+
+
+
+ de.tr7zw.changeme.nbtapi
+ de.tr7zw.nbtapi
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+ sonatype
+ https://oss.sonatype.org/content/groups/public/
+
+
+ codemc-repo
+ https://repo.codemc.org/repository/maven-public/
+ default
+
+
+ maven-repository
+ file:///${project.basedir}/maven-repository
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+
+
+
+ org.spigotmc
+ spigot
+ 1.15.2-R0.1-SNAPSHOT
+ provided
+
+
+ de.tr7zw
+ item-nbt-api
+ 2.3.0
+ compile
+
+
+ com.github.WesJD.AnvilGUI
+ anvilgui
+ 7a87a9dd65
+
+
+
diff --git a/src/main/java/net/seanomik/energeticstorage/EnergeticStorage.java b/src/main/java/net/seanomik/energeticstorage/EnergeticStorage.java
new file mode 100644
index 0000000..76d37b8
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/EnergeticStorage.java
@@ -0,0 +1,71 @@
+package net.seanomik.energeticstorage;
+
+import net.seanomik.energeticstorage.commands.ESGiveCommand;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.listeners.BlockBreakListener;
+import net.seanomik.energeticstorage.listeners.BlockPlaceListener;
+import net.seanomik.energeticstorage.listeners.PlayerInteractListener;
+import net.seanomik.energeticstorage.utils.ItemRecipies;
+import net.seanomik.energeticstorage.utils.Reference;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.plugin.java.JavaPlugin;
+
+public final class EnergeticStorage extends JavaPlugin implements Listener {
+ private static EnergeticStorage plugin;
+
+ @Override
+ public void onEnable() {
+ plugin = this;
+
+ registerCommands();
+ registerListener();
+ ItemRecipies.registerRecipes();
+
+ PlayersFile.getConfig().saveDefaultConfig();
+
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ cachePlayersSystems(player);
+ }
+ }
+
+ private void registerCommands() {
+ getCommand("esgive").setExecutor(new ESGiveCommand());
+ }
+
+ private void registerListener() {
+ getServer().getPluginManager().registerEvents(Reference.ES_TERMINAL_GUI, this);
+ getServer().getPluginManager().registerEvents(Reference.ES_SYSTEM_GUI, this);
+ getServer().getPluginManager().registerEvents(Reference.ES_DRIVE_GUI, this);
+ getServer().getPluginManager().registerEvents(Reference.ES_SYSTEM_SECURITY_GUI, this);
+ getServer().getPluginManager().registerEvents(new PlayerInteractListener(), this);
+ getServer().getPluginManager().registerEvents(new BlockBreakListener(), this);
+ getServer().getPluginManager().registerEvents(new BlockPlaceListener(), this);
+ getServer().getPluginManager().registerEvents(this, this);
+ }
+
+ public void cachePlayersSystems(Player player) {
+ if (PlayersFile.doesPlayerHaveSystem(player.getUniqueId())) {
+ Reference.ES_SYSTEMS.put(player.getUniqueId(), PlayersFile.getPlayersSystems(player.getUniqueId()));
+ }
+ }
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+
+ cachePlayersSystems(player);
+ }
+
+ @Override
+ public void onDisable() {
+ // Plugin shutdown logic
+ }
+
+ public static EnergeticStorage getPlugin() {
+ return plugin;
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/Skulls.java b/src/main/java/net/seanomik/energeticstorage/Skulls.java
new file mode 100644
index 0000000..3fc1b34
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/Skulls.java
@@ -0,0 +1,58 @@
+package net.seanomik.energeticstorage;
+
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.SkullMeta;
+
+import java.lang.reflect.Field;
+import java.util.UUID;
+
+public enum Skulls {
+
+ LeftGreenArrow("LeftGreenArrow", 0, "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTRjNDE3NDZhZjU1N2EyNGJlOGEwOTAzNjlhNTkxYWU2M2Q1Y2U5YzRiZjQwNWQzNTQyNDdkODEwYzdjNyJ9fX0=", "5da5509d-136d-4716-bc2d-d04f82058e91"),
+ UpGreenArrow("UpGreenArrow", 1, "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjIyMWRhNDQxOGJkM2JmYjQyZWI2NGQyYWI0MjljNjFkZWNiOGY0YmY3ZDRjZmI3N2ExNjJiZTNkY2IwYjkyNyJ9fX0=", "fb271319-5c42-4f5d-9389-e89ca7caf96a"),
+ Computer("Computer", 2, "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzhhMGM1MDg5N2FjZmM2ZmMzNDUxODUwOGQ5NDBlY2Q1Mjg0NmI3Zjc2NGRmZTI0YTU3ZjZmYmNiNDUzNTE5NCJ9fX0=", "0676e961-2d31-4819-82be-c1b499f00f8f");
+
+ private ItemStack item;
+ private String name;
+ private String texture;
+
+ Skulls(String name, int id, String texture, String uuid) {
+ item = createSkull(texture, name);
+ this.texture = texture;
+ this.name = name;
+ }
+
+ private ItemStack createSkull (String url, String name) {
+ ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1, (short) 3);
+ if (url.isEmpty()) return head;
+
+ SkullMeta headMeta = (SkullMeta) head.getItemMeta();
+ GameProfile gameProfile = new GameProfile(UUID.randomUUID(), null);
+
+ gameProfile.getProperties().put("textures", new Property("textures", url));
+
+ try {
+ Field profileField = headMeta.getClass().getDeclaredField("profile");
+ profileField.setAccessible(true);
+ profileField.set(headMeta, gameProfile);
+ } catch (IllegalArgumentException | NoSuchFieldException | SecurityException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ head.setItemMeta(headMeta);
+ return head;
+ }
+
+ public ItemStack getItemStack() {
+ return item;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getTexture() { return texture; }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/commands/ESGiveCommand.java b/src/main/java/net/seanomik/energeticstorage/commands/ESGiveCommand.java
new file mode 100644
index 0000000..8acde64
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/commands/ESGiveCommand.java
@@ -0,0 +1,142 @@
+package net.seanomik.energeticstorage.commands;
+
+import net.seanomik.energeticstorage.EnergeticStorage;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.utils.ItemConstructor;
+import net.seanomik.energeticstorage.utils.PermissionChecks;
+import net.seanomik.energeticstorage.utils.Reference;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.sql.Ref;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ESGiveCommand implements TabExecutor {
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ List tab = new ArrayList<>();
+
+ switch (args.length) {
+ case 1:
+ tab.addAll(Arrays.asList("drive", "system"));
+ break;
+ case 2:
+ if (args[0].equals("drive")) {
+ tab.addAll(Arrays.asList("1k", "4k", "16k", "64k"));
+ } else if (args[0].equals("system")) {
+ for (Player player : Bukkit.getServer().getOnlinePlayers()) {
+ tab.add(player.getDisplayName());
+ }
+ }
+ break;
+ case 3:
+ if (args[0].equals("drive")) {
+ for (Player player : Bukkit.getServer().getOnlinePlayers()) {
+ tab.add(player.getDisplayName());
+ }
+ }
+
+ break;
+ }
+
+ return tab;
+ }
+
+ private String generateCommandUsage(String[] args) {
+ if (args.length > 0) {
+ if (args[0].equals("drive")) {
+ return Reference.PREFIX + "Usage: /esgive drive [1k, 4k, 16k, 64k] (player)";
+ }
+
+ return Reference.PREFIX + "Usage: /esgive [drive/system] [1k, 4k, 16k, 64k] (player)";
+ } else {
+ return Reference.PREFIX + "Usage: /esgive [drive/system] [1k, 4k, 16k, 64k] (player)";
+ }
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!PermissionChecks.canESGive(sender)) {
+ sender.sendMessage(Reference.PREFIX + ChatColor.RED + "You don't have permission for this command!");
+
+ return true;
+ }
+
+ switch (args[0]) { // Switch on item type
+ case "save":
+ PlayersFile.savePlayerSystems(Reference.ES_SYSTEMS.get(((Player) sender).getUniqueId()));
+ sender.sendMessage("Saved systems!");
+ break;
+ case "system":
+ Player p = (Player) sender;
+
+ if (args.length == 2) {
+ if (!PermissionChecks.canESGiveOthers(sender)) {
+ sender.sendMessage(Reference.PREFIX + ChatColor.RED + "You don't have permission to give an item to another player!");
+
+ return true;
+ }
+
+ Player player = Bukkit.getPlayer(args[1]);
+ if (player != null) {
+ player.getInventory().addItem(ItemConstructor.createSystemBlock());
+
+ sender.sendMessage(Reference.PREFIX + ChatColor.GREEN + "Gave an ES System to " + player.getDisplayName());
+ } else {
+ sender.sendMessage(Reference.PREFIX + ChatColor.RED + "Player does not exist or is not online!");
+ }
+ } else if (args.length == 1) {
+ p.getInventory().addItem(ItemConstructor.createSystemBlock());
+ }
+ break;
+ case "drive":
+ if (args.length < 2) {
+ sender.sendMessage(generateCommandUsage(args));
+ break;
+ }
+
+ if (args[1].equals("1k") || args[1].equals("4k") || args[1].equals("16k") || args[1].equals("64k")) {
+ int size = Integer.parseInt(args[1].replace("k", "")) * 1024;
+
+ if (args.length == 3) {
+ if (!PermissionChecks.canESGiveOthers(sender)) {
+ sender.sendMessage(Reference.PREFIX + ChatColor.RED + "You don't have permission to give an item to another player!");
+
+ return true;
+ }
+
+ Player player = Bukkit.getPlayer(args[2]);
+ if (player != null) {
+ player.getInventory().addItem(ItemConstructor.createDrive(size, 0, 0));
+
+ sender.sendMessage(Reference.PREFIX + ChatColor.GREEN + "Gave an ES System to " + player.getDisplayName());
+ } else {
+ sender.sendMessage(Reference.PREFIX + ChatColor.RED + "Player does not exist or is not online!");
+ }
+ } else {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ player.getInventory().addItem(ItemConstructor.createDrive(size, 0, 0));
+ } else {
+ sender.sendMessage(Reference.PREFIX + ChatColor.RED + "Supply a player to run this command!");
+ sender.sendMessage(generateCommandUsage(args));
+ }
+ }
+ } else {
+ sender.sendMessage(generateCommandUsage(args));
+ }
+
+ break;
+ }
+
+ return true;
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/files/ConfigFile.java b/src/main/java/net/seanomik/energeticstorage/files/ConfigFile.java
new file mode 100644
index 0000000..9e5297f
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/files/ConfigFile.java
@@ -0,0 +1,89 @@
+package net.seanomik.energeticstorage.files;
+
+import net.seanomik.energeticstorage.EnergeticStorage;
+import org.bukkit.ChatColor;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+
+public class ConfigFile extends YamlConfiguration {
+ private static ConfigFile config;
+ private EnergeticStorage plugin;
+ private File configFile;
+
+ public static ConfigFile getConfig() {
+ if (ConfigFile.config == null) {
+ ConfigFile.config = new ConfigFile();
+ }
+ return ConfigFile.config;
+ }
+
+ public ConfigFile() {
+ this.plugin = (EnergeticStorage) EnergeticStorage.getPlugin((Class) EnergeticStorage.class);
+ this.configFile = new File(this.plugin.getDataFolder(), "config.yml");
+ this.saveDefault();
+ this.reload();
+ }
+
+ public void reload() {
+ try {
+ super.load(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void save() {
+ try {
+ super.save(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void saveDefault() {
+ this.plugin.saveResource("config.yml", false);
+ }
+
+ public void saveConfig() {
+ try {
+ super.save(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void reloadConfig() {
+ try {
+ super.load(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void saveDefaultConfig() {
+ try {
+ this.plugin.saveDefaultConfig();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Auto replace alternate color codes.
+ @Override
+ public String getString(String path) {
+ // Only attempt to translate if the text is not empty.
+ return (super.getString(path).isEmpty()) ? super.getString(path) : ChatColor.translateAlternateColorCodes('&', super.getString(path));
+ }
+
+ public static int getMaxTypes() {
+ return getConfig().getInt("driveMaxTypes");
+ }
+}
+
+
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/energeticstorage/files/PlayersFile.java b/src/main/java/net/seanomik/energeticstorage/files/PlayersFile.java
new file mode 100644
index 0000000..99c34b0
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/files/PlayersFile.java
@@ -0,0 +1,220 @@
+package net.seanomik.energeticstorage.files;
+
+import com.google.gson.JsonParser;
+import net.seanomik.energeticstorage.EnergeticStorage;
+import net.seanomik.energeticstorage.objects.ESDrive;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.ItemSerialization;
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.StringEscapeUtils;
+import org.bukkit.inventory.ItemStack;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.io.File;
+import java.util.*;
+
+public class PlayersFile extends YamlConfiguration {
+ private static PlayersFile config;
+ private EnergeticStorage plugin;
+ private File configFile;
+
+ public static PlayersFile getConfig() {
+ if (PlayersFile.config == null) {
+ PlayersFile.config = new PlayersFile();
+ }
+ return PlayersFile.config;
+ }
+
+ public PlayersFile() {
+ this.plugin = (EnergeticStorage) EnergeticStorage.getPlugin((Class) EnergeticStorage.class);
+ this.configFile = new File(this.plugin.getDataFolder(), "players.yml");
+ this.saveDefault();
+ this.reload();
+ }
+
+ public void reload() {
+ try {
+ super.load(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void save() {
+ try {
+ super.save(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void saveDefault() {
+ this.plugin.saveResource("players.yml", false);
+ }
+
+ public void saveConfig() {
+ try {
+ super.save(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void reloadConfig() {
+ try {
+ super.load(this.configFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void saveDefaultConfig() {
+ try {
+ this.plugin.saveDefaultConfig();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Auto replace alternate color codes.
+ @Override
+ public String getString(String path) {
+ // Only attempt to translate if the text is not empty.
+ return (super.getString(path) == null || super.getString(path).isEmpty()) ? super.getString(path) : ChatColor.translateAlternateColorCodes('&', super.getString(path));
+ }
+
+ public static boolean doesPlayerHaveSystem(UUID uuid) {
+ return getConfig().contains("players." + uuid + ".systems");
+ }
+
+ public static List getPlayersSystems(UUID uuid) {
+ List systems = new ArrayList<>();
+ for (String systemUUID : getConfig().getConfigurationSection("players." + uuid + ".systems").getKeys(false)) {
+ String systemPath = "players." + uuid + ".systems." + systemUUID + ".";
+ List drives = new ArrayList<>();
+
+ if (getConfig().contains(systemPath + "drives")) {
+ for (String driveUUID : getConfig().getConfigurationSection(systemPath + "drives").getKeys(false)) {
+
+ Map items = new HashMap();
+ if (getConfig().contains(systemPath + "drives." + driveUUID + ".items")) {
+ try {
+ JSONParser jsonParser = new JSONParser();
+ JSONArray itemJsonArray = (JSONArray) jsonParser.parse(getConfig().getString(systemPath + "drives." + driveUUID + ".items"));
+
+ for (int i = 0; i < itemJsonArray.size(); i++) {
+ JSONObject itemObject = (JSONObject) itemJsonArray.get(i);
+
+ Map.Entry item = ItemSerialization.deserializeItem((String) itemObject.get("itemYAML"));
+
+ items.put(item.getKey(), item.getValue());
+ }
+ } catch (ParseException | InvalidConfigurationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ int size = getConfig().getInt(systemPath + "drives." + driveUUID + ".size");
+
+ drives.add(new ESDrive(size, items));
+ }
+ }
+
+ List trustedUUIDs = new ArrayList<>();
+ if (getConfig().contains(systemPath + "trustedUUIDs")) {
+ try {
+ JSONArray trustedJson = (JSONArray) new JSONParser().parse(getConfig().getString(systemPath + "trustedUUIDs"));
+ for (int i = 0; i < trustedJson.size(); i++) {
+ JSONObject object = (JSONObject) trustedJson.get(i);
+
+ trustedUUIDs.add(UUID.fromString((String) object.get("UUID")));
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ boolean isPublic = getConfig().getBoolean(systemPath + "public");
+
+ Location loc = Utils.convertStringToLocation(getConfig().getString(systemPath + "loc"));
+ systems.add(new ESSystem(uuid, UUID.fromString(systemUUID), loc, drives, trustedUUIDs, isPublic));
+ }
+
+ return systems;
+ }
+
+ public static void savePlayerSystem(ESSystem esSystem) {
+ String systemPath = "players." + esSystem.getOwner() + ".systems." + esSystem.getUUID() + ".";
+
+ getConfig().set(systemPath + "loc", Utils.convertLocationToString(esSystem.getLocation()));
+ getConfig().set(systemPath + "public", esSystem.isPublic());
+
+ try {
+ JSONArray jsonArray = new JSONArray();
+ for (UUID uuid : esSystem.getTrustedPlayers()) {
+ String object = "{\"UUID\":\"" + uuid.toString() + "\"}";
+ JSONObject uuidJSON = (JSONObject) new JSONParser().parse(object);
+
+ jsonArray.add(uuidJSON);
+ }
+
+ getConfig().set(systemPath + "trustedUUIDs", jsonArray.toJSONString());
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ getConfig().set(systemPath + "drives", null);
+
+ for (ESDrive drive : esSystem.getESDrives()) {
+ getConfig().set(systemPath + "drives." + drive.getUUID() + ".size", drive.getSize());
+
+ JSONArray itemsJson = new JSONArray();
+ for (Map.Entry entry : drive.getItems().entrySet()) {
+ try {
+ String object = "{\"itemYAML\":\"" + StringEscapeUtils.escapeJson(ItemSerialization.serializeItem(entry.getKey(), entry.getValue())) + "\"}";
+ JSONObject itemJSON = (JSONObject) new JSONParser().parse(object);
+
+ itemsJson.add(itemJSON);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ getConfig().set(systemPath + "drives." + drive.getUUID() + ".items", itemsJson.toJSONString());
+ }
+
+ getConfig().saveConfig();
+ }
+
+ public static void removePlayerSystem(UUID player, UUID uuid) {
+ getConfig().set("players." + player + ".systems." + uuid, null);
+
+ // Check if the config for the player is now empty, and if it is, then just remove their UUID from the config.
+ if (getConfig().getConfigurationSection("players." + player + ".systems").getKeys(false).size() == 0) {
+ getConfig().set("players." + player, null);
+ }
+
+ getConfig().saveConfig();
+ }
+
+ public static void savePlayerSystems(List esSystems) {
+ assert esSystems != null;
+ for (ESSystem esSystem : esSystems) {
+ savePlayerSystem(esSystem);
+ }
+ }
+}
+
+
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/energeticstorage/gui/ESDriveGUI.java b/src/main/java/net/seanomik/energeticstorage/gui/ESDriveGUI.java
new file mode 100644
index 0000000..263f1ce
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/gui/ESDriveGUI.java
@@ -0,0 +1,236 @@
+package net.seanomik.energeticstorage.gui;
+
+import de.tr7zw.changeme.nbtapi.NBTItem;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.objects.ESDrive;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.Reference;
+import net.seanomik.energeticstorage.utils.Utils;
+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.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.*;
+
+public class ESDriveGUI implements InventoryHolder, Listener {
+ private final Inventory globalInv;
+ private final String title = "Example GUI";
+
+ private Map openSystems = new HashMap<>();
+
+ public ESDriveGUI() {
+ globalInv = Bukkit.createInventory(this, 9, title);
+ }
+
+ @Override
+ public Inventory getInventory() {
+ return globalInv;
+ }
+
+ // You can call this whenever you want to put the items in
+ private void initializeItems(Player player, ESSystem esSystem) {
+ // Only initialize the items for the players inventory, not all of them.
+ Inventory inv = player.getOpenInventory().getTopInventory();
+
+ // Remove all the items
+ inv.clear();
+
+ inv.setItem(0, createGuiItem(Material.PAPER, "Back"));
+ inv.setItem(1, createGuiItem(Material.BLACK_STAINED_GLASS_PANE, ""));
+
+ inv.setItem(7, createGuiItem(Material.BLACK_STAINED_GLASS_PANE, ""));
+ inv.setItem(8, createGuiItem(Material.BLACK_STAINED_GLASS_PANE, ""));
+
+ if (openSystems.containsKey(player.getUniqueId())) {
+ openSystems.replace(player.getUniqueId(), esSystem);
+ } else {
+ openSystems.put(player.getUniqueId(), esSystem);
+ }
+
+ for (int i = 2; i < esSystem.getESDrives().size() + 2; i++) {
+ ESDrive drive = esSystem.getESDrives().get(i - 2);
+
+ inv.setItem(i , drive.getDriveItem());
+ }
+ }
+
+ private ItemStack createGuiItem(Material material, String name, List description) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ meta.setLore(description);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ private ItemStack createGuiItem(Material material, List description) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setLore(description);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ private ItemStack createGuiItem(Material material, String name) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ // You can open the inventory with this
+ public void openInventory(Player p, ESSystem esSystem) {
+ p.openInventory(globalInv);
+ initializeItems(p, esSystem);
+
+ if (openSystems.containsKey(p.getUniqueId())) {
+ openSystems.replace(p.getUniqueId(), esSystem);
+ } else {
+ openSystems.put(p.getUniqueId(), esSystem);
+ }
+ }
+
+ private enum ClickType {
+ NONE,
+ SWAP,
+ SWAP_RIGHT_CLICK,
+ INTO,
+ INTO_HALF,
+ OUT,
+ OUT_HALF,
+ SHIFT_OUT,
+ SHIFT_IN,
+ INVENTORY_CLICK
+ }
+
+ private ClickType findClickType(InventoryClickEvent event) {
+ Inventory inventory = event.getClickedInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ // Check for a shift click or bottom inventory click.
+ if (event.getView().getTitle().equals(title)) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_IN : ClickType.INVENTORY_CLICK;
+ }
+
+ return ClickType.NONE;
+ }
+
+ ItemStack clickedItem = event.getCurrentItem();
+ ItemStack cursor = event.getCursor();
+
+ if ((clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor == null || cursor.getType() == Material.AIR)) {
+ return ClickType.NONE;
+ } else if ( (clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor != null || cursor.getType() != Material.AIR) ) {
+ return (event.isLeftClick()) ? ClickType.INTO : ClickType.INTO_HALF;
+ } else if (cursor == null || cursor.getType() == Material.AIR) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_OUT : (event.isLeftClick()) ? ClickType.OUT : ClickType.OUT_HALF;
+ }
+
+ return (event.isLeftClick()) ? ClickType.SWAP : ClickType.SWAP_RIGHT_CLICK;
+ }
+
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ Inventory inventory = event.getInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ return;
+ } else {
+ Player player = (Player) event.getPlayer();
+ PlayersFile.savePlayerSystem(openSystems.get(player.getUniqueId()));
+
+ openSystems.remove(player);
+ }
+ }
+
+ // Check for clicks on items
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ ClickType clickType = findClickType(event);
+
+ if (clickType != ClickType.NONE) {
+ event.setCancelled(true);
+
+ Player player = (Player) event.getWhoClicked();
+ ItemStack clickedItem = event.getCurrentItem(); // Will be valid if clicks an item (i.e. taking an item from the inventory)
+ ItemStack cursor = event.getCursor(); // Will be valid if an item is put into the inventory
+ int slot = event.getSlot();
+
+ ESSystem esSystem = openSystems.get(player.getUniqueId());
+
+ // Make sure no items will get copied to other players open inventory
+ Inventory inv = player.getOpenInventory().getTopInventory();
+
+ // Handle type of click.
+ switch (clickType) {
+ case SWAP_RIGHT_CLICK:
+ break;
+ case SWAP:
+ break;
+ case SHIFT_IN:
+ if (Utils.isItemValid(clickedItem)) {
+ event.setCancelled(true);
+
+ // Add the item into the player's inventory
+ int driveSlot = inv.firstEmpty();
+ ItemStack oneClicked = clickedItem.clone();
+ oneClicked.setAmount(1);
+ inv.setItem(driveSlot, oneClicked);
+
+ List drives = esSystem.getESDrives();
+ drives.add(driveSlot - 2, new ESDrive(clickedItem));
+ esSystem.setESDrives(drives);
+
+ // Remove the item from the players inventory
+ clickedItem.setAmount(clickedItem.getAmount() - 1);
+ }
+ break;
+ case INTO_HALF:
+ case INTO:
+ if (Utils.isItemValid(cursor)) {
+ NBTItem clickedNBT = new NBTItem(cursor);
+
+ if (clickedNBT.hasKey("ES_Drive") && clickedNBT.getBoolean("ES_Drive")) {
+ event.setCancelled(false);
+
+ List drives = esSystem.getESDrives();
+ drives.add(slot - 2, new ESDrive(cursor));
+ esSystem.setESDrives(drives);
+ }
+ }
+ break;
+ case SHIFT_OUT:
+ case OUT_HALF:
+ case OUT:
+ if (slot == 0) {
+ player.closeInventory();
+
+ Reference.ES_SYSTEM_GUI.initializeItems(player, esSystem);
+ Reference.ES_SYSTEM_GUI.openInventory(player, esSystem);
+ } else if (slot != 1 && slot != 7 && slot != 8) {
+ event.setCancelled(false);
+
+ List drives = esSystem.getESDrives();
+ drives.remove(slot - 2);
+ esSystem.setESDrives(drives);
+ }
+ break;
+ case INVENTORY_CLICK:
+ event.setCancelled(false);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/gui/ESSystemGUI.java b/src/main/java/net/seanomik/energeticstorage/gui/ESSystemGUI.java
new file mode 100644
index 0000000..979fa55
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/gui/ESSystemGUI.java
@@ -0,0 +1,218 @@
+package net.seanomik.energeticstorage.gui;
+
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.objects.ESDrive;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.Reference;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.*;
+
+public class ESSystemGUI implements InventoryHolder, Listener {
+ private final Inventory inv;
+ private final String title = "ES System";
+
+ private Map openSystems = new HashMap<>();
+
+ public ESSystemGUI() {
+ inv = Bukkit.createInventory(this, 9, title);
+ }
+
+ @Override
+ public Inventory getInventory() {
+ return inv;
+ }
+
+ // You can call this whenever you want to put the items in
+ public void initializeItems(Player player, ESSystem openSystem) {
+ for (int i = 0; i < inv.getSize(); i++) {
+ inv.setItem(i, createGuiItem(Material.BLACK_STAINED_GLASS_PANE, ""));
+ }
+
+ // Store the players open system
+ if (openSystems.containsKey(player)) {
+ openSystems.replace(player, openSystem);
+ } else {
+ openSystems.put(player, openSystem);
+ }
+
+ int maxSpace = 0;
+ int filledSpace = 0;
+ int filledTypes = 0;
+ for (ESDrive drive : openSystem.getESDrives()) {
+ maxSpace += drive.getSize();
+ filledSpace += drive.getFilledSpace();
+ filledTypes += drive.getFilledTypes();
+ }
+
+ // Get color of items text
+ ChatColor spaceColor = ChatColor.GREEN;
+ if (filledSpace >= maxSpace * 0.8) {
+ spaceColor = ChatColor.RED;
+ } else if (filledSpace >= maxSpace * 0.5) {
+ spaceColor = ChatColor.YELLOW;
+ }
+
+ // Get color of types text
+ ChatColor itemsColor = ChatColor.GREEN;
+ if (filledTypes >= Reference.MAX_DRIVE_TYPES * 0.8) {
+ itemsColor = ChatColor.RED;
+ } else if (filledTypes >= Reference.MAX_DRIVE_TYPES * 0.5) {
+ itemsColor = ChatColor.YELLOW;
+ }
+
+ List lore = new ArrayList<>();
+ lore.add(ChatColor.BLUE + "Filled Items: " + spaceColor + filledSpace + ChatColor.BLUE + "/" + ChatColor.GREEN + maxSpace);
+ lore.add(ChatColor.BLUE + "Filled Types: " + itemsColor + filledTypes + ChatColor.BLUE + "/" + ChatColor.GREEN + Reference.MAX_DRIVE_TYPES);
+ inv.setItem(5, createGuiItem(Material.GLASS_PANE, "Drives", lore));
+ inv.setItem(4, createGuiItem(Material.IRON_BARS, "Security"));
+ inv.setItem(3, createGuiItem(Material.CHEST, "Terminal"));
+ }
+
+ private ItemStack createGuiItem(Material material, String name, List description) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ meta.setLore(description);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ private ItemStack createGuiItem(Material material, List description) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setLore(description);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ private ItemStack createGuiItem(Material material, String name) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ // You can open the inventory with this
+ public void openInventory(Player p, ESSystem esSystem) {
+ if (openSystems.containsKey(p)) {
+ openSystems.replace(p, esSystem);
+ } else {
+ openSystems.put(p, esSystem);
+ }
+
+ p.openInventory(inv);
+ }
+
+ private enum ClickType {
+ NONE,
+ SWAP,
+ SWAP_RIGHT_CLICK,
+ INTO,
+ INTO_HALF,
+ OUT,
+ OUT_HALF,
+ SHIFT_OUT,
+ SHIFT_IN,
+ INVENTORY_CLICK
+ }
+
+ private ClickType findClickType(InventoryClickEvent event) {
+ Inventory inventory = event.getClickedInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ // Check for a shift click or bottom inventory click.
+ if (event.getView().getTitle().equals(title)) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_IN : ClickType.INVENTORY_CLICK;
+ }
+
+ return ClickType.NONE;
+ }
+
+ ItemStack clickedItem = event.getCurrentItem();
+ ItemStack cursor = event.getCursor();
+
+ if ((clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor == null || cursor.getType() == Material.AIR)) {
+ return ClickType.NONE;
+ } else if ( (clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor != null || cursor.getType() != Material.AIR) ) {
+ return (event.isLeftClick()) ? ClickType.INTO : ClickType.INTO_HALF;
+ } else if (cursor == null || cursor.getType() == Material.AIR) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_OUT : (event.isLeftClick()) ? ClickType.OUT : ClickType.OUT_HALF;
+ }
+
+ return (event.isLeftClick()) ? ClickType.SWAP : ClickType.SWAP_RIGHT_CLICK;
+ }
+
+ // Remove cached player data
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ Inventory inventory = event.getInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ return;
+ } else {
+ Player player = (Player) event.getPlayer();
+ openSystems.remove(player);
+ }
+ }
+
+ // Check for clicks on items
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ ClickType clickType = findClickType(event);
+
+ if (clickType != ClickType.NONE) {
+ event.setCancelled(true);
+
+ Player player = (Player) event.getWhoClicked();
+ ItemStack clickedItem = event.getCurrentItem(); // Will be valid if clicks an item (i.e. taking an item from the inventory)
+ ItemStack cursor = event.getCursor(); // Will be valid if an item is put into the inventory
+ int slot = event.getSlot();
+ ESSystem esSystem = openSystems.get(player);
+
+ switch (clickType) {
+ case SHIFT_IN:
+ break;
+ case SWAP_RIGHT_CLICK:
+ break;
+ case SWAP:
+ break;
+ case INTO_HALF:
+ break;
+ case INTO:
+ break;
+ case OUT_HALF:
+ break;
+ case OUT:
+ if (slot == 3) {
+ Reference.ES_TERMINAL_GUI.openInventory(player, esSystem);
+ } else if (slot == 4) {
+ Reference.ES_SYSTEM_SECURITY_GUI.openInventory(player, esSystem);
+ } else if (slot == 5) {
+ Reference.ES_DRIVE_GUI.openInventory(player, esSystem);
+ }
+ break;
+ case SHIFT_OUT:
+ break;
+ case INVENTORY_CLICK:
+ event.setCancelled(false);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/gui/ESSystemSecurityGUI.java b/src/main/java/net/seanomik/energeticstorage/gui/ESSystemSecurityGUI.java
new file mode 100644
index 0000000..e4ec304
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/gui/ESSystemSecurityGUI.java
@@ -0,0 +1,332 @@
+package net.seanomik.energeticstorage.gui;
+
+import net.seanomik.energeticstorage.EnergeticStorage;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.Reference;
+import net.seanomik.energeticstorage.utils.Utils;
+import net.wesjd.anvilgui.AnvilGUI;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.SkullMeta;
+
+import java.util.*;
+
+public class ESSystemSecurityGUI implements InventoryHolder, Listener {
+ private final Inventory inv;
+ private final String title = "ES System Security";
+ private final String removePlayerTitle = "Un-Trust Player";
+
+ private Map openSystems = new HashMap<>();
+ private Map openPages = new HashMap<>();
+
+ public ESSystemSecurityGUI() {
+ inv = Bukkit.createInventory(this, 9, title);
+ }
+
+ @Override
+ public Inventory getInventory() {
+ return inv;
+ }
+
+ // You can call this whenever you want to put the items in
+ public void initializeItems(Player player, ESSystem openSystem) {
+ Inventory inv = player.getOpenInventory().getTopInventory();
+
+ for (int i = 0; i < inv.getSize(); i++) {
+ inv.setItem(i, createGuiItem(Material.BLACK_STAINED_GLASS_PANE, ""));
+ }
+
+ inv.setItem(3, createGuiItem(Material.LIME_CONCRETE, "Trust player"));
+ inv.setItem(4, createGuiItem(Material.RED_CONCRETE, "Un-Trust player"));
+ if (openSystem.isPublic()) {
+ inv.setItem(5, createGuiItem(Material.IRON_BARS, "Set system to private."));
+ } else {
+ inv.setItem(5, createGuiItem(Material.WHITE_STAINED_GLASS_PANE, "Set system to public."));
+ }
+ }
+
+ public void initializeRemovePlayerItems(Player player, ESSystem openSystem) {
+ Inventory inv = player.getOpenInventory().getTopInventory();
+ //ESSystem openSystem = openSystems.get(player);
+
+ int pageIndex = 0;
+ if (!openPages.containsKey(player)) {
+ openPages.put(player, pageIndex);
+ } else {
+ pageIndex = openPages.get(player);
+ }
+
+ for (int i = 0; i < inv.getSize(); i++) {
+ inv.setItem(i, createGuiItem(Material.BLACK_STAINED_GLASS_PANE, ""));
+ }
+
+ List trustedPlayers = openSystem.getTrustedPlayers();
+
+ for (int i = 10; i < 44; i++) {
+ // Ignore the borders
+ if (i == 18 || i == 27 || i == 36 || i == 17 || i == 26 || i == 35) {
+ continue;
+ }
+
+ // Find the current line we're filling
+ int lineIndex = i / 9 - 1;
+
+ // Fill the box if an item can go there, else just empty it.
+ if (i - (10 + lineIndex * 9) <= 6) { // Each line is 9 boxes.
+ int itemIndex = i - (10 + lineIndex * 2) + pageIndex * 28; // The start of a new line is + 2 boxes, with each page showing 28 items.
+ if (itemIndex < trustedPlayers.size()) {
+ UUID trustedUUID = trustedPlayers.get(itemIndex);
+ OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(trustedUUID);
+
+
+ ItemStack item = new ItemStack(Material.PLAYER_HEAD);
+
+ SkullMeta headMeta = (SkullMeta) item.getItemMeta();
+ headMeta.setOwningPlayer(offlinePlayer);
+ headMeta.setDisplayName(offlinePlayer.getName());
+ headMeta.setLore(Arrays.asList("Click to un-trust."));
+
+ item.setItemMeta(headMeta);
+
+ inv.setItem(i, item);
+ } else {
+ inv.clear(i);
+ }
+ } else {
+ inv.clear(i);
+ }
+
+ inv.setItem(49, createGuiItem(Material.BEDROCK, "Back"));
+ inv.setItem(48, createGuiItem(Material.PAPER, "Last page"));
+ inv.setItem(50, createGuiItem(Material.PAPER, "Next page"));
+ }
+ }
+
+ private ItemStack createGuiItem(Material material, String name, List description) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ meta.setLore(description);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ private ItemStack createGuiItem(Material material, List description) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setLore(description);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ private ItemStack createGuiItem(Material material, String name) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ public void openInventory(Player p, ESSystem esSystem) {
+ if (openSystems.containsKey(p)) {
+ openSystems.replace(p, esSystem);
+ } else {
+ openSystems.put(p, esSystem);
+ }
+
+ Inventory cloneInv = Bukkit.createInventory(this, 9, title);
+ p.openInventory(cloneInv);
+ initializeItems(p, esSystem);
+ }
+
+ public void openRemoveInventory(Player p, ESSystem esSystem) {
+ if (openSystems.containsKey(p)) {
+ openSystems.replace(p, esSystem);
+ } else {
+ openSystems.put(p, esSystem);
+ }
+
+ Inventory removeInv = Bukkit.createInventory(this, 9 * 6, removePlayerTitle);
+ p.openInventory(removeInv);
+ initializeRemovePlayerItems(p, esSystem);
+ }
+
+ // Remove cached player data
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ Inventory inventory = event.getInventory();
+
+ // Checks if the closing inventory is this inventory.
+ if (inventory.getHolder() != null && inventory.getHolder() == this) {
+ // This checks if the closing inventory is not a menu of this GUI class.
+ Bukkit.getScheduler().runTaskLater(EnergeticStorage.getPlugin(), ()-> {
+ Inventory inventory1 = event.getPlayer().getOpenInventory().getTopInventory();
+
+ Player player = (Player) event.getPlayer();
+ if (inventory1.getHolder() == null || inventory1.getHolder() != this) {
+ openSystems.remove(player);
+ }
+ }, (long) 0.1);
+ }
+ }
+
+ private enum ClickType {
+ NONE,
+ SWAP,
+ SWAP_RIGHT_CLICK,
+ INTO,
+ INTO_HALF,
+ OUT,
+ OUT_HALF,
+ SHIFT_OUT,
+ SHIFT_IN,
+ INVENTORY_CLICK
+ }
+
+ private ClickType findClickType(InventoryClickEvent event) {
+ Inventory inventory = event.getClickedInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ // Check for a shift click or bottom inventory click.
+ if (event.getView().getTitle().equals(title)) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_IN : ClickType.INVENTORY_CLICK;
+ }
+
+ return ClickType.NONE;
+ }
+
+ ItemStack clickedItem = event.getCurrentItem();
+ ItemStack cursor = event.getCursor();
+
+ if ((clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor == null || cursor.getType() == Material.AIR)) {
+ return ClickType.NONE;
+ } else if ( (clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor != null || cursor.getType() != Material.AIR) ) {
+ return (event.isLeftClick()) ? ClickType.INTO : ClickType.INTO_HALF;
+ } else if (cursor == null || cursor.getType() == Material.AIR) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_OUT : (event.isLeftClick()) ? ClickType.OUT : ClickType.OUT_HALF;
+ }
+
+ return (event.isLeftClick()) ? ClickType.SWAP : ClickType.SWAP_RIGHT_CLICK;
+ }
+
+ // Check for clicks on items
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ ClickType clickType = findClickType(event);
+
+ if (clickType != ClickType.NONE) {
+ event.setCancelled(true);
+
+ Player player = (Player) event.getWhoClicked();
+ ItemStack clickedItem = event.getCurrentItem(); // Will be valid if clicks an item (i.e. taking an item from the inventory)
+ ItemStack cursor = event.getCursor(); // Will be valid if an item is put into the inventory
+ int slot = event.getSlot();
+
+ ESSystem openSystem = openSystems.get(player);
+
+ // Handle type of click.
+ switch (clickType) {
+ case SHIFT_IN:
+ break;
+ case SWAP_RIGHT_CLICK:
+ break;
+ case SWAP:
+ break;
+ case INTO_HALF:
+ break;
+ case INTO:
+ break;
+ case OUT_HALF:
+ break;
+ case OUT:
+ if (event.getView().getTitle().equals(removePlayerTitle)) {
+ // At remove player menu
+ int pageIndex = openPages.get(player);
+ if (slot == 48) { // Last page
+ List trustedUUIDs = openSystem.getTrustedPlayers();
+ if (trustedUUIDs.size() > pageIndex * 28 ) {
+ openPages.replace(player, pageIndex + 1);
+ }
+ } else if (slot == 49) { // Back
+ openInventory(player, openSystem);
+ } else if (slot == 50) { // Next page
+ openPages.replace(player, Math.max(0, pageIndex - 1));
+ } else {
+ if (Utils.isItemValid(clickedItem) && clickedItem.getType() == Material.PLAYER_HEAD) {
+ SkullMeta headMeta = (SkullMeta) clickedItem.getItemMeta();
+
+ OfflinePlayer unTrustingPlayer = headMeta.getOwningPlayer();
+ openSystem.removeTrustedPlayer(unTrustingPlayer.getUniqueId());
+
+ player.sendMessage(Reference.PREFIX + ChatColor.GREEN + unTrustingPlayer.getName() + " has been un-trusted from the system!");
+
+ player.closeInventory();
+ PlayersFile.savePlayerSystem(openSystem);
+ }
+ }
+ } else {
+ // At main menu
+ if (slot == 3) { // Add player
+ new AnvilGUI.Builder()
+ .onComplete((plr, text) -> {
+ if (text != null && !text.isEmpty()) {
+ OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(text);
+ if (offlinePlayer.hasPlayedBefore()) {
+ if (!openSystem.isPlayerTrusted(offlinePlayer.getUniqueId())) {
+ openSystem.addTrustedPlayer(offlinePlayer.getUniqueId());
+ plr.sendMessage(Reference.PREFIX + ChatColor.GREEN + text + " has been trusted in the system!");
+
+ if (offlinePlayer.isOnline()) {
+ Player onlinePlayer = offlinePlayer.getPlayer();
+ onlinePlayer.sendMessage(Reference.PREFIX + ChatColor.GREEN + "You were just trusted into " + plr.getDisplayName() + "'s ES System!");
+ }
+
+ PlayersFile.savePlayerSystem(openSystem);
+ } else {
+ plr.sendMessage(Reference.PREFIX + ChatColor.RED + text + " is already trusted in the system!");
+ }
+ } else {
+ plr.sendMessage(Reference.PREFIX + ChatColor.RED + text + " doesn't exist!");
+ return AnvilGUI.Response.text("Player doesn't exist!");
+ }
+ }
+
+ return AnvilGUI.Response.close();
+ }).text("Player Name")
+ .item(new ItemStack(Material.PLAYER_HEAD))
+ .title("Enter player to trust.")
+ .plugin(EnergeticStorage.getPlugin())
+ .open(player);
+ } else if (slot == 4) { // Remove player
+ openRemoveInventory(player, openSystem);
+ } else if (slot == 5) { // Set to public/private
+ openSystem.setPublic(!openSystem.isPublic());
+ initializeItems(player, openSystem);
+ PlayersFile.savePlayerSystem(openSystem);
+ }
+ }
+ break;
+ case SHIFT_OUT:
+ break;
+ case INVENTORY_CLICK:
+ event.setCancelled(false);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/gui/ESTerminalGUI.java b/src/main/java/net/seanomik/energeticstorage/gui/ESTerminalGUI.java
new file mode 100644
index 0000000..383bcf7
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/gui/ESTerminalGUI.java
@@ -0,0 +1,335 @@
+package net.seanomik.energeticstorage.gui;
+
+import net.seanomik.energeticstorage.EnergeticStorage;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.Reference;
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.inventory.InventoryDragEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.*;
+
+public class ESTerminalGUI implements InventoryHolder, Listener {
+ private final Inventory globalInv;
+ private final String title = "ES Terminal";
+
+ private Map openSystems = new HashMap<>();
+ private Map openPages = new HashMap<>();
+
+ public ESTerminalGUI() {
+ globalInv = Bukkit.createInventory(this, 9*6, title);
+ }
+
+ @Override
+ public Inventory getInventory() {
+ return globalInv;
+ }
+
+ // You can open the inventory with this
+ public void openInventory(Player p, ESSystem openSystem) {
+ if (openSystems.containsKey(p.getUniqueId())) {
+ openSystems.replace(p.getUniqueId(), openSystem);
+ } else {
+ openSystems.put(p.getUniqueId(), openSystem);
+ }
+
+ Inventory cloneInv = Bukkit.createInventory(this, 9*6, title);
+ p.openInventory(cloneInv);
+ initializeItems(p, openSystem);
+ }
+
+ // You can call this whenever you want to put the items in
+ private void initializeItems(Player player, ESSystem openSystem) {
+ // Only initialize the items for the players inventory, not all of them.
+ Inventory inv = player.getOpenInventory().getTopInventory();
+ //ESSystem openSystem = openSystems.get(player.getUniqueId());
+
+ for (int i = 0; i <9*6; i++) {
+ inv.setItem(i, createGuiItem(Material.BLACK_STAINED_GLASS_PANE, ""));
+ }
+
+ inv.clear(0);
+
+ inv.setItem(1, createGuiItem(Material.LIME_STAINED_GLASS_PANE, "To insert items, put them to the left."));
+ inv.setItem(9, createGuiItem(Material.LIME_STAINED_GLASS_PANE, "To insert items, put them above."));
+
+ inv.setItem(49, createGuiItem(Material.COMPASS, "Search Items"));
+ inv.setItem(48, createGuiItem(Material.PAPER, "Last page"));
+ inv.setItem(50, createGuiItem(Material.PAPER, "Next page"));
+
+ // Store the current player page if it hasn't been stored already.
+ // If the page has been saved, then get it.
+ int pageIndex = 0;
+ if (!openPages.containsKey(player.getUniqueId())) {
+ openPages.put(player.getUniqueId(), pageIndex);
+ } else {
+ pageIndex = openPages.get(player.getUniqueId());
+ }
+
+ // Fill items
+ Map items = openSystem.getAllItems();
+ for (int i = 10; i < 44; i++) {
+ // Ignore the borders
+ if (i == 18 || i == 27 || i == 36 || i == 17 || i == 26 || i == 35) {
+ continue;
+ }
+
+ // Find the current line we're filling
+ int lineIndex = i / 9 - 1;
+
+ // Fill the box if an item can go there, else just empty it.
+ if (i - (10 + lineIndex * 9) <= 6) { // Each line is 9 boxes.
+ int itemIndex = i - (10 + lineIndex * 2) + pageIndex * 28; // The start of a new line is + 2 boxes, with each page showing 28 items.
+ if (itemIndex < items.size()) {
+ try {
+ ItemStack item = (ItemStack) items.keySet().toArray()[itemIndex];
+ int amount = (int) items.values().toArray()[itemIndex];
+
+ ItemMeta itemMeta = item.getItemMeta();
+ if (itemMeta.hasLore()) {
+ List lore = itemMeta.getLore();
+ if (Utils.listStringContainsString(lore, "Amount: ")) {
+ lore.removeIf(str -> (str.contains("Amount: ")));
+ }
+
+ lore.add("Amount: " + amount);
+ itemMeta.setLore(lore);
+ } else {
+ itemMeta.setLore(Arrays.asList("Amount: " + amount));
+ }
+ item.setItemMeta(itemMeta);
+
+ item.setAmount(Math.min(amount, 64));
+
+ inv.setItem(i, item);
+ } catch (NullPointerException e) {
+ System.out.println(Reference.PREFIX + ChatColor.RED + "A null item was stored and just attempted to load!");
+ inv.setItem(i, createGuiItem(Material.RED_STAINED_GLASS_PANE, "There was an error trying to load this item!"));
+ }
+ } else {
+ inv.clear(i);
+ }
+ } else {
+ inv.clear(i);
+ }
+ }
+ }
+
+ private ItemStack createGuiItem(Material material, String name) {
+ ItemStack item = new ItemStack(material, 1);
+ ItemMeta meta = item.getItemMeta();
+ meta.setDisplayName(name);
+ item.setItemMeta(meta);
+
+ return item;
+ }
+
+ private enum ClickType {
+ NONE,
+ SWAP,
+ SWAP_RIGHT_CLICK,
+ INTO,
+ INTO_HALF,
+ OUT,
+ OUT_HALF,
+ SHIFT_OUT,
+ SHIFT_IN,
+ INVENTORY_CLICK
+ }
+
+ private ClickType findClickType(InventoryClickEvent event) {
+ Inventory inventory = event.getClickedInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ // Check for a shift click or bottom click.
+ if (event.getView().getTitle().equals(title)) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_IN : ClickType.INVENTORY_CLICK;
+ }
+
+ return ClickType.NONE;
+ }
+
+ ItemStack clickedItem = event.getCurrentItem();
+ ItemStack cursor = event.getCursor();
+
+ if ((clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor == null || cursor.getType() == Material.AIR)) {
+ return ClickType.NONE;
+ } else if ( (clickedItem == null || clickedItem.getType() == Material.AIR) && (cursor != null || cursor.getType() != Material.AIR) ) {
+ return (event.isLeftClick()) ? ClickType.INTO : ClickType.INTO_HALF;
+ } else if (cursor == null || cursor.getType() == Material.AIR) {
+ return (event.isShiftClick()) ? ClickType.SHIFT_OUT : (event.isLeftClick()) ? ClickType.OUT : ClickType.OUT_HALF;
+ }
+
+ return (event.isLeftClick()) ? ClickType.SWAP : ClickType.SWAP_RIGHT_CLICK;
+ }
+
+ @EventHandler
+ public void onInventoryDrag(InventoryDragEvent event) {
+ Inventory inventory = event.getInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ return;
+ } else {
+ event.setCancelled(true);
+ }
+ }
+
+ // Remove cached player data
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ Inventory inventory = event.getInventory();
+
+ if (inventory == null || inventory.getHolder() == null || inventory.getHolder() != this) {
+ return;
+ } else {
+ Player player = (Player) event.getPlayer();
+ PlayersFile.savePlayerSystem(openSystems.get(player.getUniqueId()));
+
+ Bukkit.getScheduler().runTaskLaterAsynchronously(EnergeticStorage.getPlugin(), () -> {
+ openSystems.remove(player);
+ openPages.remove(player);
+ }, (long) 0.1);
+ }
+ }
+
+ // Check for clicks on items
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ ClickType clickType = findClickType(event);
+
+ if (clickType != ClickType.NONE && clickType != ClickType.INVENTORY_CLICK) {
+ event.setCancelled(true);
+
+ Player player = (Player) event.getWhoClicked();
+ ItemStack clickedItem = event.getCurrentItem(); // Will be valid if clicks an item (i.e. taking an item from the inventory)
+ ItemStack cursor = event.getCursor(); // Will be valid if an item is put into the inventory
+ int slot = event.getSlot();
+
+ ESSystem openSystem = openSystems.get(player.getUniqueId());
+
+ // Make sure no items will get copied to other players open inventory
+ Inventory inv = player.getOpenInventory().getTopInventory();
+
+ int pageIndex = openPages.get(player.getUniqueId());
+ if (slot == 48) { // Back page
+ if (pageIndex != 0) {
+ pageIndex--;
+
+ openPages.replace(player.getUniqueId(), pageIndex);
+ initializeItems(player, openSystem);
+ }
+ } else if (slot == 49) { // Search
+ // @TODO: Add anvil gui search
+ } else if (slot == 50) {
+ Map items = openSystem.getAllItems();
+
+ if (items.size() > pageIndex * 28 ) {
+ pageIndex++;
+ openPages.replace(player.getUniqueId(), pageIndex);
+ initializeItems(player, openSystem);
+ }
+ } else {
+ switch (clickType) {
+ case SHIFT_IN:
+ if (Utils.isItemValid(clickedItem)) {
+ if (openSystem.addItem(clickedItem)) {
+ event.setCancelled(false);
+
+ Bukkit.getScheduler().runTaskLater(EnergeticStorage.getPlugin(), () -> {
+ initializeItems(player, openSystem);
+ }, (long) 0.1);
+ }
+ }
+
+ break;
+ // Currently just ignore a into half since there really isn't any point of it.
+ case SWAP_RIGHT_CLICK:
+ if (cursor.isSimilar(clickedItem)) {
+ // This will take an item out one by one when the player is holding the same material.
+ ItemStack takingItem = cursor.clone();
+ takingItem.setAmount(1); // Only request to take one item
+ openSystem.removeItem(takingItem);
+ cursor.setAmount(cursor.getAmount() + 1);
+
+ Bukkit.getScheduler().runTaskLater(EnergeticStorage.getPlugin(), () -> {
+ initializeItems(player, openSystem);
+ }, (long) 0.1);
+
+ break;
+ }
+ case SWAP:
+ event.setCancelled(true);
+
+ if (openSystem.addItem(cursor)) {
+ // Remove cursor item
+ event.getView().setCursor(null);
+
+ Bukkit.getScheduler().runTaskLater(EnergeticStorage.getPlugin(), () -> {
+ initializeItems(player, openSystem);
+ }, (long) 0.1);
+ }
+
+ break;
+ case INTO_HALF:
+ case INTO:
+ if (Utils.isItemValid(cursor)) {
+ if (openSystem.addItem(cursor)) {
+ event.setCancelled(false);
+
+ Bukkit.getScheduler().runTaskLater(EnergeticStorage.getPlugin(), () -> {
+ initializeItems(player, openSystem);
+ }, (long) 0.1);
+ }
+ }
+
+ break;
+ case OUT_HALF:
+ case OUT:
+ if (Utils.isItemValid(clickedItem)) {
+ ItemStack takingItem = clickedItem.clone();
+
+ /*Map items = openSystem.getAllItems();
+ int amount = items.values().toArray()[Utils.indexOfSimilarItem(items.keySet(), clickedItem)]*/
+ takingItem.setAmount((clickType == ClickType.OUT_HALF && clickedItem.getAmount() / 2 > 0) ? clickedItem.getAmount() / 2 : 64);
+
+ takingItem = openSystem.removeItem(takingItem);
+ event.getView().setCursor(takingItem);
+
+ Bukkit.getScheduler().runTaskLater(EnergeticStorage.getPlugin(), () -> {
+ initializeItems(player, openSystem);
+ }, (long) 0.1);
+ }
+ break;
+ case SHIFT_OUT:
+ if (Utils.isItemValid(clickedItem)) {
+ if (player.getInventory().firstEmpty() != -1) {
+ ItemStack takingitem = clickedItem.clone();
+ takingitem.setAmount(64);
+
+ ItemStack item = openSystem.removeItem(takingitem);
+
+ player.getInventory().addItem(item);
+
+ Bukkit.getScheduler().runTaskLater(EnergeticStorage.getPlugin(), () -> {
+ initializeItems(player, openSystem);
+ }, (long) 0.1);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/seanomik/energeticstorage/listeners/BlockBreakListener.java b/src/main/java/net/seanomik/energeticstorage/listeners/BlockBreakListener.java
new file mode 100644
index 0000000..60315cd
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/listeners/BlockBreakListener.java
@@ -0,0 +1,54 @@
+package net.seanomik.energeticstorage.listeners;
+
+import de.tr7zw.changeme.nbtapi.NBTTileEntity;
+import net.seanomik.energeticstorage.Skulls;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.objects.ESDrive;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.PermissionChecks;
+import net.seanomik.energeticstorage.utils.Reference;
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockBreakEvent;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class BlockBreakListener implements Listener {
+
+ @EventHandler
+ public void onBlockBreakListener(BlockBreakEvent event) {
+ if (event.getBlock().getType() == Material.PLAYER_HEAD) {
+ Block block = event.getBlock();
+ Player player = event.getPlayer();
+
+ NBTTileEntity blockNBT = new NBTTileEntity(block.getState());
+ if (blockNBT.getCompound("Owner").getCompound("Properties").getCompoundList("textures").get(0).getString("Value").equals(Skulls.Computer.getTexture())) {
+ ESSystem esSystem = Utils.findSystemAtLocation(block.getLocation());
+
+ if (esSystem != null) {
+ if (esSystem.isPlayerTrusted(player) || esSystem.getOwner().equals(player.getUniqueId()) || PermissionChecks.canDestroyUntrustedSystems(player)) {
+ for (ESDrive drive : esSystem.getESDrives()) {
+ block.getLocation().getWorld().dropItem(block.getLocation(), drive.getDriveItem());
+ }
+
+ // Remove the system from cache and storage
+ PlayersFile.removePlayerSystem(player.getUniqueId(), esSystem.getUUID());
+
+ List systems = new LinkedList<>(Reference.ES_SYSTEMS.get(player.getUniqueId()));
+ systems.removeIf(esSystem::equals);
+ Reference.ES_SYSTEMS.replace(player.getUniqueId(), systems);
+ } else {
+ event.setCancelled(true);
+ player.sendMessage(Reference.PREFIX + ChatColor.RED + "You are not trusted to this system!");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/listeners/BlockPlaceListener.java b/src/main/java/net/seanomik/energeticstorage/listeners/BlockPlaceListener.java
new file mode 100644
index 0000000..6fd7ad2
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/listeners/BlockPlaceListener.java
@@ -0,0 +1,50 @@
+package net.seanomik.energeticstorage.listeners;
+
+import de.tr7zw.changeme.nbtapi.NBTTileEntity;
+import net.seanomik.energeticstorage.Skulls;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.PermissionChecks;
+import net.seanomik.energeticstorage.utils.Reference;
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.BlockPlaceEvent;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+public class BlockPlaceListener implements Listener {
+
+ @EventHandler
+ public void onBlockPlace(BlockPlaceEvent event) {
+ if (event.getBlock().getType() == Material.PLAYER_HEAD) {
+ Block block = event.getBlock();
+ Player player = event.getPlayer();
+
+ NBTTileEntity blockNBT = new NBTTileEntity(block.getState());
+
+ if (blockNBT.getCompound("Owner").getCompound("Properties").getCompoundList("textures").get(0).getString("Value").equals(Skulls.Computer.getTexture())) {
+ if (PermissionChecks.canCreateSystem(player)) {
+ ESSystem newSystem = new ESSystem(player.getUniqueId(), UUID.randomUUID(), block.getLocation());
+ PlayersFile.savePlayerSystem(newSystem);
+
+ // If the player already has a system then add it to their cached systems, else just add it.
+ if (Reference.ES_SYSTEMS.containsKey(player.getUniqueId())) {
+ List playerESSystems = new LinkedList<>(Reference.ES_SYSTEMS.get(player.getUniqueId()));
+ playerESSystems.add(newSystem);
+
+ Reference.ES_SYSTEMS.replace(player.getUniqueId(), playerESSystems);
+ } else {
+ Reference.ES_SYSTEMS.put(player.getUniqueId(), Arrays.asList(newSystem));
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/listeners/PlayerInteractListener.java b/src/main/java/net/seanomik/energeticstorage/listeners/PlayerInteractListener.java
new file mode 100644
index 0000000..970989b
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/listeners/PlayerInteractListener.java
@@ -0,0 +1,62 @@
+package net.seanomik.energeticstorage.listeners;
+
+import de.tr7zw.changeme.nbtapi.NBTTileEntity;
+import net.seanomik.energeticstorage.Skulls;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import net.seanomik.energeticstorage.utils.PermissionChecks;
+import net.seanomik.energeticstorage.utils.Reference;
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.*;
+import org.bukkit.block.Block;
+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.player.PlayerInteractEvent;
+import org.bukkit.inventory.EquipmentSlot;
+
+public class PlayerInteractListener implements Listener {
+
+ @EventHandler
+ public void onPlayerInteract(PlayerInteractEvent event) {
+ if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getHand() == EquipmentSlot.HAND) {
+ if (event.getClickedBlock().getType() == Material.PLAYER_HEAD) {
+ Block block = event.getClickedBlock();
+ Player player = event.getPlayer();
+
+ NBTTileEntity blockNBT = new NBTTileEntity(block.getState());
+
+ if (blockNBT.getCompound("Owner").getCompound("Properties").getCompoundList("textures").get(0).getString("Value").equals(Skulls.Computer.getTexture())) {
+ event.setCancelled(true);
+
+ ESSystem esSystem = Utils.findSystemAtLocation(block.getLocation());
+ if (esSystem != null) {
+ if (esSystem.isPlayerTrusted(player) || esSystem.isPublic() || esSystem.getOwner().equals(player.getUniqueId()) || PermissionChecks.canOpenUntrustedSystem(player)) {
+ Reference.ES_SYSTEM_GUI.initializeItems(player, esSystem);
+ Reference.ES_SYSTEM_GUI.openInventory(player, esSystem);
+ } else {
+ player.sendMessage(Reference.PREFIX + ChatColor.RED + "You are not trusted to this system!");
+ }
+ } else {
+ player.sendMessage(Reference.PREFIX + ChatColor.RED + "You are not trusted to this system!");
+ }
+ }
+/*
+// You probably do not need an atomic reference IntelliJ just recommended this to me.
+AtomicReference lastIncrement = new AtomicReference<>((double) 0);
+Bukkit.getScheduler().runTaskTimer(plugin, ()-> {
+ Location a = new Location(Bukkit.getWorld(""), 0,0,0,);
+ Location b = new Location(Bukkit.getWorld(""), 0,0,0,);
+ Vector d = b.subtract(a).toVector();
+
+ lastIncrement.updateAndGet(v -> (v + 0.1));
+ Location line = a.add(d).multiply(lastIncrement.get());
+
+ // Spawns 1 heart particle
+ line.getWorld().spawnParticle(Particle.HEART, line, 1);
+}, (long) 20, (long) 15); // 20 = delay, 15 = timer
+*/
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/objects/ESDrive.java b/src/main/java/net/seanomik/energeticstorage/objects/ESDrive.java
new file mode 100644
index 0000000..a3435e5
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/objects/ESDrive.java
@@ -0,0 +1,184 @@
+package net.seanomik.energeticstorage.objects;
+
+import de.tr7zw.changeme.nbtapi.NBTItem;
+import net.seanomik.energeticstorage.utils.ItemConstructor;
+import net.seanomik.energeticstorage.utils.ItemSerialization;
+import net.seanomik.energeticstorage.utils.Reference;
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.Material;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.StringEscapeUtils;
+import org.bukkit.inventory.ItemStack;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.util.*;
+
+public class ESDrive implements Cloneable {
+ private UUID uuid;
+ private int size;
+ private Map items = new HashMap<>(); // Item, amount
+
+ public ESDrive(int size) {
+ this.size = size;
+ }
+
+ public ESDrive(int size, Map items) {
+ this(size);
+ uuid = UUID.randomUUID();
+
+ this.items = items;
+ }
+
+ public ESDrive(ItemStack driveItem) {
+ NBTItem driveNBT = new NBTItem(driveItem);
+
+ if (driveNBT.hasKey("ES_DriveItems")) {
+ try {
+ JSONParser jsonParser = new JSONParser();
+ JSONArray itemJsonArray = (JSONArray) jsonParser.parse(driveNBT.getString("ES_DriveItems"));
+
+ for (int i = 0; i < itemJsonArray.size(); i++) {
+ JSONObject itemObject = (JSONObject) itemJsonArray.get(i);
+
+ Map.Entry item = ItemSerialization.deserializeItem((String) itemObject.get("itemYAML"));
+
+ items.put(item.getKey(), item.getValue());
+ }
+ } catch (ParseException | InvalidConfigurationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ size = driveNBT.getInteger("ES_DriveMaxItemAmount");
+ uuid = (driveNBT.hasKey("ES_DriveUUID")) ? UUID.fromString(driveNBT.getString("ES_DriveUUID")) : UUID.randomUUID();
+ }
+
+ public UUID getUUID() {
+ return uuid;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public int getFilledSpace() {
+ int filled = 0;
+
+ for (int amount : items.values()) {
+ filled += amount;
+ }
+
+ return filled;
+ }
+
+ public int getFilledTypes() {
+ List foundItems = new ArrayList<>();
+
+ for (ItemStack item : items.keySet()) {
+ if (!foundItems.contains(item.getType())) {
+ foundItems.add(item.getType());
+ }
+ }
+
+ return foundItems.size();
+ }
+
+ public Map getItems() { return items; }
+
+ public void setUUID(UUID uuid) {
+ this.uuid = uuid;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+ public void setItems(Map items) { this.items = items; }
+
+ public ESDrive clone() {
+ try {
+ ESDrive drive = (ESDrive) super.clone();
+ if (this.items != null) {
+ items = new HashMap<>(items);
+ }
+
+ return drive;
+ } catch (CloneNotSupportedException var2) {
+ throw new Error(var2);
+ }
+ }
+
+ public boolean isAvailable(ItemStack item) {
+ return (Utils.isItemValid(item)) ? getFilledTypes() < Reference.MAX_DRIVE_TYPES && getFilledSpace() < size : getFilledSpace() < size;
+ }
+
+ public boolean addItem(ItemStack item) {
+ item = item.clone();
+
+ if (isAvailable(item)) {
+ // The item is contained, then update the amount.
+ if (Utils.containsSimilarItem(new ArrayList<>(items.keySet()), item, true)) {
+ int amount = (int) items.values().toArray()[Utils.indexOfSimilarItem(new ArrayList<>(items.keySet()), item)] + item.getAmount();
+ Utils.removeSimilarItem(items, item);
+ items.put(item, amount);
+ } else {
+ items.put(item, item.getAmount());
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public ItemStack removeItem(ItemStack item) {
+ // If there isn't enough items stored to take out the requested amount, then just take out all that we can.
+ int foundItemAmount = (int) items.values().toArray()[Utils.indexOfSimilarItem(new ArrayList<>(items.keySet()), item)];
+ if (foundItemAmount - item.getAmount() < 1) {
+ Utils.removeSimilarItem(items, item);
+ item.setAmount(foundItemAmount);
+ } else {
+ int newAmount = foundItemAmount - item.getAmount();
+
+ Utils.removeSimilarItem(items, item);
+ items.put(item, newAmount);
+ }
+
+ return item;
+ }
+
+ private String exceptionMessage(Exception e) {
+ return "An exception occurred in ESDrive (UUID:" + uuid + ", Exception: " + e.getMessage() + ")";
+ }
+
+ public ItemStack getDriveItem() {
+ try {
+ ItemStack drive = ItemConstructor.createDrive(size, getFilledSpace(), getFilledTypes());
+ NBTItem driveNBT = new NBTItem(drive);
+
+ JSONArray itemsJson = new JSONArray();
+ for (Map.Entry entry : items.entrySet()) {
+ try {
+ String object = "{\"itemYAML\":\"" + StringEscapeUtils.escapeJson(ItemSerialization.serializeItem(entry.getKey(), entry.getValue())) + "\"}";
+ JSONObject itemJSON = (JSONObject) new JSONParser().parse(object);
+
+ itemsJson.add(itemJSON);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ driveNBT.setString("ES_DriveItems", itemsJson.toJSONString());
+ drive = driveNBT.getItem();
+
+ return drive;
+ } catch (Exception e) {
+ System.out.println(exceptionMessage(e));
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/objects/ESSystem.java b/src/main/java/net/seanomik/energeticstorage/objects/ESSystem.java
new file mode 100644
index 0000000..ef8e9e6
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/objects/ESSystem.java
@@ -0,0 +1,210 @@
+package net.seanomik.energeticstorage.objects;
+
+import net.seanomik.energeticstorage.utils.Utils;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.*;
+
+public class ESSystem implements Cloneable {
+ private UUID owner;
+ private UUID uuid;
+ private Location location;
+ private List esDrives = new ArrayList<>();
+ private List trustedPlayers = new ArrayList<>();
+ private boolean isPublic;
+
+ public ESSystem(UUID owner, UUID uuid, Location location) {
+ this.owner = owner;
+ this.uuid = uuid;
+ this.location = location;
+ }
+
+ public ESSystem(UUID owner, UUID uuid, Location location, List esDrives, List trustedPlayers, boolean isPublic) {
+ this(owner, uuid, location);
+
+ this.esDrives = esDrives;
+ this.trustedPlayers = trustedPlayers;
+ this.isPublic = isPublic;
+ }
+
+ public void setEsDrives(List esDrives) {
+ this.esDrives = esDrives;
+ }
+
+ public List getEsDrives() {
+ return esDrives;
+ }
+
+ public void setTrustedPlayers(List trustedPlayers) {
+ this.trustedPlayers = trustedPlayers;
+ }
+
+ public List getTrustedPlayers() {
+ return trustedPlayers;
+ }
+
+ public boolean isPlayerTrusted(UUID uuid) {
+ return trustedPlayers.contains(uuid) || isPublic;
+ }
+
+ public boolean isPublic() {
+ return isPublic;
+ }
+
+ public void setPublic(boolean aPublic) {
+ isPublic = aPublic;
+ }
+
+ public boolean isPlayerTrusted(Player player) {
+ return trustedPlayers.contains(player.getUniqueId());
+ }
+
+ public void addTrustedPlayer(UUID uuid) {
+ trustedPlayers.add(uuid);
+ }
+
+ public void addTrustedPlayer(Player player) {
+ trustedPlayers.add(player.getUniqueId());
+ }
+
+ public void removeTrustedPlayer(UUID uuid) {
+ trustedPlayers.remove(uuid);
+ }
+
+ public void removeTrustedPlayer(Player player) {
+ trustedPlayers.remove(player.getUniqueId());
+ }
+
+ public UUID getUUID() {
+ return uuid;
+ }
+
+ public UUID getOwner() {
+ return owner;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public List getESDrives() {
+ return esDrives;
+ }
+
+ public void setUUID(UUID id) {
+ this.uuid = uuid;
+ }
+
+ public void setOwner(UUID owner) {
+ this.owner = owner;
+ }
+
+ public void setESDrives(List esDrives) {
+ this.esDrives = esDrives;
+ }
+
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ public ESSystem clone() {
+ try {
+ ESSystem system = (ESSystem) super.clone();
+ if (this.esDrives != null) {
+ esDrives = new ArrayList<>(esDrives);
+ }
+
+ return system;
+ } catch (CloneNotSupportedException var2) {
+ throw new Error(var2);
+ }
+ }
+
+ public boolean equals(Object other) {
+ assert other != null;
+ if (other instanceof ESSystem) {
+ ESSystem otherSystem = (ESSystem) other;
+ return otherSystem.getUUID() == uuid;
+ }
+
+ return false;
+ }
+
+ public ESDrive getNextAvailableDrive() {
+ for (ESDrive drive : esDrives) {
+ if (drive.isAvailable(null)) {
+ return drive;
+ }
+ }
+
+ return null;
+ }
+
+ public ESDrive findItemInAvailableDrive(ItemStack item) {
+ for (ESDrive drive : esDrives) {
+ for (ItemStack itemStack : drive.getItems().keySet()) {
+ if (item.isSimilar(itemStack) && drive.isAvailable(item)) {
+ return drive;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public Map getAllItems() {
+ Map items = new HashMap<>();
+
+ for (ESDrive drive : esDrives) {
+ for (Map.Entry entry : drive.getItems().entrySet()) {
+ if (items.containsKey(entry.getKey())) {
+ // Set the ItemStack amount to the already existing item's amount + this amount
+ entry.getKey().setAmount(Math.min(entry.getValue(), 64));
+ items.remove(entry.getKey());
+ }
+
+ items.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ return items;
+ }
+
+public boolean addItem(ItemStack item) {
+ ESDrive drive = findItemInAvailableDrive(item);
+
+ // If we failed to find the item in the next available drive, then find another drive.
+ if (drive == null) {
+ drive = getNextAvailableDrive();
+
+ if (drive == null) {
+ return false;
+ }
+ }
+
+ boolean addReturn = drive.addItem(item);
+
+ return addReturn;
+}
+
+ public ItemStack removeItem(ItemStack item) {
+ // Find a drive that has this item to remove from.
+ ESDrive drive = null;
+ for (ESDrive esDrive : esDrives) {
+ for (ItemStack itemStack : esDrive.getItems().keySet()) {
+ if (Utils.removeAmountFromLore(item).isSimilar(Utils.removeAmountFromLore(itemStack))) {
+ drive = esDrive;
+ }
+ }
+ }
+
+ // If we failed to find the item in the next available drive, then find another drive.
+ if (drive == null) {
+ return null;
+ }
+
+ return drive.removeItem(item);
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/utils/ItemConstructor.java b/src/main/java/net/seanomik/energeticstorage/utils/ItemConstructor.java
new file mode 100644
index 0000000..aeed970
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/utils/ItemConstructor.java
@@ -0,0 +1,84 @@
+package net.seanomik.energeticstorage.utils;
+
+import de.tr7zw.changeme.nbtapi.NBTItem;
+import de.tr7zw.changeme.nbtapi.NBTTileEntity;
+import net.seanomik.energeticstorage.Skulls;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class ItemConstructor {
+ private static Material DRIVE_MATERIAL = Material.BLUE_DYE;
+
+ public static ItemStack createSystemBlock() {
+ ItemStack systemBlock = Skulls.Computer.getItemStack();
+
+ NBTItem systemNBT = new NBTItem(systemBlock);
+ systemNBT.setBoolean("ES_SYSTEM", true);
+ systemBlock = systemNBT.getItem();
+
+ ItemMeta systemMeta = systemBlock.getItemMeta();
+ systemMeta.setDisplayName(ChatColor.LIGHT_PURPLE + "ES System");
+ systemBlock.setItemMeta(systemMeta);
+
+ return systemBlock;
+ }
+
+ public static ItemStack createDrive(int size, int filledItems, int filledTypes) {
+ int smallSize = size / 1024;
+ if (smallSize != 1 && smallSize != 4 && smallSize != 16 && smallSize != 64) {
+ return null;
+ }
+
+ // Get the size string for the items name.
+ String sizeString = size + "k";
+ sizeString = sizeString.substring(0, sizeString.indexOf('k') - 3);
+ if (sizeString.equals("65")) sizeString = "64";
+
+ ItemStack drive = new ItemStack(DRIVE_MATERIAL, 1);
+
+ // Save the items data in NBT
+ NBTItem driveNBT = new NBTItem(drive);
+ driveNBT.setBoolean("ES_Drive", true);
+ driveNBT.setInteger("ES_DriveMaxItemAmount", size);
+ driveNBT.setInteger("ES_DriveMaxTypeAmount", Reference.MAX_DRIVE_TYPES);
+ driveNBT.setString("ES_DriveUUID", UUID.randomUUID().toString());
+ drive = driveNBT.getItem();
+
+ ItemMeta driveMeta = drive.getItemMeta();
+
+ driveMeta.setDisplayName(ChatColor.LIGHT_PURPLE + "ES " + sizeString + "k Drive");
+
+ // Get color of items text
+ ChatColor itemsColor = ChatColor.GREEN;
+ if (filledItems >= size * 0.8) {
+ itemsColor = ChatColor.RED;
+ } else if (filledItems >= size * 0.5) {
+ itemsColor = ChatColor.YELLOW;
+ }
+
+ // Get color of types text
+ ChatColor typesColor = ChatColor.GREEN;
+ if (filledTypes >= Reference.MAX_DRIVE_TYPES * 0.8) {
+ typesColor = ChatColor.RED;
+ } else if (filledTypes >= Reference.MAX_DRIVE_TYPES * 0.5) {
+ typesColor = ChatColor.YELLOW;
+ }
+
+ List lore = new ArrayList<>();
+ lore.add(ChatColor.BLUE + "Filled Items: " + itemsColor + filledItems + ChatColor.BLUE + "/" + ChatColor.GREEN + size);
+ lore.add(ChatColor.BLUE + "Filled Types: " + typesColor + filledTypes + ChatColor.BLUE + "/" + ChatColor.GREEN + Reference.MAX_DRIVE_TYPES);
+ driveMeta.setLore(lore);
+
+ drive.setItemMeta(driveMeta);
+
+ return drive;
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/utils/ItemRecipies.java b/src/main/java/net/seanomik/energeticstorage/utils/ItemRecipies.java
new file mode 100644
index 0000000..34e551c
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/utils/ItemRecipies.java
@@ -0,0 +1,92 @@
+package net.seanomik.energeticstorage.utils;
+
+import net.seanomik.energeticstorage.EnergeticStorage;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.ShapedRecipe;
+
+public class ItemRecipies {
+ public static void registerRecipes() {
+ registerBlockRecipes();
+ registerDriveRecipes();
+ }
+
+ private static void registerBlockRecipes() {
+ try {
+ // Register system block
+ ItemStack esSystem = ItemConstructor.createSystemBlock();
+ ShapedRecipe systemRecipe = new ShapedRecipe(new NamespacedKey(EnergeticStorage.getPlugin(), "es_system"), esSystem);
+ systemRecipe.shape(
+ "III",
+ "RGR",
+ "DID");
+ systemRecipe.setIngredient('I', Material.IRON_INGOT);
+ systemRecipe.setIngredient('G', Material.GLOWSTONE_DUST);
+ systemRecipe.setIngredient('R', Material.REDSTONE);
+ systemRecipe.setIngredient('D', Material.DIAMOND);
+ Bukkit.getServer().addRecipe(systemRecipe);
+ } catch (Exception e) {
+
+ }
+ }
+
+ private static void registerDriveRecipes() {
+ try { // If the plugin was reloaded, a exception will be thrown.
+ // Register Drive 1k
+ ItemStack drive1k = ItemConstructor.createDrive(1024, 0, 0);
+
+ ShapedRecipe drv1k = new ShapedRecipe(new NamespacedKey(EnergeticStorage.getPlugin(), "es_drive_1k"), drive1k);
+ drv1k.shape(
+ "RCR",
+ "CRC",
+ "III");
+ drv1k.setIngredient('I', Material.IRON_INGOT);
+ drv1k.setIngredient('C', Material.CLAY);
+ drv1k.setIngredient('R', Material.REDSTONE);
+ Bukkit.getServer().addRecipe(drv1k);
+
+ // Register Drive 4k
+ ItemStack drive4k = ItemConstructor.createDrive(4096, 0, 0);
+
+ ShapedRecipe drv4k = new ShapedRecipe(new NamespacedKey(EnergeticStorage.getPlugin(), "es_drive_4k"), drive4k);
+ drv4k.shape(
+ "RBR",
+ "BRB",
+ "III");
+ drv4k.setIngredient('I', Material.IRON_INGOT);
+ drv4k.setIngredient('B', Material.BRICK);
+ drv4k.setIngredient('R', Material.REDSTONE);
+ Bukkit.getServer().addRecipe(drv4k);
+
+ // Register Drive 16k
+ ItemStack drive16k = ItemConstructor.createDrive(16384, 0, 0);
+
+ ShapedRecipe drv16k = new ShapedRecipe(new NamespacedKey(EnergeticStorage.getPlugin(), "es_drive_16k"), drive16k);
+ drv16k.shape(
+ "RGR",
+ "GRG",
+ "III");
+ drv16k.setIngredient('I', Material.IRON_INGOT);
+ drv16k.setIngredient('G', Material.GOLD_INGOT);
+ drv16k.setIngredient('R', Material.REDSTONE);
+ Bukkit.getServer().addRecipe(drv16k);
+
+ // Register Drive 64k
+ ItemStack drive64k = ItemConstructor.createDrive(65536, 0, 0);
+
+ ShapedRecipe drv64k = new ShapedRecipe(new NamespacedKey(EnergeticStorage.getPlugin(), "es_drive_64k"), drive64k);
+ drv64k.shape(
+ "RDR",
+ "DRD",
+ "III");
+ drv64k.setIngredient('I', Material.IRON_INGOT);
+ drv64k.setIngredient('D', Material.DIAMOND);
+ drv64k.setIngredient('R', Material.REDSTONE);
+ Bukkit.getServer().addRecipe(drv64k);
+ } catch (Exception e) {
+
+ }
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/utils/ItemSerialization.java b/src/main/java/net/seanomik/energeticstorage/utils/ItemSerialization.java
new file mode 100644
index 0000000..ee3f038
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/utils/ItemSerialization.java
@@ -0,0 +1,31 @@
+package net.seanomik.energeticstorage.utils;
+
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.AbstractMap;
+import java.util.Map;
+
+public class ItemSerialization {
+ public static String serializeItem(ItemStack item, int amount) {
+ YamlConfiguration yaml = new YamlConfiguration();
+
+ yaml.set("amount", amount);
+ yaml.set("item", item);
+
+ return yaml.saveToString();
+ }
+
+ public static Map.Entry deserializeItem(String item) throws InvalidConfigurationException {
+ YamlConfiguration yaml = new YamlConfiguration();
+ yaml.loadFromString(item);
+
+ ItemStack itemStack = yaml.getItemStack("item");
+ int amount = yaml.getInt("amount");
+
+ Map.Entry itemEntry = new AbstractMap.SimpleEntry<>(itemStack, amount);
+
+ return itemEntry;
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/utils/PermissionChecks.java b/src/main/java/net/seanomik/energeticstorage/utils/PermissionChecks.java
new file mode 100644
index 0000000..0213397
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/utils/PermissionChecks.java
@@ -0,0 +1,25 @@
+package net.seanomik.energeticstorage.utils;
+
+import org.bukkit.command.CommandSender;
+
+public class PermissionChecks {
+ public static boolean canDestroyUntrustedSystems(CommandSender sender) {
+ return sender.hasPermission("energeticstorage.system.destroy.untrusted");
+ }
+
+ public static boolean canOpenUntrustedSystem(CommandSender sender) {
+ return sender.hasPermission("energeticstorage.system.open.untrusted");
+ }
+
+ public static boolean canESGive(CommandSender sender) {
+ return sender.hasPermission("energeticstorage.esgive");
+ }
+
+ public static boolean canESGiveOthers(CommandSender sender) {
+ return sender.hasPermission("energeticstorage.esgive.others");
+ }
+
+ public static boolean canCreateSystem(CommandSender sender) {
+ return sender.hasPermission("energeticstorage.system.create");
+ }
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/utils/Reference.java b/src/main/java/net/seanomik/energeticstorage/utils/Reference.java
new file mode 100644
index 0000000..e06c261
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/utils/Reference.java
@@ -0,0 +1,25 @@
+package net.seanomik.energeticstorage.utils;
+
+import net.seanomik.energeticstorage.files.ConfigFile;
+import net.seanomik.energeticstorage.gui.ESDriveGUI;
+import net.seanomik.energeticstorage.gui.ESSystemGUI;
+import net.seanomik.energeticstorage.gui.ESSystemSecurityGUI;
+import net.seanomik.energeticstorage.gui.ESTerminalGUI;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import org.bukkit.ChatColor;
+
+import java.util.*;
+
+public class Reference {
+
+ public static String PREFIX = ChatColor.AQUA + "" + ChatColor.ITALIC + "[Energetic Storage] " + ChatColor.RESET;
+
+ public static ESTerminalGUI ES_TERMINAL_GUI = new ESTerminalGUI();
+ public static ESSystemGUI ES_SYSTEM_GUI = new ESSystemGUI();
+ public static ESDriveGUI ES_DRIVE_GUI = new ESDriveGUI();
+ public static ESSystemSecurityGUI ES_SYSTEM_SECURITY_GUI = new ESSystemSecurityGUI();
+
+ public static Map> ES_SYSTEMS = new HashMap<>();
+
+ public static int MAX_DRIVE_TYPES = ConfigFile.getMaxTypes();
+}
diff --git a/src/main/java/net/seanomik/energeticstorage/utils/Utils.java b/src/main/java/net/seanomik/energeticstorage/utils/Utils.java
new file mode 100644
index 0000000..fbd8ebe
--- /dev/null
+++ b/src/main/java/net/seanomik/energeticstorage/utils/Utils.java
@@ -0,0 +1,115 @@
+package net.seanomik.energeticstorage.utils;
+
+import jdk.internal.jline.internal.Nullable;
+import net.seanomik.energeticstorage.files.PlayersFile;
+import net.seanomik.energeticstorage.objects.ESSystem;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.sql.Ref;
+import java.util.*;
+
+public class Utils {
+ public static String convertLocationToString(final Location l) {
+ if (l == null) {
+ return "";
+ }
+ return l.getWorld().getName() + ":" + l.getBlockX() + ":" + l.getBlockY() + ":" + l.getBlockZ();
+ }
+
+ public static Location convertStringToLocation(final String s) {
+ if (s == null || s.trim() == "") {
+ return null;
+ }
+ final String[] parts = s.split(":");
+ if (parts.length == 4) {
+ final World w = Bukkit.getServer().getWorld(parts[0]);
+ final int x = Integer.parseInt(parts[1]);
+ final int y = Integer.parseInt(parts[2]);
+ final int z = Integer.parseInt(parts[3]);
+ return new Location(w, x, y, z);
+ }
+ return null;
+ }
+
+ /**
+ * @param item Item to check if valid
+ * This checks if the item is not null and also not air.
+ *
+ * @return boolean - If the item is vallid or not
+ */
+ public static boolean isItemValid(@Nullable ItemStack item) {
+ return item != null && item.getType() != Material.AIR;
+ }
+
+ public static ESSystem findSystemAtLocation(Location location) {
+ for (List systems : Reference.ES_SYSTEMS.values()) {
+ for (ESSystem system : systems) {
+ if (system.getLocation().getBlockX() == location.getBlockX() && system.getLocation().getBlockY() == location.getBlockY() && system.getLocation().getBlockZ() == location.getBlockZ()) {
+ return system;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public static boolean containsSimilarItem(List itemStacks, ItemStack item, boolean ignoreMeta) {
+ for (ItemStack itemStack : itemStacks) {
+ if (removeAmountFromLore(itemStack).isSimilar(item)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static void removeSimilarItem(Map itemStacks, ItemStack item) {
+ itemStacks.entrySet().removeIf(entry -> removeAmountFromLore(entry.getKey()).isSimilar(item));
+ }
+
+ public static int indexOfSimilarItem(List itemStacks, ItemStack item) {
+ removeAmountFromLore(item);
+
+ for (ItemStack itemStack : itemStacks) {
+ removeAmountFromLore(itemStack);
+ if (itemStack.isSimilar(item)) {
+ return itemStacks.indexOf(itemStack);
+ }
+ }
+
+ return -1;
+ }
+
+ public static ItemStack removeAmountFromLore(ItemStack item) {
+ ItemMeta itemMeta = item.getItemMeta();
+ if (itemMeta != null && itemMeta.getLore() != null && !itemMeta.getLore().isEmpty()) {
+ itemMeta.setLore(removeAmountFromLore(itemMeta.getLore()));
+ item.setItemMeta(itemMeta);
+ }
+
+ return item;
+ }
+
+ public static List removeAmountFromLore(List lore) {
+ if (lore != null) {
+ lore.removeIf(line -> line.contains("Amount: "));
+ }
+
+ return lore;
+ }
+
+ public static boolean listStringContainsString(List list, String string) {
+ for (String str : list) {
+ if (str.contains(string)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..b848d38
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1 @@
+driveMaxTypes: 128
\ No newline at end of file
diff --git a/src/main/resources/players.yml b/src/main/resources/players.yml
new file mode 100644
index 0000000..50651a1
--- /dev/null
+++ b/src/main/resources/players.yml
@@ -0,0 +1 @@
+players: {}
\ 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..fa8ac2e
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,37 @@
+name: EnergeticStorage
+version: ${project.version}
+main: net.seanomik.energeticstorage.EnergeticStorage
+api-version: 1.15
+authors: [SeanOMik]
+commands:
+ esgive:
+ aliases: [egive]
+ description: Give a Energetic Storage item.
+ usage: /esgive
+permissions:
+ energeticstorage.*:
+ description: All Energetic Storage permissions.
+ default: op
+ children:
+ energeticstorage.esgive: true
+ energeticstorage.esgive.others: true
+ energeticstorage.system.open.untrusted: true
+ energeticstorage.system.create: true
+ energeticstorage.system.destroy.untrusted: true
+ energeticstorage.esgive:
+ description: Give Energetic Storage items.
+ default: op
+ children:
+ energeticstorage.esgive.others: true
+ energeticstorage.esgive.others:
+ description: Give Energetic Storage items to other players.
+ default: op
+ energeticstorage.system.open.untrusted:
+ description: Gives the player permission to open untrusted systems.
+ default: op
+ energeticstorage.system.create:
+ description: Permission for creating new Energetic Storage.
+ default: op
+ energeticstorage.system.destroy.untrusted:
+ description: Permission for destroying an ES System that the player is not trusted in.
+ default: op
\ No newline at end of file
diff --git a/target/classes/config.yml b/target/classes/config.yml
new file mode 100644
index 0000000..b848d38
--- /dev/null
+++ b/target/classes/config.yml
@@ -0,0 +1 @@
+driveMaxTypes: 128
\ No newline at end of file
diff --git a/target/classes/players.yml b/target/classes/players.yml
new file mode 100644
index 0000000..50651a1
--- /dev/null
+++ b/target/classes/players.yml
@@ -0,0 +1 @@
+players: {}
\ No newline at end of file
diff --git a/target/classes/plugin.yml b/target/classes/plugin.yml
new file mode 100644
index 0000000..df37e86
--- /dev/null
+++ b/target/classes/plugin.yml
@@ -0,0 +1,37 @@
+name: EnergeticStorage
+version: 0.1-SNAPSHOT
+main: net.seanomik.energeticstorage.EnergeticStorage
+api-version: 1.15
+authors: [SeanOMik]
+commands:
+ esgive:
+ aliases: [egive]
+ description: Give a Energetic Storage item.
+ usage: /esgive
+permissions:
+ energeticstorage.*:
+ description: All Energetic Storage permissions.
+ default: op
+ children:
+ energeticstorage.esgive: true
+ energeticstorage.esgive.others: true
+ energeticstorage.system.open.untrusted: true
+ energeticstorage.system.create: true
+ energeticstorage.system.destroy.untrusted: true
+ energeticstorage.esgive:
+ description: Give Energetic Storage items.
+ default: op
+ children:
+ energeticstorage.esgive.others: true
+ energeticstorage.esgive.others:
+ description: Give Energetic Storage items to other players.
+ default: op
+ energeticstorage.system.open.untrusted:
+ description: Gives the player permission to open untrusted systems.
+ default: op
+ energeticstorage.system.create:
+ description: Permission for creating new Energetic Storage.
+ default: op
+ energeticstorage.system.destroy.untrusted:
+ description: Permission for destroying an ES System that the player is not trusted in.
+ default: op
\ No newline at end of file
diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..05c2644
--- /dev/null
+++ b/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Apr 07 00:41:39 CDT 2020
+groupId=net.seanomik
+artifactId=energeticstorage
+version=0.1-SNAPSHOT
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..e3d7498
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,28 @@
+net\seanomik\energeticstorage\gui\ESDriveGUI.class
+net\seanomik\energeticstorage\gui\ESDriveGUI$ClickType.class
+net\seanomik\energeticstorage\utils\ItemConstructor.class
+net\seanomik\energeticstorage\files\ConfigFile.class
+net\seanomik\energeticstorage\utils\PermissionChecks.class
+net\seanomik\energeticstorage\utils\ItemSerialization.class
+net\seanomik\energeticstorage\listeners\PlayerInteractListener.class
+net\seanomik\energeticstorage\objects\ESSystem.class
+net\seanomik\energeticstorage\objects\ESDrive.class
+net\seanomik\energeticstorage\gui\ESDriveGUI$1.class
+net\seanomik\energeticstorage\utils\ItemRecipies.class
+net\seanomik\energeticstorage\gui\ESTerminalGUI.class
+net\seanomik\energeticstorage\gui\ESSystemGUI.class
+net\seanomik\energeticstorage\gui\ESTerminalGUI$ClickType.class
+net\seanomik\energeticstorage\files\PlayersFile.class
+net\seanomik\energeticstorage\gui\ESTerminalGUI$1.class
+net\seanomik\energeticstorage\gui\ESSystemGUI$1.class
+net\seanomik\energeticstorage\EnergeticStorage.class
+net\seanomik\energeticstorage\gui\ESSystemSecurityGUI$1.class
+net\seanomik\energeticstorage\gui\ESSystemSecurityGUI$ClickType.class
+net\seanomik\energeticstorage\listeners\BlockBreakListener.class
+net\seanomik\energeticstorage\commands\ESGiveCommand.class
+net\seanomik\energeticstorage\listeners\BlockPlaceListener.class
+net\seanomik\energeticstorage\gui\ESSystemSecurityGUI.class
+net\seanomik\energeticstorage\utils\Utils.class
+net\seanomik\energeticstorage\Skulls.class
+net\seanomik\energeticstorage\utils\Reference.class
+net\seanomik\energeticstorage\gui\ESSystemGUI$ClickType.class
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..56de941
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,20 @@
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\gui\ESTerminalGUI.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\utils\ItemRecipies.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\commands\ESGiveCommand.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\utils\Utils.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\gui\ESSystemSecurityGUI.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\utils\ItemConstructor.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\listeners\BlockBreakListener.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\gui\ESDriveGUI.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\objects\ESSystem.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\gui\ESSystemGUI.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\EnergeticStorage.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\utils\PermissionChecks.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\files\PlayersFile.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\listeners\PlayerInteractListener.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\files\ConfigFile.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\utils\ItemSerialization.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\utils\Reference.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\objects\ESDrive.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\Skulls.java
+D:\Code\java\spigotPlugins\myPlugins\EnergeticStorage\src\main\java\net\seanomik\energeticstorage\listeners\BlockPlaceListener.java
diff --git a/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29