From b1528c30a256ba66d39afbb03245fe94fd7fe915 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 19:23:15 +0200
Subject: [PATCH 01/55] Fix for distance between different worlds

---
 src/main/java/com/songoda/skyblock/listeners/Move.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Move.java b/src/main/java/com/songoda/skyblock/listeners/Move.java
index 0909bee8..a8360f01 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Move.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Move.java
@@ -235,7 +235,8 @@ public class Move implements Listener {
         final WorldManager worldManager = skyblock.getWorldManager();
         if(e.getTo() != null && e.getTo().getWorld() != null){
             e.getTo().getWorld().loadChunk(e.getTo().getChunk());
-            if(worldManager.isIslandWorld(e.getTo().getWorld()) && e.getTo().distance(e.getFrom()) > 1.0d){ // We should not care of self block tp
+            if(worldManager.isIslandWorld(e.getTo().getWorld())
+                    && (!e.getTo().getWorld().equals(e.getFrom().getWorld()) || e.getTo().distance(e.getFrom()) > 1.0d)){ // We should not care of self block tp
                 if(skyblock.getIslandManager().getIslandAtLocation(e.getTo()) == null){
                     e.setCancelled(true);
                     skyblock.getMessageManager().sendMessage(player,

From 6f2adfad702a80b22eda4d42340f4740cad8ee37 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 20:33:01 +0200
Subject: [PATCH 02/55] Fixed damage and portal settings

---
 .../songoda/skyblock/listeners/Entity.java    |  2 +-
 .../songoda/skyblock/listeners/Portal.java    |  5 +--
 .../permission/PermissionManager.java         | 30 +++++++++++-----
 .../listening/DamagePermission.java           | 14 ++++----
 .../listening/PortalPermission.java           | 36 ++++++++++++-------
 5 files changed, 56 insertions(+), 31 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Entity.java b/src/main/java/com/songoda/skyblock/listeners/Entity.java
index 6d1d768f..ad47df64 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Entity.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Entity.java
@@ -109,7 +109,7 @@ public class Entity implements Listener {
 
             // Check permissions.
             skyblock.getPermissionManager()
-                    .processPermission(event, player, islandManager.getIslandAtLocation(player.getLocation()));
+                    .processPermission(event, player, islandManager.getIslandAtLocation(player.getLocation()), true);
 
         } else { // Make it work with all the entities, not just TNT
             org.bukkit.entity.Entity entity = event.getEntity();
diff --git a/src/main/java/com/songoda/skyblock/listeners/Portal.java b/src/main/java/com/songoda/skyblock/listeners/Portal.java
index 2dc5a66d..145852a3 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Portal.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Portal.java
@@ -81,9 +81,10 @@ public class Portal implements Listener {
         Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml"));
         FileConfiguration configLoad = config.getFileConfiguration();
 
+        PlayerEnterPortalEvent playerEnterPortalEvent = new PlayerEnterPortalEvent(player, player.getLocation()); // TODO Why?? - Fabrimat
         // Check permissions.
-        if (!skyblock.getPermissionManager().processPermission(new PlayerEnterPortalEvent(player, player.getLocation()),
-                player, island))
+        if (!skyblock.getPermissionManager().processPermission(playerEnterPortalEvent,
+                player, island) || playerEnterPortalEvent.isCancelled())
             return;
 
         IslandEnvironment spawnEnvironment;
diff --git a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
index 4038b7fe..1d1b1a11 100644
--- a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
+++ b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
@@ -146,6 +146,10 @@ public class PermissionManager {
     }
 
     public boolean processPermission(Cancellable cancellable, Player player, Island island) {
+        return processPermission(cancellable, player, island, false);
+    }
+
+    public boolean processPermission(Cancellable cancellable, Player player, Island island, boolean reversePermission) {
         if (island == null) return true;
 
         for (HandlerWrapper wrapper : registeredHandlers) {
@@ -157,7 +161,7 @@ public class PermissionManager {
 
             BasicPermission permission = wrapper.getPermission();
 
-            if (hasPermission(player, island, permission))
+            if (hasPermission(player, island, permission, reversePermission))
                 continue;
 
             try {
@@ -169,20 +173,28 @@ public class PermissionManager {
         return true;
     }
 
-    public boolean hasPermission(Player player, Island island, BasicPermission permission) {
+    public boolean hasPermission(Player player, Island island, BasicPermission permission, boolean reversePermission){
         if (player == null)
             return island.hasPermission(IslandRole.Owner, permission);
 
         if (player.hasPermission("fabledskyblock.bypass." + permission.getName().toLowerCase()))
-            return true;
+            return !reversePermission;
 
-        if (island.hasPermission(island.getRole(player), permission))
-            return true;
+        switch(island.getRole(player)){
+            case Owner:
+            case Operator:
+            case Member:
+                return island.hasPermission(IslandRole.Member, permission);
+            case Coop:
+                return island.hasPermission(IslandRole.Coop, permission);
+            case Visitor:
+                return island.hasPermission(IslandRole.Visitor, permission);
+        }
+        return false;
+    }
 
-        if (island.isCoopPlayer(player.getUniqueId()) && island.hasPermission(IslandRole.Coop, permission))
-            return true;
-
-        return island.hasPermission(IslandRole.Visitor, permission);
+    public boolean hasPermission(Player player, Island island, BasicPermission permission) {
+        return this.hasPermission(player, island, permission, false);
     }
 
     public boolean hasPermission(Location location, String permission, IslandRole islandRole) {
diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java
index 9673cd72..baed4a95 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java
@@ -7,6 +7,7 @@ import com.songoda.skyblock.permission.ListeningPermission;
 import com.songoda.skyblock.permission.PermissionHandler;
 import com.songoda.skyblock.permission.PermissionType;
 import com.songoda.skyblock.utils.version.NMSUtil;
+import org.bukkit.Bukkit;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Entity;
 import org.bukkit.entity.EntityType;
@@ -52,10 +53,10 @@ public class DamagePermission extends ListeningPermission {
         FileManager.Config config = fileManager.getConfig(new File(plugin.getDataFolder(), "config.yml"));
         FileConfiguration configLoad = config.getFileConfiguration();
 
-        if (configLoad.getBoolean("Island.Settings.Damage.Enable"))
-            event.setCancelled(true);
-        else if (!configLoad.getBoolean("Island.Damage.Enable"))
+        if (configLoad.getBoolean("Island.Settings.Damage.Enable", false)
+                || !configLoad.getBoolean("Island.Damage.Enable", false)) {
             event.setCancelled(true);
+        }
     }
 
     @PermissionHandler
@@ -66,10 +67,9 @@ public class DamagePermission extends ListeningPermission {
 
         FileManager.Config config = fileManager.getConfig(new File(plugin.getDataFolder(), "config.yml"));
         FileConfiguration configLoad = config.getFileConfiguration();
-
-        if (configLoad.getBoolean("Island.Settings.Damage.Enable")) {
-            event.setCancelled(true);
-        } else if (!configLoad.getBoolean("Island.Damage.Enable")) {
+        
+        if (configLoad.getBoolean("Island.Settings.Damage.Enable", false)
+                || !configLoad.getBoolean("Island.Damage.Enable", false)) {
             event.setCancelled(true);
         }
     }
diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
index 654dec3f..3ebaaf7d 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
@@ -3,12 +3,15 @@ package com.songoda.skyblock.permission.permissions.listening;
 import com.songoda.core.compatibility.CompatibleMaterial;
 import com.songoda.core.compatibility.ServerVersion;
 import com.songoda.skyblock.SkyBlock;
+import com.songoda.skyblock.island.*;
 import com.songoda.skyblock.message.MessageManager;
 import com.songoda.skyblock.permission.ListeningPermission;
 import com.songoda.skyblock.permission.PermissionHandler;
 import com.songoda.skyblock.permission.PermissionType;
 import com.songoda.skyblock.permission.event.events.PlayerEnterPortalEvent;
 import com.songoda.skyblock.utils.world.LocationUtil;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
 import org.bukkit.entity.Player;
 import org.bukkit.event.player.PlayerMoveEvent;
 import org.bukkit.event.player.PlayerTeleportEvent;
@@ -26,18 +29,11 @@ public class PortalPermission extends ListeningPermission {
 
     @PermissionHandler
     public void onPortalEnter(PlayerEnterPortalEvent event) {
-        Player player = (Player) event.getEntity();
+        if(event.getEntity() instanceof Player){
+            Player player = (Player) event.getEntity();
 
-        cancelAndMessage(event, player, plugin, messageManager);
-    }
-
-    @PermissionHandler
-    public void onMove(PlayerMoveEvent event) {
-        CompatibleMaterial toMaterial = CompatibleMaterial.getMaterial(event.getTo().getBlock().getType());
-
-        if (toMaterial == CompatibleMaterial.NETHER_BRICK || toMaterial == CompatibleMaterial.END_PORTAL) {
-            event.setTo(LocationUtil.getRandomLocation(event.getFrom().getWorld(), 5000, 5000, true, true));
-            cancelAndMessage(event, event.getPlayer(), plugin, messageManager);
+            cancelAndMessage(event, player, plugin, messageManager);
+            player.teleport(getToLocation(event.getLocation(), player));
         }
     }
 
@@ -47,8 +43,24 @@ public class PortalPermission extends ListeningPermission {
                 || event.getCause() == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL
                 || event.getCause() == PlayerTeleportEvent.TeleportCause.END_PORTAL
                 || ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9) &&
-                event.getCause() == PlayerTeleportEvent.TeleportCause.END_GATEWAY)
+                event.getCause() == PlayerTeleportEvent.TeleportCause.END_GATEWAY){
+            event.getPlayer().teleport(getToLocation(event.getFrom(), event.getPlayer()));
+
             cancelAndMessage(event, event.getPlayer(), plugin, messageManager);
+        }
+    }
+
+    private Location getToLocation(Location from, Player player) {
+        IslandManager islandManager = plugin.getIslandManager();
+        Island island = islandManager.getIslandAtLocation(from);
+        Location to = island.getLocation(IslandWorld.Normal, IslandEnvironment.Main);
+        if(island.hasRole(IslandRole.Visitor, player.getUniqueId())){
+            to = LocationUtil.getSafeLocation(island.getLocation(IslandWorld.Normal, IslandEnvironment.Visitor));
+            if(to == null){
+                to = LocationUtil.getSpawnLocation();
+            }
+        }
+        return to;
     }
 }
 

From 808c3c06dabf2f9d78d01693a986e1f2b81143aa Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 20:50:07 +0200
Subject: [PATCH 03/55] Added option to have same Members, operators and owner
 settings

---
 .../skyblock/permission/PermissionManager.java        | 11 +++++++++++
 .../permissions/listening/DamagePermission.java       |  2 +-
 src/main/resources/config.yml                         |  4 +++-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
index 1d1b1a11..4e4bd347 100644
--- a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
+++ b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
@@ -1,6 +1,7 @@
 package com.songoda.skyblock.permission;
 
 import com.songoda.skyblock.SkyBlock;
+import com.songoda.skyblock.config.FileManager;
 import com.songoda.skyblock.island.Island;
 import com.songoda.skyblock.island.IslandRole;
 import com.songoda.skyblock.permission.event.Stoppable;
@@ -8,6 +9,7 @@ import com.songoda.skyblock.permission.permissions.basic.*;
 import com.songoda.skyblock.permission.permissions.listening.*;
 import org.bukkit.Bukkit;
 import org.bukkit.Location;
+import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
 import org.bukkit.event.Cancellable;
 
@@ -180,9 +182,18 @@ public class PermissionManager {
         if (player.hasPermission("fabledskyblock.bypass." + permission.getName().toLowerCase()))
             return !reversePermission;
 
+        FileManager.Config config = SkyBlock.getInstance().getFileManager().getConfig(new File(plugin.getDataFolder(), "config.yml"));
+        FileConfiguration configLoad = config.getFileConfiguration();
+
         switch(island.getRole(player)){
             case Owner:
+                if(configLoad.getBoolean("Island.Settings.OwnersAndOperatorsAsMembers", false)){
+                    return island.hasPermission(IslandRole.Owner, permission);
+                }
             case Operator:
+                if(configLoad.getBoolean("Island.Settings.OwnersAndOperatorsAsMembers", false)){
+                    return island.hasPermission(IslandRole.Operator, permission);
+                }
             case Member:
                 return island.hasPermission(IslandRole.Member, permission);
             case Coop:
diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java
index baed4a95..e91520a5 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/DamagePermission.java
@@ -67,7 +67,7 @@ public class DamagePermission extends ListeningPermission {
 
         FileManager.Config config = fileManager.getConfig(new File(plugin.getDataFolder(), "config.yml"));
         FileConfiguration configLoad = config.getFileConfiguration();
-        
+
         if (configLoad.getBoolean("Island.Settings.Damage.Enable", false)
                 || !configLoad.getBoolean("Island.Damage.Enable", false)) {
             event.setCancelled(true);
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index ca6c6fa2..e4baadf3 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -90,7 +90,7 @@ Island:
                 Height: 60
     Member:
         # Max amount of players allowed to be in a team.
-        Capacity: 12
+        Capacity: 12 # TODO Remove
     Chat:
         # If island chat should be output to console
         OutputToConsole: true
@@ -299,6 +299,8 @@ Island:
             Enable: true
         Hunger:
             Enable: false
+        # If owners and operators should have same permission of members
+        OwnersAndOperatorsAsMembers: false
     Portal:
         # When disabled, when a player enters a portal, they will teleport to the nether or
         # end world rather than the island world.

From 32b8f661ca13b40aa8e7753ef9e7afbfd9906c5f Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 21:35:53 +0200
Subject: [PATCH 04/55] Config comments update

---
 src/main/resources/config.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index e4baadf3..1803329e 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -36,7 +36,7 @@ Island:
             Time: 60
         # [!] How many seconds to wait before teleporting to a newly created island
         TeleportTimeout: 1
-        # The distance between the islands
+        # The distance between the islands EXPERIMENTAL!
         Distance: 1200
     Deletion:
         # [!] You are adviced to keep these options both enabled to prevent any issues.
@@ -90,7 +90,7 @@ Island:
                 Height: 60
     Member:
         # Max amount of players allowed to be in a team.
-        Capacity: 12 # TODO Remove
+        Capacity: 12
     Chat:
         # If island chat should be output to console
         OutputToConsole: true

From c58c60a80524804c72dc372d84e66a0be3adcae7 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 22:17:18 +0200
Subject: [PATCH 05/55] Fix for permission setting for owners and ops

---
 .../com/songoda/skyblock/permission/PermissionManager.java    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
index 4e4bd347..616e14d4 100644
--- a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
+++ b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
@@ -187,11 +187,11 @@ public class PermissionManager {
 
         switch(island.getRole(player)){
             case Owner:
-                if(configLoad.getBoolean("Island.Settings.OwnersAndOperatorsAsMembers", false)){
+                if(!configLoad.getBoolean("Island.Settings.OwnersAndOperatorsAsMembers", false)){
                     return island.hasPermission(IslandRole.Owner, permission);
                 }
             case Operator:
-                if(configLoad.getBoolean("Island.Settings.OwnersAndOperatorsAsMembers", false)){
+                if(!configLoad.getBoolean("Island.Settings.OwnersAndOperatorsAsMembers", false)){
                     return island.hasPermission(IslandRole.Operator, permission);
                 }
             case Member:

From 586874e20e1a17e71cdacb1942e24c4cf0028b28 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 22:17:28 +0200
Subject: [PATCH 06/55] Added comment in config

---
 src/main/resources/config.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 1803329e..e02f6afb 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -300,6 +300,7 @@ Island:
         Hunger:
             Enable: false
         # If owners and operators should have same permission of members
+        # It should be left to false as it could be changed soon
         OwnersAndOperatorsAsMembers: false
     Portal:
         # When disabled, when a player enters a portal, they will teleport to the nether or

From b83544df9d44126972c277ef0efa30b3fd2dc952 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 22:23:07 +0200
Subject: [PATCH 07/55] LaborPatch 0.0.6

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index d359add2..6471f5b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>com.songoda</groupId>
 	<artifactId>skyblock</artifactId>
-	<version>2.2.16-LaborPatch-0.0.5</version>
+	<version>2.2.16-LaborPatch-0.0.6</version>
 	<packaging>jar</packaging>
 	<build>
 		<defaultGoal>clean install</defaultGoal>

From e6cd8558c993c79b860ab17bc1fdc14a0cb2d8de Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Wed, 17 Jun 2020 22:27:47 +0200
Subject: [PATCH 08/55] [ci skip] Updated readme

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 1aeb70c4..edbb5f76 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,8 @@ Forked from [FabledSkyBlock](https://gitlab.com/Songoda/fabledskyblock)
 This fork contains bug fixes, features and improvements:
 - Added option to check location security when using `/is visit`
 - Added option to remove water from Island Spawn
-- Added an option to toggle fall damage in certain conditions like when using `/is home`
+- Added option to have Members, Operators and Owners all responding to Members settings as a temporary fix to Operators and Owners settings not being editable via GUI
+- Added option to toggle fall damage in certain conditions like when using `/is home`
 - Added per-world generator (editable only from generators.yml, GUI not supported yet)
 - Added a "subtract" value to levels in order to have all the new islands to level 0
 - Added option to set default WorldBorder status

From cb3e16031e966b4c95feaa33bd6ff652d1cb8b94 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 00:51:32 +0200
Subject: [PATCH 09/55] Reworked portal setting handle

---
 .../com/songoda/skyblock/listeners/Move.java  | 11 +++++++---
 .../listening/PortalPermission.java           | 20 +++++++++++++------
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Move.java b/src/main/java/com/songoda/skyblock/listeners/Move.java
index a8360f01..e3ef3789 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Move.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Move.java
@@ -169,12 +169,17 @@ public class Move implements Listener {
             }
 
             // Load the island they are now on if one exists
-            if (player.hasPermission("fabledskyblock.bypass")) {
-                Island loadedIsland = islandManager.loadIslandAtLocation(player.getLocation());
-                if (loadedIsland != null) {
+            Island loadedIsland = islandManager.loadIslandAtLocation(player.getLocation());
+            if (loadedIsland != null) {
+                if (player.hasPermission("fabledskyblock.bypass")) {
                     playerData.setIsland(loadedIsland.getOwnerUUID());
                     return;
                 }
+
+                if(loadedIsland.isOpen()){
+                    loadedIsland.getVisit().addVisitor(player.getUniqueId());
+                    return;
+                }
             }
 
             LocationUtil.teleportPlayerToSpawn(player);
diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
index 3ebaaf7d..f339ab3a 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
@@ -12,6 +12,7 @@ import com.songoda.skyblock.permission.event.events.PlayerEnterPortalEvent;
 import com.songoda.skyblock.utils.world.LocationUtil;
 import org.bukkit.Bukkit;
 import org.bukkit.Location;
+import org.bukkit.block.BlockFace;
 import org.bukkit.entity.Player;
 import org.bukkit.event.player.PlayerMoveEvent;
 import org.bukkit.event.player.PlayerTeleportEvent;
@@ -33,18 +34,25 @@ public class PortalPermission extends ListeningPermission {
             Player player = (Player) event.getEntity();
 
             cancelAndMessage(event, player, plugin, messageManager);
-            player.teleport(getToLocation(event.getLocation(), player));
+            Bukkit.getScheduler().runTask(plugin, () -> {
+                player.teleport(getToLocation(event.getLocation(), player));
+            });
         }
     }
 
     @PermissionHandler
     public void onTeleport(PlayerTeleportEvent event) {
-        if (event.getCause() == PlayerTeleportEvent.TeleportCause.ENDER_PEARL
-                || event.getCause() == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL
-                || event.getCause() == PlayerTeleportEvent.TeleportCause.END_PORTAL
-                || ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9) &&
-                event.getCause() == PlayerTeleportEvent.TeleportCause.END_GATEWAY){
+        if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.ENDER_PEARL)
+                || event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL)
+                || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)
+                || (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)
+                    && event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_GATEWAY))){
             event.getPlayer().teleport(getToLocation(event.getFrom(), event.getPlayer()));
+            Location to = getToLocation(event.getFrom(), event.getPlayer());
+            Bukkit.getScheduler().runTask(plugin, () -> {
+                event.getPlayer().teleport(to);
+            });
+            event.setTo(to);
 
             cancelAndMessage(event, event.getPlayer(), plugin, messageManager);
         }

From e5ccded437406de41860d62c541d375472f43b1d Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 00:58:23 +0200
Subject: [PATCH 10/55] Updated readme

---
 README.md | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index edbb5f76..4ffbd242 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ This fork contains bug fixes, features and improvements:
 - Added a "subtract" value to levels in order to have all the new islands to level 0
 - Added option to set default WorldBorder status
 - Added permissions for WorldBorder colors
-- Added permission to bypass `/is kick`
+- Added permissions to bypass kick and ban
 - Added water in Nether mechanics!
 - Added option to let slime splitting bypass limits.yml
 - Added option to define distance between islands
@@ -20,8 +20,17 @@ This fork contains bug fixes, features and improvements:
 - Fixed bugs in Challenges that didn't remove all the items
 - Fixed WorldBorder size not reflecting real island size
 - Fixed bugs in island settings that prevented the from loading correctly
+- Fixed mob grief setting
+- Fixed explosion setting
+- Fixed damage setting
+- Fixed use portal setting
+- Fixed bank that couldn't be opened from Members
+- Fixed message telling that island disappeared on login
+- Fixed GUI menus that had used the same page variable
+- Fixed stackable bypassing break setting
 - Now you can use `/is chat <message>` to send messages to island chat
 - Now Challenges can be per-island too
+- Now hunger setting works as intended
 - Hide options in control panel if missing the permission
 - Hide vanished players from visitors list
 - Hide bank from leaderboard if disabled

From 4af09dd7a1d22d408045772a3a5f3be2a6bbdda5 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 03:41:21 +0200
Subject: [PATCH 11/55] Fix for members can't withdraw or deposit from bank

---
 src/main/java/com/songoda/skyblock/menus/Bank.java | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/menus/Bank.java b/src/main/java/com/songoda/skyblock/menus/Bank.java
index e21461cb..139f2ce6 100644
--- a/src/main/java/com/songoda/skyblock/menus/Bank.java
+++ b/src/main/java/com/songoda/skyblock/menus/Bank.java
@@ -64,7 +64,7 @@ public class Bank {
             executors.put(MenuClickRegistry.RegistryKey.fromLanguageFile("Menu.Bank.Item.Deposit.Displayname", CompatibleMaterial.DIRT), (inst, player, e) -> {
                 inst.getSoundManager().playSound(player, CompatibleSound.ENTITY_BAT_TAKEOFF.getSound(), 1.0F, 1.0F);
                 //Deposit money
-                Island island = islandManager.getIslandByPlayer(Bukkit.getOfflinePlayer(player.getUniqueId()));
+                Island island = islandManager.getIsland(player);
                 if (island != null) {
                     SelectInputMethod.getInstance().open(player, "Deposit", (action) -> {
                         if (action == InputMethodSelectlistener.InputMethod.CANCELED) {
@@ -96,18 +96,16 @@ public class Bank {
             executors.put(MenuClickRegistry.RegistryKey.fromLanguageFile("Menu.Bank.Item.Withdraw.Displayname", CompatibleMaterial.GLISTERING_MELON_SLICE), (inst, player, e) -> {
                 inst.getSoundManager().playSound(player, CompatibleSound.ENTITY_BAT_TAKEOFF.getSound(), 1.0F, 1.0F);
                 //Withdraw money
-                Island island = null;
-                island = islandManager.getIslandByPlayer(Bukkit.getOfflinePlayer(player.getUniqueId()));
+                Island island;
+                island = islandManager.getIsland(player);
                 if (island != null) {
-                    Island finalIsland = island;
                     SelectInputMethod.getInstance().open(player, "Withdraw", (action) -> {
                         if (action == InputMethodSelectlistener.InputMethod.CANCELED) {
                             Bukkit.getScheduler().runTask(skyblock, () -> {
                                 this.open(player);
                             });
-                            return;
                         } else if (action == InputMethodSelectlistener.InputMethod.ALL) {
-                            withdraw(player, finalIsland, finalIsland.getBankBalance());
+                            withdraw(player, island, island.getBankBalance());
                         } else {
                                     ChatPrompt.showPrompt(skyblock, player, (event) -> {
                                                 if (event.getMessage().equals(""))
@@ -119,7 +117,7 @@ public class Bank {
                                                     messageManager.sendMessage(player, configLoad.getString("Command.Island.Bank.Short4.Message"));
                                                     soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);
                                                 }
-                                                withdraw(player, finalIsland, amount);
+                                                withdraw(player, island, amount);
                                             });
                         }
                     });

From 102e4d37b84c2db6208ddd700f651bec5310dc52 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 03:41:35 +0200
Subject: [PATCH 12/55] Shorter bank log

---
 src/main/java/com/songoda/skyblock/bank/BankManager.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/bank/BankManager.java b/src/main/java/com/songoda/skyblock/bank/BankManager.java
index 95693e7a..4e829937 100644
--- a/src/main/java/com/songoda/skyblock/bank/BankManager.java
+++ b/src/main/java/com/songoda/skyblock/bank/BankManager.java
@@ -9,6 +9,7 @@ import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
 
 import java.io.File;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -38,7 +39,8 @@ public class BankManager {
             int size = transactions.size()>10 ? 10 : transactions.size();
             for (int i = 0;i<size;i++) {
                 Transaction t = transactions.get((transactions.size()-1)-i);
-                lore.add("#" + (i+1) + " " + t.timestamp.toString() +" " + t.player.getPlayer().getDisplayName() + " " + t.action.name().toLowerCase() + " " + EconomyManager.formatEconomy(t.ammount));
+                SimpleDateFormat formatDate = new SimpleDateFormat("dd/MM/yyyy HH:mm");
+                lore.add("#" + (i+1) + " " + formatDate.format(t.timestamp) +" " + t.player.getPlayer().getDisplayName() + " " + t.action.name().toLowerCase() + " " + EconomyManager.formatEconomy(t.ammount));
             }
             return lore;
         }else {

From e60c2f85d76c0c99bb1d73b60dcc81358b027398 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 03:41:47 +0200
Subject: [PATCH 13/55] Defaulting subtract to 0

---
 src/main/resources/config.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index e02f6afb..86f46908 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -209,7 +209,7 @@ Island:
         # Island Level Points divided by value
         Division: 100
         # Points to subtract to Island Level Points
-        Subtract: 1000
+        Subtract: 0
         Cooldown:
             # Time until Island level rescan expires
             Time: 60

From f73ac5d5ba1c4d8117e557c5c0e4c04f5b4ccf52 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 03:56:52 +0200
Subject: [PATCH 14/55] Fixed possible NullPointer on bank save

---
 src/main/java/com/songoda/skyblock/bank/BankManager.java    | 6 +++++-
 .../java/com/songoda/skyblock/playerdata/PlayerData.java    | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/bank/BankManager.java b/src/main/java/com/songoda/skyblock/bank/BankManager.java
index 4e829937..78073003 100644
--- a/src/main/java/com/songoda/skyblock/bank/BankManager.java
+++ b/src/main/java/com/songoda/skyblock/bank/BankManager.java
@@ -80,6 +80,10 @@ public class BankManager {
     }
 
     public List<Transaction> getTransactionList(Player player) {
-        return log.get(player.getUniqueId());
+        return getTransactionList(player.getUniqueId());
+    }
+
+    public List<Transaction> getTransactionList(UUID uuid) {
+        return log.get(uuid);
     }
 }
diff --git a/src/main/java/com/songoda/skyblock/playerdata/PlayerData.java b/src/main/java/com/songoda/skyblock/playerdata/PlayerData.java
index d3401ac8..ed2d2a3c 100644
--- a/src/main/java/com/songoda/skyblock/playerdata/PlayerData.java
+++ b/src/main/java/com/songoda/skyblock/playerdata/PlayerData.java
@@ -255,7 +255,7 @@ public class PlayerData {
     }
 
     public void save() {
-        transactions = BankManager.getInstance().getTransactionList(getPlayer());
+        transactions = BankManager.getInstance().getTransactionList(getPlayerUUID());
         Config config = getConfig();
         FileConfiguration configLoad = config.getFileConfiguration();
         configLoad.set("Statistics.Island.Playtime", getPlaytime());
@@ -287,6 +287,10 @@ public class PlayerData {
         return Bukkit.getPlayer(uuid);
     }
 
+    public UUID getPlayerUUID() {
+        return uuid;
+    }
+
     public List<Transaction> getTransactions() {
         return transactions;
     }

From b58eef400d6aa987f999bd0545b8f08c90db43b7 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 04:36:25 +0200
Subject: [PATCH 15/55] Fixed NullPointer in Explosion permission

---
 .../permission/permissions/listening/ExplosionsPermission.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/ExplosionsPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/ExplosionsPermission.java
index 210c91f2..80e8e1b8 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/ExplosionsPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/ExplosionsPermission.java
@@ -81,7 +81,7 @@ public class ExplosionsPermission extends ListeningPermission {
 
     @PermissionHandler
     public void onTNTInteract(PlayerInteractEvent event) {
-        if(event.getItem().getType().equals(CompatibleMaterial.FLINT_AND_STEEL.getMaterial())
+        if(event.getItem() != null && event.getItem().getType().equals(CompatibleMaterial.FLINT_AND_STEEL.getMaterial())
                 && event.getClickedBlock().getType().equals(CompatibleMaterial.TNT.getBlockMaterial())){
             cancelAndMessage(event, event.getPlayer(), plugin, plugin.getMessageManager());
         }

From 9d9fb48f0f567a13e257bf2e8ea9f3ea49b9b6fc Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 14:52:32 +0200
Subject: [PATCH 16/55] Fix coop settings not working

---
 src/main/java/com/songoda/skyblock/island/Island.java | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/main/java/com/songoda/skyblock/island/Island.java b/src/main/java/com/songoda/skyblock/island/Island.java
index bc72846e..901777f9 100644
--- a/src/main/java/com/songoda/skyblock/island/Island.java
+++ b/src/main/java/com/songoda/skyblock/island/Island.java
@@ -537,6 +537,9 @@ public class Island {
     }
 
     public IslandRole getRole(OfflinePlayer player) {
+        if(isCoopPlayer(player.getUniqueId())){
+            return IslandRole.Coop; // TODO Rework Coop status - Fabrimat
+        }
         for (IslandRole role : IslandRole.values())
             if (getRole(role).contains(player.getUniqueId()))
                 return role;

From 7c0460bd063a5b120cc6d22b07a7d79ef54e274c Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 14:53:02 +0200
Subject: [PATCH 17/55] Check all the permissions before coming to conclusions

---
 .../com/songoda/skyblock/permission/PermissionManager.java    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
index 616e14d4..8e760007 100644
--- a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
+++ b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
@@ -158,7 +158,7 @@ public class PermissionManager {
             Method handler = wrapper.getHandler();
             if (handler.getParameterTypes()[0] != cancellable.getClass()) continue;
 
-            if (cancellable.isCancelled()) return false;
+            // if (cancellable.isCancelled()) return false;
             if (cancellable instanceof Stoppable && ((Stoppable) cancellable).isStopped()) return true;
 
             BasicPermission permission = wrapper.getPermission();
@@ -172,7 +172,7 @@ public class PermissionManager {
                 e.printStackTrace();
             }
         }
-        return true;
+        return cancellable.isCancelled();
     }
 
     public boolean hasPermission(Player player, Island island, BasicPermission permission, boolean reversePermission){

From c73612de876c6b09f043611a5f6e5be07521b8ac Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 14:53:18 +0200
Subject: [PATCH 18/55] Refactored Storage permission

---
 .../listening/StoragePermission.java          | 42 ++++++++++++-------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/StoragePermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/StoragePermission.java
index 7c15fe75..454ed98e 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/StoragePermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/StoragePermission.java
@@ -7,6 +7,7 @@ import com.songoda.skyblock.message.MessageManager;
 import com.songoda.skyblock.permission.ListeningPermission;
 import com.songoda.skyblock.permission.PermissionHandler;
 import com.songoda.skyblock.permission.PermissionType;
+import org.bukkit.Bukkit;
 import org.bukkit.entity.EntityType;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.minecart.StorageMinecart;
@@ -27,31 +28,44 @@ public class StoragePermission extends ListeningPermission {
 
     @PermissionHandler
     public void onInteract(PlayerInteractEvent event) {
-        if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
+        if (!event.getAction().equals(Action.RIGHT_CLICK_BLOCK))
             return;
 
         CompatibleMaterial material = CompatibleMaterial.getMaterial(event.getClickedBlock());
         Player player = event.getPlayer();
 
-        if (material == CompatibleMaterial.CHEST || material == CompatibleMaterial.TRAPPED_CHEST
-                || (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9) && (material == CompatibleMaterial.SHULKER_BOX
-                || material == CompatibleMaterial.BLACK_SHULKER_BOX || material == CompatibleMaterial.BLUE_SHULKER_BOX
-                || material == CompatibleMaterial.BROWN_SHULKER_BOX || material == CompatibleMaterial.CYAN_SHULKER_BOX
-                || material == CompatibleMaterial.GRAY_SHULKER_BOX || material == CompatibleMaterial.GREEN_SHULKER_BOX
-                || material == CompatibleMaterial.LIGHT_BLUE_SHULKER_BOX || material == CompatibleMaterial.LIGHT_GRAY_SHULKER_BOX
-                || material == CompatibleMaterial.LIME_SHULKER_BOX || material == CompatibleMaterial.MAGENTA_SHULKER_BOX
-                || material == CompatibleMaterial.ORANGE_SHULKER_BOX || material == CompatibleMaterial.PINK_SHULKER_BOX
-                || material == CompatibleMaterial.PURPLE_SHULKER_BOX || material == CompatibleMaterial.RED_SHULKER_BOX
-                || material == CompatibleMaterial.WHITE_SHULKER_BOX || material == CompatibleMaterial.YELLOW_SHULKER_BOX))
-                || ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14) && material == CompatibleMaterial.BARREL)
-            cancelAndMessage(event, player, plugin, messageManager);
+        switch (material){
+            case CHEST:
+            case TRAPPED_CHEST:
+            case DROPPER:
+            case DISPENSER:
+            case SHULKER_BOX:
+            case BLACK_SHULKER_BOX:
+            case BLUE_SHULKER_BOX:
+            case BROWN_SHULKER_BOX:
+            case CYAN_SHULKER_BOX:
+            case GRAY_SHULKER_BOX:
+            case GREEN_SHULKER_BOX:
+            case LIGHT_BLUE_SHULKER_BOX:
+            case LIGHT_GRAY_SHULKER_BOX:
+            case LIME_SHULKER_BOX:
+            case MAGENTA_SHULKER_BOX:
+            case ORANGE_SHULKER_BOX:
+            case PURPLE_SHULKER_BOX:
+            case PINK_SHULKER_BOX:
+            case RED_SHULKER_BOX:
+            case YELLOW_SHULKER_BOX:
+            case WHITE_SHULKER_BOX:
+            case BARREL:
+                cancelAndMessage(event, player, plugin, messageManager);
+        }
     }
 
     @PermissionHandler
     public void onInteractEntity(PlayerInteractEntityEvent event) {
         Player player = event.getPlayer();
 
-        if (event.getRightClicked().getType() == EntityType.ITEM_FRAME
+        if (event.getRightClicked().getType().equals(EntityType.ITEM_FRAME)
                 || event.getRightClicked() instanceof StorageMinecart)
             cancelAndMessage(event, player, plugin, messageManager);
 

From fbc18f279c8c53141f0b28fae8b951c1ea803a73 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 16:16:55 +0200
Subject: [PATCH 19/55] Removed some entities from challenges

---
 src/main/resources/challenges.yml | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/main/resources/challenges.yml b/src/main/resources/challenges.yml
index 0a23f691..f7b0e6c0 100644
--- a/src/main/resources/challenges.yml
+++ b/src/main/resources/challenges.yml
@@ -1683,14 +1683,11 @@ challenges:
           - 'NEAR:COW 1'
           - 'NEAR:RABBIT 1'
           - 'NEAR:WOLF 1'
-          - 'NEAR:DONKEY 1'
           - 'NEAR:HORSE 1'
-          - 'NEAR:LLAMA 1'
           - 'NEAR:OCELOT 1'
           - 'NEAR:MUSHROOM_COW 1'
           - 'NEAR:SHEEP 1'
           - 'NEAR:VILLAGER 1'
-          - 'NEAR:SKELETON_HORSE 1'
         reward:
           - 'CMD:eco give {player} 3000'
           - 'ITEM:diamond_block 32'
@@ -1709,14 +1706,11 @@ challenges:
             - '&e   - 1 Cow'
             - '&e   - 1 Rabbit'
             - '&e   - 1 Wolf'
-            - '&e   - 1 Donkey'
             - '&e   - 1 Horse'
-            - '&e   - 1 Llama'
             - '&e   - 1 Ocelot'
             - '&e   - 1 Mooshroom cow'
             - '&e   - 1 Sheep'
             - '&e   - 1 Villager'
-            - '&e   - 1 Skeleton Horse'
             - '&c&lRewards:'
             - '&e- 32 diamond blocks'
             - '&e- 3000 $'

From 54aaed3fd68d22997adf006f8fd98a53472b7a7a Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 16:17:42 +0200
Subject: [PATCH 20/55] Some extra checks in Mob hurting permission

---
 .../listening/MobHurtingPermission.java          | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/MobHurtingPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/MobHurtingPermission.java
index 36a51d46..fbce594d 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/MobHurtingPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/MobHurtingPermission.java
@@ -24,18 +24,18 @@ public class MobHurtingPermission extends ListeningPermission {
 
     @PermissionHandler
     public void onVehicleDamage(VehicleDamageEvent event) {
-
-
-        Player player = (Player) event.getAttacker();
-        cancelAndMessage(event, player, plugin, messageManager);
+        if(event.getAttacker() instanceof Player){
+            Player player = (Player) event.getAttacker();
+            cancelAndMessage(event, player, plugin, messageManager);
+        }
     }
 
     @PermissionHandler
     public void onVehicleDestroy(VehicleDestroyEvent event) {
-
-
-        Player player = (Player) event.getAttacker();
-        cancelAndMessage(event, player, plugin, messageManager);
+        if(event.getAttacker() instanceof Player){
+            Player player = (Player) event.getAttacker();
+            cancelAndMessage(event, player, plugin, messageManager);
+        }
     }
 
     @PermissionHandler

From d94d7923b8fd152ad48b633d31f15a28ce31777e Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 16:17:55 +0200
Subject: [PATCH 21/55] Reworked pvp permission

---
 .../permissions/listening/PvpPermission.java  | 31 ++++++++++---------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java
index ce5ecaaa..ed3da5d0 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java
@@ -28,26 +28,27 @@ public class PvpPermission extends ListeningPermission {
 
     @PermissionHandler
     public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
-        Entity entity = event.getEntity();
-
-        Player player;
+        Player attacker = null;
         if (event.getDamager() instanceof Player)
-            player = (Player) event.getDamager();
+            attacker = (Player) event.getDamager();
         else if (event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof Player)
-            player = (Player) ((Projectile) event.getDamager()).getShooter();
-        else return;
+            attacker = (Player) ((Projectile) event.getDamager()).getShooter();
 
-        FileManager.Config config = fileManager.getConfig(new File(plugin.getDataFolder(), "config.yml"));
-        FileConfiguration configLoad = config.getFileConfiguration();
+        if(attacker instanceof Player
+                && event.getEntity() instanceof Player){
+            Player victim = (Player) event.getEntity();
 
-        if (configLoad.getBoolean("Island.Settings.PvP.Enable")) {
-            event.setCancelled(true);
-        } else if (!configLoad.getBoolean("Island.PvP.Enable")) {
-            event.setCancelled(true);
+            FileManager.Config config = fileManager.getConfig(new File(plugin.getDataFolder(), "config.yml"));
+            FileConfiguration configLoad = config.getFileConfiguration();
+
+            if (configLoad.getBoolean("Island.Settings.PvP.Enable")) {
+                event.setCancelled(true);
+            } else if (!configLoad.getBoolean("Island.PvP.Enable")) {
+                event.setCancelled(true);
+            }
+
+            cancelAndMessage(event, victim, plugin, messageManager);
         }
 
-        if (entity.getType() == EntityType.ARMOR_STAND || !(entity instanceof Monster)) return;
-
-        cancelAndMessage(event, player, plugin, messageManager);
     }
 }

From 3d0d8b602b6d05e45cc8ba90ba45c25a6294dd5d Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 17:23:24 +0200
Subject: [PATCH 22/55] 2.3.1

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 6471f5b3..49a819f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>com.songoda</groupId>
 	<artifactId>skyblock</artifactId>
-	<version>2.2.16-LaborPatch-0.0.6</version>
+	<version>2.3.1</version>
 	<packaging>jar</packaging>
 	<build>
 		<defaultGoal>clean install</defaultGoal>

From 74a9037f05d851fb0caa46a2d26616efe654f45e Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 17:26:06 +0200
Subject: [PATCH 23/55] Fixed levelling admin gui not updating

---
 src/main/java/com/songoda/skyblock/menus/admin/Levelling.java | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java b/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java
index dd69ea4c..ae8adaa8 100644
--- a/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java
+++ b/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java
@@ -332,6 +332,8 @@ public class Levelling implements Listener {
                                                 Bukkit.getServer().getScheduler().runTaskLater(skyblock,
                                                         () -> open(player), 1L);
 
+                                                levellingManager.addWorth(materials, materialPoints);
+
                                                 Bukkit.getServer().getScheduler().runTaskAsynchronously(skyblock,
                                                         () -> {
                                                             Config config1 = fileManager.getConfig(new File(

From fbd41321fcab1fca60cb96b3eb5772d8b0cfa076 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 19:10:32 +0200
Subject: [PATCH 24/55] Reworked admin settings GUI and adapted to new system

---
 .../commands/admin/SettingsCommand.java       |  12 +-
 .../skyblock/gui/GuiAdminPermissions.java     | 126 ++++++++++++++++++
 .../songoda/skyblock/gui/GuiPermissions.java  |  10 +-
 .../skyblock/gui/GuiPermissionsSelector.java  |  48 ++++---
 .../skyblock/permission/BasicPermission.java  |   6 +-
 5 files changed, 176 insertions(+), 26 deletions(-)
 create mode 100644 src/main/java/com/songoda/skyblock/gui/GuiAdminPermissions.java

diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java
index b08423ba..d19e3fd9 100644
--- a/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java
+++ b/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java
@@ -2,18 +2,28 @@ package com.songoda.skyblock.command.commands.admin;
 
 import com.songoda.core.compatibility.CompatibleSound;
 import com.songoda.skyblock.command.SubCommand;
+import com.songoda.skyblock.config.FileManager;
+import com.songoda.skyblock.gui.GuiPermissionsSelector;
+import com.songoda.skyblock.island.Island;
+import com.songoda.skyblock.island.IslandManager;
+import com.songoda.skyblock.island.IslandRole;
 import com.songoda.skyblock.menus.admin.Settings;
+import com.songoda.skyblock.message.MessageManager;
+import com.songoda.skyblock.permission.PermissionManager;
 import com.songoda.skyblock.sound.SoundManager;
 import org.bukkit.command.ConsoleCommandSender;
+import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
 
+import java.io.File;
+
 public class SettingsCommand extends SubCommand {
 
     @Override
     public void onCommandByPlayer(Player player, String[] args) {
         SoundManager soundManager = skyblock.getSoundManager();
 
-        Settings.getInstance().open(player, Settings.Type.Categories, null);
+        skyblock.getGuiManager().showGUI(player, new GuiPermissionsSelector(skyblock, null, null));
         soundManager.playSound(player, CompatibleSound.BLOCK_CHEST_OPEN.getSound(), 1.0F, 1.0F);
     }
 
diff --git a/src/main/java/com/songoda/skyblock/gui/GuiAdminPermissions.java b/src/main/java/com/songoda/skyblock/gui/GuiAdminPermissions.java
new file mode 100644
index 00000000..1089ee1a
--- /dev/null
+++ b/src/main/java/com/songoda/skyblock/gui/GuiAdminPermissions.java
@@ -0,0 +1,126 @@
+package com.songoda.skyblock.gui;
+
+import com.songoda.core.compatibility.CompatibleMaterial;
+import com.songoda.core.compatibility.CompatibleSound;
+import com.songoda.core.gui.Gui;
+import com.songoda.core.gui.GuiUtils;
+import com.songoda.core.utils.TextUtils;
+import com.songoda.skyblock.SkyBlock;
+import com.songoda.skyblock.config.FileManager;
+import com.songoda.skyblock.island.Island;
+import com.songoda.skyblock.island.IslandPermission;
+import com.songoda.skyblock.island.IslandRole;
+import com.songoda.skyblock.permission.BasicPermission;
+import com.songoda.skyblock.permission.PermissionManager;
+import com.songoda.skyblock.permission.PermissionType;
+import com.songoda.skyblock.visit.Visit;
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class GuiAdminPermissions extends Gui {
+
+    private final PermissionManager permissionManager;
+    private final IslandRole role;
+    private final FileConfiguration configLoad;
+    private final FileManager.Config settingsConfig;
+    private final FileConfiguration settingsConfigLoad;
+    private final Gui returnGui;
+
+    public GuiAdminPermissions(SkyBlock plugin, IslandRole role, Gui returnGui) {
+        super(6, returnGui);
+        this.permissionManager = plugin.getPermissionManager();
+        this.role = role;
+        this.returnGui = returnGui;
+        this.configLoad = plugin.getFileManager()
+                .getConfig(new File(plugin.getDataFolder(), "language.yml")).getFileConfiguration();
+        settingsConfig = plugin.getFileManager()
+                .getConfig(new File(plugin.getDataFolder(), "settings.yml"));
+        settingsConfigLoad = settingsConfig.getFileConfiguration();
+        setTitle(TextUtils.formatText(configLoad.getString("Menu.Settings." + role.name() + ".Title")));
+        setDefaultItem(null);
+        paint();
+    }
+
+    public void paint() {
+        if (inventory != null)
+            inventory.clear();
+        setActionForRange(0, 0, 5, 9, null);
+
+        setButton(0, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
+                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Exit.Displayname"))), (event) -> {
+            CompatibleSound.BLOCK_CHEST_CLOSE.play(event.player);
+            guiManager.showGUI(event.player, returnGui);
+        });
+
+        setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
+                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Exit.Displayname"))), (event) -> {
+            CompatibleSound.BLOCK_CHEST_CLOSE.play(event.player);
+            guiManager.showGUI(event.player, returnGui);
+        });
+
+        List<BasicPermission> permissions = permissionManager.getPermissions().stream()
+                .filter(p -> p.getType() == getType(role))
+                .collect(Collectors.toList());
+        double itemCount = permissions.size();
+        this.pages = (int) Math.max(1, Math.ceil(itemCount / 36));
+
+        if (page != 1)
+            setButton(5, 2, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
+                    TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Last.Displayname"))),
+                    (event) -> {
+                        page--;
+                        paint();
+                    });
+
+        if (page != pages)
+            setButton(5, 6, GuiUtils.createButtonItem(CompatibleMaterial.ARROW,
+                    TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Next.Displayname"))),
+                    (event) -> {
+                        page++;
+                        paint();
+                    });
+
+        for (int i = 9; i < 45; i++) {
+            int current = ((page - 1) * 36) - 9;
+            if (current + i >= permissions.size()) {
+                setItem(i, null);
+                continue;
+            }
+            BasicPermission permission = permissions.get(current + i);
+            if (permission == null) continue;
+
+            final String path = "Settings." + role.name() + "." + permission.getName();
+            boolean setting = settingsConfigLoad.getBoolean(path);
+            setButton(i, permission.getItem(setting, role), (event) -> {
+                settingsConfigLoad.set(path, !setting);
+                try {
+                    settingsConfigLoad.save(settingsConfig.getFile());
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+                paint();
+            });
+        }
+    }
+
+    public PermissionType getType(IslandRole role) {
+        switch (role) {
+            default:
+            case Visitor:
+            case Member:
+            case Coop:
+                return PermissionType.GENERIC;
+            case Operator:
+                return PermissionType.OPERATOR;
+            case Owner:
+                return PermissionType.ISLAND;
+        }
+    }
+}
diff --git a/src/main/java/com/songoda/skyblock/gui/GuiPermissions.java b/src/main/java/com/songoda/skyblock/gui/GuiPermissions.java
index 41394641..59711117 100644
--- a/src/main/java/com/songoda/skyblock/gui/GuiPermissions.java
+++ b/src/main/java/com/songoda/skyblock/gui/GuiPermissions.java
@@ -24,7 +24,7 @@ import java.util.stream.Collectors;
 
 public class GuiPermissions extends Gui {
 
-    private SkyBlock plugin;
+    private final SkyBlock plugin;
     private final PermissionManager permissionManager;
     private final IslandRole role;
     private final Island island;
@@ -63,17 +63,13 @@ public class GuiPermissions extends Gui {
                 setButton(5, GuiUtils.createButtonItem(CompatibleMaterial.MAP,
                         TextUtils.formatText(configLoad.getString("Menu.Settings.Visitor.Item.Welcome.Displayname")),
                         TextUtils.formatText(configLoad.getStringList("Menu.Settings.Visitor.Item.Welcome.Lore"))),
-                        (event) -> {
-                            guiManager.showGUI(event.player, new GuiWelcomeEditor(plugin, this, island));
-                        });
+                        (event) -> guiManager.showGUI(event.player, new GuiWelcomeEditor(plugin, this, island)));
 
             if (config.getFileConfiguration().getBoolean("Island.Visitor.Signature.Enable")) {
                 setButton(3, GuiUtils.createButtonItem(CompatibleMaterial.PAPER,
                         TextUtils.formatText(configLoad.getString("Menu.Settings.Visitor.Item.Signature.Displayname")),
                         TextUtils.formatText(configLoad.getStringList("Menu.Settings.Visitor.Item.Signature.Lore"))),
-                        (event) -> {
-                            guiManager.showGUI(event.player, new GuiSignatureEditor(plugin, this, island));
-                        });
+                        (event) -> guiManager.showGUI(event.player, new GuiSignatureEditor(plugin, this, island)));
             }
 
             Visit visit = island.getVisit();
diff --git a/src/main/java/com/songoda/skyblock/gui/GuiPermissionsSelector.java b/src/main/java/com/songoda/skyblock/gui/GuiPermissionsSelector.java
index 7bc4abee..a722099e 100644
--- a/src/main/java/com/songoda/skyblock/gui/GuiPermissionsSelector.java
+++ b/src/main/java/com/songoda/skyblock/gui/GuiPermissionsSelector.java
@@ -11,54 +11,68 @@ import com.songoda.skyblock.island.IslandRole;
 import org.bukkit.ChatColor;
 import org.bukkit.configuration.file.FileConfiguration;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import java.io.File;
 
 public class GuiPermissionsSelector extends Gui {
 
-    public GuiPermissionsSelector(SkyBlock plugin, Island island, Gui returnGui) {
+    public GuiPermissionsSelector(@Nonnull SkyBlock plugin, @Nullable Island island, @Nullable Gui returnGui) {
         super(1, returnGui);
         setDefaultItem(null);
 
+        String admin = island == null ? "Admin." : "";
+
         FileConfiguration configLoad = plugin.getFileManager()
                 .getConfig(new File(plugin.getDataFolder(), "language.yml")).getFileConfiguration();
 
         setTitle(ChatColor.translateAlternateColorCodes('&',
-                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Title"))));
+                TextUtils.formatText(configLoad.getString("Menu." + admin + "Settings.Categories.Title"))));
 
         setButton(2, GuiUtils.createButtonItem(CompatibleMaterial.OAK_SIGN,
-                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Visitor.Displayname")),
-                TextUtils.formatText(configLoad.getStringList("Menu.Settings.Categories.Item.Visitor.Lore"))), (event) ->
-                guiManager.showGUI(event.player, new GuiPermissions(plugin, island, IslandRole.Visitor, this)));
+                TextUtils.formatText(configLoad.getString("Menu." + admin + "Settings.Categories.Item.Visitor.Displayname")),
+                TextUtils.formatText(configLoad.getStringList("Menu." + admin + "Settings.Categories.Item.Visitor.Lore"))), (event) ->
+                guiManager.showGUI(event.player, island == null ?
+                        new GuiAdminPermissions(plugin, IslandRole.Visitor, this) :
+                        new GuiPermissions(plugin, island, IslandRole.Visitor, this)));
 
         setButton(3, GuiUtils.createButtonItem(CompatibleMaterial.PAINTING,
-                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Member.Displayname")),
-                TextUtils.formatText(configLoad.getStringList("Menu.Settings.Categories.Item.Member.Lore"))), (event) ->
-                guiManager.showGUI(event.player, new GuiPermissions(plugin, island, IslandRole.Member, this)));
+                TextUtils.formatText(configLoad.getString("Menu." + admin + "Settings.Categories.Item.Member.Displayname")),
+                TextUtils.formatText(configLoad.getStringList("Menu." + admin + "Settings.Categories.Item.Member.Lore"))), (event) ->
+                guiManager.showGUI(event.player, island == null ?
+                        new GuiAdminPermissions(plugin, IslandRole.Member, this) :
+                        new GuiPermissions(plugin, island, IslandRole.Member, this)));
 
         setButton(4, GuiUtils.createButtonItem(CompatibleMaterial.ITEM_FRAME,
-                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Operator.Displayname")),
-                TextUtils.formatText(configLoad.getStringList("Menu.Settings.Categories.Item.Operator.Lore"))), (event) ->
-                guiManager.showGUI(event.player, new GuiPermissions(plugin, island, IslandRole.Operator, this)));
+                TextUtils.formatText(configLoad.getString("Menu." + admin + "Settings.Categories.Item.Operator.Displayname")),
+                TextUtils.formatText(configLoad.getStringList("Menu." + admin + "Settings.Categories.Item.Operator.Lore"))), (event) ->
+                guiManager.showGUI(event.player, island == null ?
+                    new GuiAdminPermissions(plugin, IslandRole.Operator, this) :
+                    new GuiPermissions(plugin, island, IslandRole.Operator, this)));
 
         boolean isCoop = plugin.getFileManager().getConfig(new File(plugin.getDataFolder(), "config.yml")).getFileConfiguration()
                 .getBoolean("Island.Coop.Enable");
 
         setButton(0, GuiUtils.createButtonItem(CompatibleMaterial.OAK_FENCE_GATE,
-                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Exit.Displayname"))), (event) -> {
+                TextUtils.formatText(configLoad.getString("Menu." + admin + "Settings.Categories.Item.Exit.Displayname"))), (event) -> {
             CompatibleSound.BLOCK_CHEST_CLOSE.play(event.player);
             event.player.closeInventory();
         });
 
         if (isCoop)
             setButton(6, GuiUtils.createButtonItem(CompatibleMaterial.NAME_TAG,
-                    TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Coop.Displayname")),
+                    TextUtils.formatText(configLoad.getString("Menu." + admin + "Settings.Categories.Item.Coop.Displayname")),
                             TextUtils.formatText(configLoad.getStringList("Menu.Settings.Categories.Item.Coop.Lore"))), (event) ->
-                    guiManager.showGUI(event.player, new GuiPermissions(plugin, island, IslandRole.Coop, this)));
+                            guiManager.showGUI(event.player, island == null ?
+                                    new GuiAdminPermissions(plugin, IslandRole.Coop, this) :
+                                    new GuiPermissions(plugin, island, IslandRole.Coop, this)));
 
         setButton(isCoop ? 7 : 8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_SAPLING.getItem(),
-                TextUtils.formatText(configLoad.getString("Menu.Settings.Categories.Item.Owner.Displayname")),
-                        TextUtils.formatText(configLoad.getStringList("Menu.Settings.Categories.Item.Owner.Lore"))), (event) ->
-                guiManager.showGUI(event.player, new GuiPermissions(plugin, island, IslandRole.Owner, this)));
+                TextUtils.formatText(configLoad.getString("Menu." + admin + "Settings.Categories.Item.Owner.Displayname")),
+                        TextUtils.formatText(configLoad.getStringList("Menu." + admin + "Settings.Categories.Item.Owner.Lore"))), (event) ->
+                        guiManager.showGUI(event.player, island == null ?
+                                new GuiAdminPermissions(plugin, IslandRole.Owner, this) :
+                                new GuiPermissions(plugin, island, IslandRole.Owner, this)));
 
     }
 }
diff --git a/src/main/java/com/songoda/skyblock/permission/BasicPermission.java b/src/main/java/com/songoda/skyblock/permission/BasicPermission.java
index 8ecf2cb3..92f0e067 100644
--- a/src/main/java/com/songoda/skyblock/permission/BasicPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/BasicPermission.java
@@ -28,6 +28,10 @@ public abstract class BasicPermission {
     }
 
     public ItemStack getItem(Island island, IslandRole role) {
+        return getItem(island.hasPermission(role, this), role);
+    }
+
+    public ItemStack getItem(boolean permissionEnabled, IslandRole role) {
         ItemStack is = icon.getItem();
         FileManager.Config config = SkyBlock.getInstance().getFileManager()
                 .getConfig(new File(SkyBlock.getInstance().getDataFolder(), "language.yml"));
@@ -50,7 +54,7 @@ public abstract class BasicPermission {
 
         for (String itemLoreList : configLoad
                 .getStringList("Menu.Settings." + roleName + ".Item.Setting.Status."
-                        + (island.hasPermission(role, this) ? "Enabled" : "Disabled") + ".Lore"))
+                        + (permissionEnabled ? "Enabled" : "Disabled") + ".Lore"))
             itemLore.add(TextUtils.formatText(itemLoreList));
 
         im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);

From 24f722d408349bf9e6b659d91e16a0320e191780 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 20:02:56 +0200
Subject: [PATCH 25/55] Fixed white settings name

---
 src/main/resources/language.yml | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml
index 58f0d6a9..8e09ddd5 100644
--- a/src/main/resources/language.yml
+++ b/src/main/resources/language.yml
@@ -1145,6 +1145,18 @@ Menu:
             Displayname: '&aDoor Use'
           Jukebox:
             Displayname: '&aJukebox Use'
+          PvP:
+            Displayname: '&aPvP'
+          Noteblock:
+            Displayname: '&aNoteblock use'
+          Minecart:
+            Displayname: '&aMinecart'
+          Damage:
+            Displayname: '&aDamage'
+          Boat:
+            Displayname: '&aBoat'
+          Trample:
+            Displayname: '&aTrample'
           Bucket:
             Displayname: '&aBucket Use'
           SpawnEgg:
@@ -1502,6 +1514,18 @@ Menu:
                 - '&7Status&8: &cfalse'
             Milking:
               Displayname: '&aMilking'
+            PvP:
+              Displayname: '&aPvP'
+            Noteblock:
+              Displayname: '&aNoteblock use'
+            Minecart:
+              Displayname: '&aMinecart'
+            Damage:
+              Displayname: '&aDamage'
+            Boat:
+              Displayname: '&aBoat'
+            Trample:
+              Displayname: '&aTrample'
             Anvil:
               Displayname: '&aAnvil Use'
             Portal:

From bb62bc56176ea600f2429cfdcc37b7258066ac36 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Thu, 18 Jun 2020 20:04:17 +0200
Subject: [PATCH 26/55] Simplified setting icon creation

---
 .../skyblock/permission/BasicPermission.java  | 22 ++++++++++---------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/BasicPermission.java b/src/main/java/com/songoda/skyblock/permission/BasicPermission.java
index 92f0e067..bfb179bc 100644
--- a/src/main/java/com/songoda/skyblock/permission/BasicPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/BasicPermission.java
@@ -6,6 +6,7 @@ import com.songoda.skyblock.SkyBlock;
 import com.songoda.skyblock.config.FileManager;
 import com.songoda.skyblock.island.Island;
 import com.songoda.skyblock.island.IslandRole;
+import org.bukkit.Bukkit;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.inventory.ItemFlag;
 import org.bukkit.inventory.ItemStack;
@@ -48,18 +49,19 @@ public abstract class BasicPermission {
                 || role == IslandRole.Coop)
             roleName = "Default";
 
-        String nameFinal = configLoad.getString("Menu.Settings." + roleName + ".Item.Setting." + name + ".Displayname");
+        String nameFinal = TextUtils.formatText(configLoad.getString("Menu.Settings." + roleName + ".Item.Setting." + name + ".Displayname", name));
 
-        im.setDisplayName(TextUtils.formatText(nameFinal == null ? name : nameFinal));
+        if(im != null){
+            im.setDisplayName(nameFinal);
+            for (String itemLoreList : configLoad
+                    .getStringList("Menu.Settings." + roleName + ".Item.Setting.Status."
+                            + (permissionEnabled ? "Enabled" : "Disabled") + ".Lore"))
+                itemLore.add(TextUtils.formatText(itemLoreList));
 
-        for (String itemLoreList : configLoad
-                .getStringList("Menu.Settings." + roleName + ".Item.Setting.Status."
-                        + (permissionEnabled ? "Enabled" : "Disabled") + ".Lore"))
-            itemLore.add(TextUtils.formatText(itemLoreList));
-
-        im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
-        im.setLore(itemLore);
-        is.setItemMeta(im);
+            im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
+            im.setLore(itemLore);
+            is.setItemMeta(im);
+        }
 
         return is;
     }

From 9fbbca4a134881e00a25698f1ac52c3870625691 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 00:11:53 +0200
Subject: [PATCH 27/55] Fixed Portals

---
 .../com/songoda/skyblock/island/Island.java   | 17 +++++++-----
 .../songoda/skyblock/listeners/Portal.java    | 26 ++++++++-----------
 .../permission/PermissionManager.java         |  7 +++--
 .../listening/PortalPermission.java           | 19 +++++++++++---
 4 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/island/Island.java b/src/main/java/com/songoda/skyblock/island/Island.java
index 901777f9..38495a97 100644
--- a/src/main/java/com/songoda/skyblock/island/Island.java
+++ b/src/main/java/com/songoda/skyblock/island/Island.java
@@ -26,6 +26,7 @@ import org.bukkit.WeatherType;
 import org.bukkit.block.Biome;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
 
 import java.io.File;
 import java.io.IOException;
@@ -864,7 +865,7 @@ public class Island {
         getLevel().save();
     }
 
-    public boolean isRegionUnlocked(Player player, String type) {
+    public boolean isRegionUnlocked(Player player, IslandWorld type) {
         FileManager fileManager = skyblock.getFileManager();
         SoundManager soundManager = skyblock.getSoundManager();
         MessageManager messageManager = skyblock.getMessageManager();
@@ -874,22 +875,26 @@ public class Island {
                 .getConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"),
                         ownerUUID.toString() + ".yml"));
         FileConfiguration configLoadIslandData = islandData.getFileConfiguration();
-        double price = configLoad.getDouble("Island.World." + type + ".UnlockPrice");
+        double price = configLoad.getDouble("Island.World." + type.name() + ".UnlockPrice");
 
-        boolean unlocked = configLoadIslandData.getBoolean("Unlocked." + type);
+        boolean unlocked = configLoadIslandData.getBoolean("Unlocked." + type.name());
         if (price == -1) {
-            configLoadIslandData.set("Unlocked." + type, true);
+            configLoadIslandData.set("Unlocked." + type.name(), true);
             unlocked = true;
         }
 
         if (!unlocked) {
             messageManager.sendMessage(player,
                     fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml")).getFileConfiguration()
-                            .getString("Island.Unlock." + type + ".Message").replace(
+                            .getString("Island.Unlock." + type.name() + ".Message").replace(
                             "%cost%", NumberUtil.formatNumberByDecimal(price)));
 
             soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);
-            player.setVelocity(player.getLocation().getDirection().multiply(-.50));
+            if(type.equals(IslandWorld.End)){
+                player.setVelocity(player.getLocation().getDirection().multiply(-.50).setY(.6f));
+            } else if(type.equals(IslandWorld.Nether)) {
+                player.setVelocity(player.getLocation().getDirection().multiply(-.50));
+            }
         }
         return unlocked;
     }
diff --git a/src/main/java/com/songoda/skyblock/listeners/Portal.java b/src/main/java/com/songoda/skyblock/listeners/Portal.java
index 145852a3..2b76866f 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Portal.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Portal.java
@@ -81,12 +81,6 @@ public class Portal implements Listener {
         Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml"));
         FileConfiguration configLoad = config.getFileConfiguration();
 
-        PlayerEnterPortalEvent playerEnterPortalEvent = new PlayerEnterPortalEvent(player, player.getLocation()); // TODO Why?? - Fabrimat
-        // Check permissions.
-        if (!skyblock.getPermissionManager().processPermission(playerEnterPortalEvent,
-                player, island) || playerEnterPortalEvent.isCancelled())
-            return;
-
         IslandEnvironment spawnEnvironment;
         switch (island.getRole(player)) {
             case Operator:
@@ -123,23 +117,25 @@ public class Portal implements Listener {
 
         if (tick == null) return;
 
+        PlayerEnterPortalEvent playerEnterPortalEvent = new PlayerEnterPortalEvent(player, player.getLocation()); // TODO Why?? - Fabrimat
+        // Check permissions.
+        if (!skyblock.getPermissionManager().processPermission(playerEnterPortalEvent,
+                player, island))
+            return;
+
         IslandWorld fromWorld = worldManager.getIslandWorld(player.getWorld());
         IslandWorld toWorld = IslandWorld.Normal;
 
-        if (CompatibleMaterial.getMaterial(block.getType()).equals(CompatibleMaterial.NETHER_PORTAL))
+        if (block.getType().equals(CompatibleMaterial.NETHER_PORTAL.getMaterial())) {
             toWorld = fromWorld.equals(IslandWorld.Normal) ? IslandWorld.Nether : IslandWorld.Normal;
-        else if (CompatibleMaterial.getMaterial(block.getType()).equals(CompatibleMaterial.END_PORTAL))
+        } else if (block.getType().equals(CompatibleMaterial.END_PORTAL.getMaterial())) {
             toWorld = fromWorld.equals(IslandWorld.Normal) ? IslandWorld.End : IslandWorld.Normal;
+        }
 
         switch (toWorld) {
-            case Nether:
-                if (configLoad.getBoolean("Island.World.Nether.Enable") && island.isRegionUnlocked(player, "Nether")) {
-                    teleportPlayerToWorld(player, soundManager, island, spawnEnvironment, tick, toWorld);
-                }
-                break;
-
             case End:
-                if (configLoad.getBoolean("Island.World.End.Enable") && island.isRegionUnlocked(player, "End")) {
+            case Nether:
+                if (configLoad.getBoolean("Island.World." + toWorld.name() + ".Enable") && island.isRegionUnlocked(player, toWorld)) {
                     teleportPlayerToWorld(player, soundManager, island, spawnEnvironment, tick, toWorld);
                 }
                 break;
diff --git a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
index 8e760007..27ab7761 100644
--- a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
+++ b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
@@ -12,6 +12,7 @@ import org.bukkit.Location;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
 import org.bukkit.event.Cancellable;
+import org.bukkit.event.player.PlayerMoveEvent;
 
 import java.io.File;
 import java.lang.reflect.InvocationTargetException;
@@ -158,11 +159,13 @@ public class PermissionManager {
             Method handler = wrapper.getHandler();
             if (handler.getParameterTypes()[0] != cancellable.getClass()) continue;
 
-            // if (cancellable.isCancelled()) return false;
+            if (cancellable.isCancelled()) return false;
             if (cancellable instanceof Stoppable && ((Stoppable) cancellable).isStopped()) return true;
 
             BasicPermission permission = wrapper.getPermission();
 
+            //if(cancellable instanceof PlayerMoveEvent) Bukkit.broadcastMessage("A " + permission.getName());
+
             if (hasPermission(player, island, permission, reversePermission))
                 continue;
 
@@ -172,7 +175,7 @@ public class PermissionManager {
                 e.printStackTrace();
             }
         }
-        return cancellable.isCancelled();
+        return true;
     }
 
     public boolean hasPermission(Player player, Island island, BasicPermission permission, boolean reversePermission){
diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
index f339ab3a..9ff90cff 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
@@ -35,11 +35,24 @@ public class PortalPermission extends ListeningPermission {
 
             cancelAndMessage(event, player, plugin, messageManager);
             Bukkit.getScheduler().runTask(plugin, () -> {
-                player.teleport(getToLocation(event.getLocation(), player));
+                //player.teleport(getToLocation(event.getLocation(), player));
             });
         }
     }
 
+    @PermissionHandler
+    public void onMove(PlayerMoveEvent event) {
+        if(event.getTo() != null){
+            CompatibleMaterial toMaterial = CompatibleMaterial.getMaterial(event.getTo().getBlock().getType());
+
+            if (toMaterial == CompatibleMaterial.NETHER_PORTAL || toMaterial == CompatibleMaterial.END_PORTAL) {
+                //event.setTo(LocationUtil.getRandomLocation(event.getFrom().getWorld(), 5000, 5000, true, true));
+                cancelAndMessage(event, event.getPlayer(), plugin, messageManager);
+            }
+        }
+    }
+
+
     @PermissionHandler
     public void onTeleport(PlayerTeleportEvent event) {
         if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.ENDER_PEARL)
@@ -47,12 +60,12 @@ public class PortalPermission extends ListeningPermission {
                 || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)
                 || (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)
                     && event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_GATEWAY))){
-            event.getPlayer().teleport(getToLocation(event.getFrom(), event.getPlayer()));
+            /*event.getPlayer().teleport(getToLocation(event.getFrom(), event.getPlayer()));
             Location to = getToLocation(event.getFrom(), event.getPlayer());
             Bukkit.getScheduler().runTask(plugin, () -> {
                 event.getPlayer().teleport(to);
             });
-            event.setTo(to);
+            event.setTo(to);*/
 
             cancelAndMessage(event, event.getPlayer(), plugin, messageManager);
         }

From 2fef576a48df309e0a94e56f9039b15cf2bef31e Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 00:12:06 +0200
Subject: [PATCH 28/55] Fixed errors when getting safe location

---
 .../skyblock/utils/world/LocationUtil.java    | 37 +++++++++++--------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java b/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java
index cf961fd2..c2a4429f 100644
--- a/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java
+++ b/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java
@@ -18,6 +18,8 @@ import org.bukkit.block.Block;
 import org.bukkit.block.BlockFace;
 import org.bukkit.entity.Player;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
@@ -38,29 +40,32 @@ public final class LocationUtil {
         }
     }
 
-    public static Location getSafeLocation(Location loc){
+    public static @Nullable Location getSafeLocation(Location loc){
         boolean found = false;
-        Location locChecked = loc.clone();
-        loc.getWorld().loadChunk(loc.getWorld().getChunkAt(loc));
-        for(int i=loc.getBlockY(); i>=0 && !found; i--){
-            locChecked = locChecked.subtract(0d, 1d, 0d);
-            found = checkBlock(locChecked);
-        }
-        if(!found){
-            for(int i=loc.getBlockY(); i<256 && !found; i++){
-                locChecked = locChecked.add(0d, 1d, 0d);
+        Location locChecked = null;
+        if(loc != null && loc.getWorld() != null){
+            locChecked = loc.clone();
+            loc.getWorld().loadChunk(loc.getWorld().getChunkAt(loc));
+            for(int i=loc.getBlockY(); i>=0 && !found; i--){
+                locChecked = locChecked.subtract(0d, 1d, 0d);
                 found = checkBlock(locChecked);
             }
-        }
-        if (found) {
-            locChecked = locChecked.add(0d,1d,0d);
-        } else {
-            locChecked = null;
+            if(!found){
+                for(int i=loc.getBlockY(); i<256 && !found; i++){
+                    locChecked = locChecked.add(0d, 1d, 0d);
+                    found = checkBlock(locChecked);
+                }
+            }
+            if (found) {
+                locChecked = locChecked.add(0d,1d,0d);
+            } else {
+                locChecked = null;
+            }
         }
         return locChecked;
     }
 
-    public static Location getDefinitiveLocation(Location loc){
+    public static @Nonnull Location getDefinitiveLocation(Location loc){
         Location locWorking = loc.clone();
         for(int i=locWorking.getBlockY(); i>=0; i--){
             if(!locWorking.getBlock().isEmpty()){

From 62c819e6111b15fd84affd7b6203ea6d71e48f1f Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 03:07:26 +0200
Subject: [PATCH 29/55] Residence plugin support for fly

---
 pom.xml                                           |  6 ++++++
 .../songoda/skyblock/island/IslandManager.java    | 15 +++++++++++++++
 src/main/resources/plugin.yml                     |  2 +-
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 49a819f8..0bcf11c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -190,5 +190,11 @@
 			<version>LATEST</version>
 			<scope>compile</scope>
 		</dependency>
+		<dependency>
+			<groupId>com.Zrips</groupId>
+			<artifactId>Residence</artifactId>
+			<scope>provided</scope>
+			<version>4.9.0.6</version>
+		</dependency>
 	</dependencies>
 </project>
diff --git a/src/main/java/com/songoda/skyblock/island/IslandManager.java b/src/main/java/com/songoda/skyblock/island/IslandManager.java
index 0db97ead..0bf9404b 100644
--- a/src/main/java/com/songoda/skyblock/island/IslandManager.java
+++ b/src/main/java/com/songoda/skyblock/island/IslandManager.java
@@ -1,5 +1,9 @@
 package com.songoda.skyblock.island;
 
+import com.bekvon.bukkit.residence.Residence;
+import com.bekvon.bukkit.residence.api.ResidenceApi;
+import com.bekvon.bukkit.residence.containers.Flags;
+import com.bekvon.bukkit.residence.protection.ClaimedResidence;
 import com.google.common.base.Preconditions;
 import com.songoda.core.compatibility.CompatibleMaterial;
 import com.songoda.core.compatibility.CompatibleSound;
@@ -47,6 +51,7 @@ import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
 
 import java.io.File;
 import java.io.IOException;
@@ -1380,6 +1385,16 @@ public class IslandManager {
         if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR || player.hasPermission("essentials.fly") || player.hasPermission("cmi.command.fly"))
             return;
 
+        // Residence support
+        if (Bukkit.getServer().getPluginManager().getPlugin("Residence") != null) {
+            ClaimedResidence res = Residence.getInstance().getResidenceManagerAPI().getByLoc(player.getLocation());
+            if(res != null){
+                if(res.getPermissions().has(Flags.fly, false)){
+                    return;
+                }
+            }
+        }
+
         Island island = getIslandAtLocation(player.getLocation());
 
         UpgradeManager upgradeManager = skyblock.getUpgradeManager();
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index c1218e25..2932d356 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -5,7 +5,7 @@ api-version: 1.13
 description: A unique SkyBlock plugin
 author: Songoda
 authors: [Fabrimat]
-softdepend: [HolographicDisplays, Holograms, CMI, PlaceholderAPI, MVdWPlaceholderAPI, Vault, Reserve, LeaderHeads, EpicSpawners, WildStacker, UltimateStacker, WorldEdit]
+softdepend: [HolographicDisplays, Holograms, CMI, PlaceholderAPI, MVdWPlaceholderAPI, Vault, Reserve, LeaderHeads, EpicSpawners, WildStacker, UltimateStacker, WorldEdit, Residence]
 loadbefore: [Multiverse-Core, ProtocolLib]
 commands:
     island:

From 68f11d3e2b27a762aa81e1c45b86f22c4beeb6b9 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 03:07:46 +0200
Subject: [PATCH 30/55] Fixed bug that tp you in the real nether/end when
 endering portal

---
 .../com/songoda/skyblock/listeners/Teleport.java   | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Teleport.java b/src/main/java/com/songoda/skyblock/listeners/Teleport.java
index 1c6b4c11..b8263ca1 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Teleport.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Teleport.java
@@ -1,5 +1,6 @@
 package com.songoda.skyblock.listeners;
 
+import com.songoda.core.compatibility.CompatibleMaterial;
 import com.songoda.core.compatibility.CompatibleSound;
 import com.songoda.skyblock.SkyBlock;
 import com.songoda.skyblock.api.event.player.PlayerIslandEnterEvent;
@@ -11,7 +12,6 @@ import com.songoda.skyblock.config.FileManager.Config;
 import com.songoda.skyblock.island.IslandManager;
 import com.songoda.skyblock.island.IslandWorld;
 import com.songoda.skyblock.message.MessageManager;
-import com.songoda.skyblock.permission.event.events.PlayerEnterPortalEvent;
 import com.songoda.skyblock.playerdata.PlayerData;
 import com.songoda.skyblock.playerdata.PlayerDataManager;
 import com.songoda.skyblock.sound.SoundManager;
@@ -20,6 +20,7 @@ import com.songoda.skyblock.world.WorldManager;
 import org.bukkit.Bukkit;
 import org.bukkit.Location;
 import org.bukkit.OfflinePlayer;
+import org.bukkit.World;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.EntityType;
 import org.bukkit.entity.Player;
@@ -56,6 +57,17 @@ public class Teleport implements Listener {
         Bukkit.getScheduler().runTaskLater(skyblock, () -> islandManager.updateFlight(player), 1L);
         islandManager.loadPlayer(player);
 
+
+        // Fix for bug that tp you in the real Nether/End when entering in a portal in an island
+        if (worldManager.isIslandWorld(event.getFrom().getWorld())
+                && !worldManager.isIslandWorld(event.getTo().getWorld())
+                && (event.getFrom().getBlock().getType().equals(CompatibleMaterial.END_PORTAL.getMaterial())
+                    || event.getFrom().getBlock().getType().equals(CompatibleMaterial.NETHER_PORTAL.getMaterial())) && (event.getTo().getWorld() != null
+                && event.getTo().getWorld().getEnvironment().equals(World.Environment.NETHER)
+                    || event.getTo().getWorld().getEnvironment().equals(World.Environment.THE_END))) {
+            event.setCancelled(true);
+        }
+
         if (worldManager.isIslandWorld(player.getWorld())) {
 
             com.songoda.skyblock.island.Island island = islandManager.getIslandAtLocation(event.getTo());

From 601acb2b728f6ad7fe96084a58a97932a7bf690c Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 05:03:32 +0200
Subject: [PATCH 31/55] Make more method synchronized in order to try avoiding
 IO issues

---
 .../java/com/songoda/skyblock/island/Island.java |  2 +-
 .../songoda/skyblock/island/IslandManager.java   | 16 ++++++++--------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/island/Island.java b/src/main/java/com/songoda/skyblock/island/Island.java
index 38495a97..b83c1f52 100644
--- a/src/main/java/com/songoda/skyblock/island/Island.java
+++ b/src/main/java/com/songoda/skyblock/island/Island.java
@@ -812,7 +812,7 @@ public class Island {
         this.deleted = deleted;
     }
 
-    public void save() {
+    public synchronized void save() {
         FileManager fileManager = skyblock.getFileManager();
 
         Config config = fileManager
diff --git a/src/main/java/com/songoda/skyblock/island/IslandManager.java b/src/main/java/com/songoda/skyblock/island/IslandManager.java
index 0bf9404b..ebf350af 100644
--- a/src/main/java/com/songoda/skyblock/island/IslandManager.java
+++ b/src/main/java/com/songoda/skyblock/island/IslandManager.java
@@ -102,7 +102,7 @@ public class IslandManager {
         }
     }
 
-    public void saveNextAvailableLocation(IslandWorld world) {
+    public synchronized void saveNextAvailableLocation(IslandWorld world) {
         FileManager fileManager = skyblock.getFileManager();
         Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "worlds.yml"));
 
@@ -124,7 +124,7 @@ public class IslandManager {
         }
     }
 
-    public void setNextAvailableLocation(IslandWorld world, org.bukkit.Location location) {
+    public synchronized void setNextAvailableLocation(IslandWorld world, org.bukkit.Location location) {
         for (IslandPosition islandPositionList : islandPositions) {
             if (islandPositionList.getWorld() == world) {
                 islandPositionList.setX(location.getX());
@@ -134,7 +134,7 @@ public class IslandManager {
     }
 
 
-    public org.bukkit.Location prepareNextAvailableLocation(IslandWorld world) {
+    public synchronized org.bukkit.Location prepareNextAvailableLocation(IslandWorld world) {
         for (IslandPosition islandPositionList : islandPositions) {
             if (islandPositionList.getWorld() == world) {
 
@@ -196,7 +196,7 @@ public class IslandManager {
         return null;
     }
 
-    public boolean createIsland(Player player, Structure structure) {
+    public synchronized boolean createIsland(Player player, Structure structure) {
         ScoreboardManager scoreboardManager = skyblock.getScoreboardManager();
         VisitManager visitManager = skyblock.getVisitManager();
         FileManager fileManager = skyblock.getFileManager();
@@ -296,7 +296,7 @@ public class IslandManager {
         return true;
     }
 
-    public boolean previewIsland(Player player, Structure structure) {
+    public synchronized boolean previewIsland(Player player, Structure structure) {
         FileManager fileManager = skyblock.getFileManager();
 
         PlayerData data = skyblock.getPlayerDataManager().getPlayerData(player);
@@ -407,7 +407,7 @@ public class IslandManager {
         return true;
     }
 
-    public void giveOwnership(Island island, org.bukkit.OfflinePlayer player) {
+    public synchronized void giveOwnership(Island island, org.bukkit.OfflinePlayer player) {
         PlayerDataManager playerDataManager = skyblock.getPlayerDataManager();
         CooldownManager cooldownManager = skyblock.getCooldownManager();
         FileManager fileManager = skyblock.getFileManager();
@@ -529,7 +529,7 @@ public class IslandManager {
         }
     }
 
-    public boolean deleteIsland(Island island, boolean force) {
+    public synchronized boolean deleteIsland(Island island, boolean force) {
         ScoreboardManager scoreboardManager = skyblock.getScoreboardManager();
         PlayerDataManager playerDataManager = skyblock.getPlayerDataManager();
         CooldownManager cooldownManager = skyblock.getCooldownManager();
@@ -657,7 +657,7 @@ public class IslandManager {
         return true;
     }
 
-    public void deleteIslandData(UUID uuid) {
+    public synchronized void deleteIslandData(UUID uuid) {
         FileManager fileManager = skyblock.getFileManager();
         fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/island-data", uuid.toString() + ".yml"));
         fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/ban-data", uuid.toString() + ".yml"));

From cb586ee840c6a511d4f140db0deedc5b1eddaae3 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 05:10:45 +0200
Subject: [PATCH 32/55] 2.3.2

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 0bcf11c7..0839c7df 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>com.songoda</groupId>
 	<artifactId>skyblock</artifactId>
-	<version>2.3.1</version>
+	<version>2.3.2</version>
 	<packaging>jar</packaging>
 	<build>
 		<defaultGoal>clean install</defaultGoal>

From 8a601a605cb4111d0078ce80dc48d91e27335468 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 15:51:57 +0200
Subject: [PATCH 33/55] Removed useless null

---
 src/main/java/com/songoda/skyblock/listeners/Spawner.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Spawner.java b/src/main/java/com/songoda/skyblock/listeners/Spawner.java
index ef2f6338..0c934716 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Spawner.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Spawner.java
@@ -46,7 +46,7 @@ public class Spawner implements Listener {
                         spawner.setMaxSpawnDelay(400);
                     } else {
                         try {
-                            Object MobSpawner = null;
+                            Object MobSpawner;
 
                             try {
                                 Field TileEntityMobSpawnerField = spawner.getClass().getDeclaredField("spawner");

From a97d951b7f3fd223e38b23c710a55633dca5f226 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 16:09:47 +0200
Subject: [PATCH 34/55] Fixed checks in challenge management

---
 .../skyblock/challenge/challenge/Challenge.java      | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java b/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java
index d7deaf71..28ff0685 100644
--- a/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java
+++ b/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java
@@ -6,6 +6,8 @@ import java.util.List;
 import java.util.regex.Pattern;
 
 import com.songoda.core.compatibility.CompatibleMaterial;
+import com.songoda.skyblock.SkyBlock;
+import com.songoda.skyblock.island.Island;
 import org.bukkit.Bukkit;
 import org.bukkit.Material;
 import org.bukkit.entity.Entity;
@@ -18,7 +20,6 @@ import org.bukkit.potion.PotionData;
 import org.bukkit.potion.PotionType;
 
 import com.songoda.skyblock.api.SkyBlockAPI;
-import com.songoda.skyblock.api.island.Island;
 
 public class Challenge {
 	private ChallengeCategory category;
@@ -240,11 +241,12 @@ public class Challenge {
 			public boolean has(Player p, Object obj) {
 				// Check if the level of player's island is greater or equals to the required
 				// level
-				Island is = SkyBlockAPI.getIslandManager().getIsland(p);
+				Island is = SkyBlock.getInstance().getIslandManager().getIsland(p);
 				// Player doesn't have an island
-				if (is == null)
-					return false;
-				return is.getLevel().getLevel() >= (Integer) obj;
+				if (is != null && obj instanceof Number) {
+					return is.getLevel().getLevel() >= (Long) obj;
+				}
+				return false;
 			}
 
 			@Override

From 00e5ff18ec1834fe9cb56207466bddf832a7ee02 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 16:17:55 +0200
Subject: [PATCH 35/55] Fix for proxy command not working with offline players

---
 .../skyblock/command/commands/admin/ProxyCommand.java       | 4 +++-
 .../java/com/songoda/skyblock/island/IslandManager.java     | 6 ++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/ProxyCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/ProxyCommand.java
index 1400d0b4..d97b773e 100644
--- a/src/main/java/com/songoda/skyblock/command/commands/admin/ProxyCommand.java
+++ b/src/main/java/com/songoda/skyblock/command/commands/admin/ProxyCommand.java
@@ -8,6 +8,7 @@ import com.songoda.skyblock.island.IslandManager;
 import com.songoda.skyblock.message.MessageManager;
 import com.songoda.skyblock.sound.SoundManager;
 import com.songoda.skyblock.utils.player.OfflinePlayer;
+import org.bukkit.Bukkit;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.ConsoleCommandSender;
 import org.bukkit.configuration.file.FileConfiguration;
@@ -39,9 +40,10 @@ public class ProxyCommand extends SubCommand {
 
         if (args.length == 1) {
             OfflinePlayer targetPlayerOffline = new OfflinePlayer(args[0]);
+
             UUID islandOwnerUUID = targetPlayerOffline.getOwner();
 
-            if (islandManager.containsIsland(islandOwnerUUID)) {
+            if (islandManager.getIsland(Bukkit.getOfflinePlayer(islandOwnerUUID)) != null) {
                 if (islandManager.isPlayerProxyingAnotherPlayer(((Player)sender).getUniqueId())) {
                     messageManager.sendMessage(sender,
                             configLoad.getString("Command.Island.Admin.Proxy.IsOffPlayer.Message")
diff --git a/src/main/java/com/songoda/skyblock/island/IslandManager.java b/src/main/java/com/songoda/skyblock/island/IslandManager.java
index ebf350af..52836fcb 100644
--- a/src/main/java/com/songoda/skyblock/island/IslandManager.java
+++ b/src/main/java/com/songoda/skyblock/island/IslandManager.java
@@ -1191,8 +1191,8 @@ public class IslandManager {
             return islandStorage.get(uuid);
         }
 
-        if (offlinePlayer.isOnline()) {
-            Player player = offlinePlayer.getPlayer();
+        Player player = offlinePlayer.getPlayer();
+        if (offlinePlayer.isOnline() && player != null) {
 
             if (playerDataManager.hasPlayerData(player)) {
                 PlayerData playerData = playerDataManager.getPlayerData(player);
@@ -1207,6 +1207,8 @@ public class IslandManager {
             if (offlinePlayerData.getOwner() != null && islandStorage.containsKey(offlinePlayer.getUniqueId())) {
                 return islandStorage.get(offlinePlayerData.getOwner());
             }
+
+            return loadIsland(offlinePlayer); // TODO That could be done first, needs testing - Fabrimat
         }
 
         return null;

From 7fd6f967dca4eb94c61128903833f229db9cca93 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 16:49:29 +0200
Subject: [PATCH 36/55] Optimize and fix pvp permission message

---
 .../permissions/listening/PvpPermission.java   | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java
index ed3da5d0..334162e5 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PvpPermission.java
@@ -8,7 +8,8 @@ import com.songoda.skyblock.permission.ListeningPermission;
 import com.songoda.skyblock.permission.PermissionHandler;
 import com.songoda.skyblock.permission.PermissionType;
 import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.entity.*;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Projectile;
 import org.bukkit.event.entity.EntityDamageByEntityEvent;
 
 import java.io.File;
@@ -29,25 +30,22 @@ public class PvpPermission extends ListeningPermission {
     @PermissionHandler
     public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
         Player attacker = null;
-        if (event.getDamager() instanceof Player)
+        if (event.getDamager() instanceof Player) {
             attacker = (Player) event.getDamager();
-        else if (event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof Player)
+        } else if (event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof Player) {
             attacker = (Player) ((Projectile) event.getDamager()).getShooter();
+        }
 
-        if(attacker instanceof Player
-                && event.getEntity() instanceof Player){
-            Player victim = (Player) event.getEntity();
+        if(attacker != null && event.getEntity() instanceof Player){
 
             FileManager.Config config = fileManager.getConfig(new File(plugin.getDataFolder(), "config.yml"));
             FileConfiguration configLoad = config.getFileConfiguration();
 
-            if (configLoad.getBoolean("Island.Settings.PvP.Enable")) {
-                event.setCancelled(true);
-            } else if (!configLoad.getBoolean("Island.PvP.Enable")) {
+            if (configLoad.getBoolean("Island.Settings.PvP.Enable") || !configLoad.getBoolean("Island.PvP.Enable")) {
                 event.setCancelled(true);
             }
 
-            cancelAndMessage(event, victim, plugin, messageManager);
+            cancelAndMessage(event, attacker, plugin, messageManager);
         }
 
     }

From e64b3542523f9686ce191d5121537f0eb28904c9 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 16:50:07 +0200
Subject: [PATCH 37/55] Removed pvp default value from owner

---
 src/main/resources/settings.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml
index 63e4ccbd..5b408de9 100644
--- a/src/main/resources/settings.yml
+++ b/src/main/resources/settings.yml
@@ -161,7 +161,6 @@ Settings:
     Owner:
         NaturalMobSpawning: true
         MobGriefing: false
-        PvP: false
         Explosions: false
         FireSpread: true
         LeafDecay: true

From 2c4bb357da75d49d4e3482ee126b97cbbd3d2b69 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 22:29:55 +0200
Subject: [PATCH 38/55] Fixed portals

---
 .../songoda/skyblock/listeners/Portal.java    | 41 +++++++++++--------
 .../listening/PortalPermission.java           |  3 --
 2 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Portal.java b/src/main/java/com/songoda/skyblock/listeners/Portal.java
index 2b76866f..d7001f1a 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Portal.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Portal.java
@@ -119,9 +119,8 @@ public class Portal implements Listener {
 
         PlayerEnterPortalEvent playerEnterPortalEvent = new PlayerEnterPortalEvent(player, player.getLocation()); // TODO Why?? - Fabrimat
         // Check permissions.
-        if (!skyblock.getPermissionManager().processPermission(playerEnterPortalEvent,
-                player, island))
-            return;
+        boolean perms = !skyblock.getPermissionManager().processPermission(playerEnterPortalEvent,
+                player, island);
 
         IslandWorld fromWorld = worldManager.getIslandWorld(player.getWorld());
         IslandWorld toWorld = IslandWorld.Normal;
@@ -132,21 +131,29 @@ public class Portal implements Listener {
             toWorld = fromWorld.equals(IslandWorld.Normal) ? IslandWorld.End : IslandWorld.Normal;
         }
 
-        switch (toWorld) {
-            case End:
-            case Nether:
-                if (configLoad.getBoolean("Island.World." + toWorld.name() + ".Enable") && island.isRegionUnlocked(player, toWorld)) {
-                    teleportPlayerToWorld(player, soundManager, island, spawnEnvironment, tick, toWorld);
-                }
-                break;
+        if(!perms){
+            switch (toWorld) {
+                case End:
+                case Nether:
+                    if (configLoad.getBoolean("Island.World." + toWorld.name() + ".Enable") && island.isRegionUnlocked(player, toWorld)) {
+                        teleportPlayerToWorld(player, soundManager, island, spawnEnvironment, tick, toWorld);
+                    }
+                    break;
 
-            default:
-                IslandWorld toWorldF = toWorld;
-                Bukkit.getScheduler().scheduleSyncDelayedTask(skyblock, () -> player.teleport(island.getLocation(toWorldF, spawnEnvironment)), 1L);
-                soundManager.playSound(player, CompatibleSound.ENTITY_ENDERMAN_TELEPORT.getSound(), 1.0F, 1.0F);
-                player.setFallDistance(0.0F);
-                tick.setTick(1);
-                break;
+                default:
+                    IslandWorld toWorldF = toWorld;
+                    Bukkit.getScheduler().scheduleSyncDelayedTask(skyblock, () -> player.teleport(island.getLocation(toWorldF, spawnEnvironment)), 1L);
+                    soundManager.playSound(player, CompatibleSound.ENTITY_ENDERMAN_TELEPORT.getSound(), 1.0F, 1.0F);
+                    player.setFallDistance(0.0F);
+                    tick.setTick(1);
+                    break;
+            }
+        } else {
+            if(toWorld.equals(IslandWorld.End)){
+                player.setVelocity(player.getLocation().getDirection().multiply(-.50).setY(.6f));
+            } else if(toWorld.equals(IslandWorld.Nether)) {
+                player.setVelocity(player.getLocation().getDirection().multiply(-.50));
+            }
         }
 
     }
diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
index 9ff90cff..fbd4ef43 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/PortalPermission.java
@@ -34,9 +34,6 @@ public class PortalPermission extends ListeningPermission {
             Player player = (Player) event.getEntity();
 
             cancelAndMessage(event, player, plugin, messageManager);
-            Bukkit.getScheduler().runTask(plugin, () -> {
-                //player.teleport(getToLocation(event.getLocation(), player));
-            });
         }
     }
 

From e9cbfdac925c6207b545cb923a9a1d0b9e50249a Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 22:46:51 +0200
Subject: [PATCH 39/55] Fix for is kick offline members

---
 .../skyblock/command/commands/island/KickCommand.java        | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/command/commands/island/KickCommand.java b/src/main/java/com/songoda/skyblock/command/commands/island/KickCommand.java
index cc83190a..ee2be148 100644
--- a/src/main/java/com/songoda/skyblock/command/commands/island/KickCommand.java
+++ b/src/main/java/com/songoda/skyblock/command/commands/island/KickCommand.java
@@ -72,8 +72,7 @@ public class KickCommand extends SubCommand {
                                 targetPlayerName = targetPlayer.getName();
                             }
 
-                            assert targetPlayer != null;
-                            if((targetPlayer.hasPermission("fabledskyblock.bypass.kick") || targetPlayer.isOp()) && islandVisitors.contains(targetPlayer.getUniqueId())){
+                            if(targetPlayer != null && (targetPlayer.hasPermission("fabledskyblock.bypass.kick") || targetPlayer.isOp()) && islandVisitors.contains(targetPlayer.getUniqueId())){
                                 messageManager.sendMessage(player, languageConfig.getFileConfiguration().getString("Command.Island.Kick.Exempt"));
                                 soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);
                             } else if (targetPlayerUUID.equals(player.getUniqueId())) {
@@ -85,7 +84,7 @@ public class KickCommand extends SubCommand {
                             } else if (island.getOwnerUUID().equals(targetPlayerUUID)) {
                                 messageManager.sendMessage(player, languageConfig.getFileConfiguration().getString("Command.Island.Kick.Role.Owner.Message"));
                                 soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);
-                            } else if (island.isOpen() && islandVisitors.contains(targetPlayerUUID) && targetPlayer != null) {
+                            } else if (island.isOpen() && islandVisitors.contains(targetPlayerUUID)) {
                                 if (island.isCoopPlayer(targetPlayerUUID)) {
                                     messageManager.sendMessage(player, languageConfig.getFileConfiguration().getString("Command.Island.Kick.Cooped.Message"));
                                     soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);

From 341edb3c3b24e06a62974abae3a205495dbde0e6 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 22:47:40 +0200
Subject: [PATCH 40/55] Fixed loading islands for offline members

---
 .../songoda/skyblock/api/island/Island.java   |  3 ++-
 .../command/commands/admin/DeleteCommand.java |  3 ++-
 .../commands/admin/SetBiomeCommand.java       |  3 ++-
 .../commands/island/AcceptCommand.java        |  4 +--
 .../skyblock/island/IslandManager.java        | 27 +++++++++----------
 .../com/songoda/skyblock/listeners/Join.java  |  3 ++-
 .../com/songoda/skyblock/listeners/Move.java  |  3 ++-
 7 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/api/island/Island.java b/src/main/java/com/songoda/skyblock/api/island/Island.java
index ee95ae3d..2173931c 100644
--- a/src/main/java/com/songoda/skyblock/api/island/Island.java
+++ b/src/main/java/com/songoda/skyblock/api/island/Island.java
@@ -459,7 +459,8 @@ public class Island {
 	 */
 	public void load() {
 		if (this.handle == null) {
-			this.handle = SkyBlockAPI.getImplementation().getIslandManager().loadIsland(player);
+			SkyBlockAPI.getImplementation().getIslandManager().loadIsland(player);
+			this.handle = SkyBlockAPI.getImplementation().getIslandManager().getIsland(player);
 		}
 	}
 
diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/DeleteCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/DeleteCommand.java
index 9488733b..da182ad6 100644
--- a/src/main/java/com/songoda/skyblock/command/commands/admin/DeleteCommand.java
+++ b/src/main/java/com/songoda/skyblock/command/commands/admin/DeleteCommand.java
@@ -68,7 +68,8 @@ public class DeleteCommand extends SubCommand {
                         configLoad.getString("Command.Island.Admin.Delete.Owner.Message"));
                 soundManager.playSound(sender, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);
             } else {
-                Island island = islandManager.loadIsland(Bukkit.getServer().getOfflinePlayer(targetPlayerUUID));
+                islandManager.loadIsland(Bukkit.getServer().getOfflinePlayer(targetPlayerUUID));
+                Island island = islandManager.getIsland(Bukkit.getServer().getOfflinePlayer(targetPlayerUUID));
                 Location spawnLocation = LocationUtil.getSpawnLocation();
 
                 if (spawnLocation != null && islandManager.isLocationAtIsland(island, spawnLocation)) {
diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/SetBiomeCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/SetBiomeCommand.java
index e97e8ed1..3ac41cc8 100644
--- a/src/main/java/com/songoda/skyblock/command/commands/admin/SetBiomeCommand.java
+++ b/src/main/java/com/songoda/skyblock/command/commands/admin/SetBiomeCommand.java
@@ -79,7 +79,8 @@ public class SetBiomeCommand extends SubCommand {
                         biomeManager.setBiome(island, biome.getBiome());
                         island.setBiome(biome.getBiome());
                     } else {
-                        Island island = islandManager.loadIsland(Bukkit.getOfflinePlayer(islandOwnerUUID));
+                        islandManager.loadIsland(Bukkit.getOfflinePlayer(islandOwnerUUID));
+                        Island island = islandManager.getIsland(Bukkit.getOfflinePlayer(islandOwnerUUID));
                         if (island == null) {
                             messageManager.sendMessage(sender,
                                     configLoad.getString("Command.Island.Admin.SetBiome.Island.Data.Message"));
diff --git a/src/main/java/com/songoda/skyblock/command/commands/island/AcceptCommand.java b/src/main/java/com/songoda/skyblock/command/commands/island/AcceptCommand.java
index 11b4c2c7..8cf32a29 100644
--- a/src/main/java/com/songoda/skyblock/command/commands/island/AcceptCommand.java
+++ b/src/main/java/com/songoda/skyblock/command/commands/island/AcceptCommand.java
@@ -62,8 +62,8 @@ public class AcceptCommand extends SubCommand {
                             island = islandManager
                                     .getIsland(Bukkit.getServer().getOfflinePlayer(invite.getOwnerUUID()));
                         } else {
-                            island = islandManager
-                                    .loadIsland(Bukkit.getServer().getOfflinePlayer(invite.getOwnerUUID()));
+                            islandManager.loadIsland(Bukkit.getServer().getOfflinePlayer(invite.getOwnerUUID()));
+                            island = islandManager.getIsland(Bukkit.getServer().getOfflinePlayer(invite.getOwnerUUID()));
                             unloadIsland = true;
                         }
 
diff --git a/src/main/java/com/songoda/skyblock/island/IslandManager.java b/src/main/java/com/songoda/skyblock/island/IslandManager.java
index 52836fcb..f0238949 100644
--- a/src/main/java/com/songoda/skyblock/island/IslandManager.java
+++ b/src/main/java/com/songoda/skyblock/island/IslandManager.java
@@ -671,7 +671,7 @@ public class IslandManager {
         }
     }
 
-    public Island loadIsland(org.bukkit.OfflinePlayer player) {
+    public void loadIsland(org.bukkit.OfflinePlayer player) {
         VisitManager visitManager = skyblock.getVisitManager();
         FileManager fileManager = skyblock.getFileManager();
         BanManager banManager = skyblock.getBanManager();
@@ -686,7 +686,7 @@ public class IslandManager {
                 deleteIslandData(player.getUniqueId());
                 configLoad.set("Island.Owner", null);
 
-                return null;
+                return;
             }
 
             islandOwnerUUID = player.getUniqueId();
@@ -698,7 +698,8 @@ public class IslandManager {
 
         if (islandOwnerUUID != null) {
             if (containsIsland(islandOwnerUUID)) {
-                return getIsland(player);
+                //return getIsland(player);
+                return;
             } else {
                 config = fileManager.getConfig(new File(skyblock.getDataFolder().toString() + "/island-data", islandOwnerUUID.toString() + ".yml"));
 
@@ -706,7 +707,7 @@ public class IslandManager {
                     deleteIslandData(islandOwnerUUID);
                     configLoad.set("Island.Owner", null);
 
-                    return null;
+                    return;
                 }
 
                 Island island = new Island(Bukkit.getServer().getOfflinePlayer(islandOwnerUUID));
@@ -731,11 +732,9 @@ public class IslandManager {
                 Bukkit.getScheduler().runTask(skyblock, () ->
                         Bukkit.getServer().getPluginManager().callEvent(new IslandLoadEvent(island.getAPIWrapper())));
 
-                return island;
+                return;
             }
         }
-
-        return null;
     }
 
     /**
@@ -786,11 +785,11 @@ public class IslandManager {
         oldSystemIslands.put(IslandWorld.End, endZ);
     }
 
-    public Island loadIslandAtLocation(Location location) {
+    public void loadIslandAtLocation(Location location) {
         FileManager fileManager = skyblock.getFileManager();
         File configFile = new File(skyblock.getDataFolder().toString() + "/island-data");
 
-        if (!configFile.exists()) return null;
+        if (!configFile.exists()) return;
 
         for (File fileList : configFile.listFiles()) {
             if (fileList != null && fileList.getName().contains(".yml") && fileList.getName().length() > 35) {
@@ -807,7 +806,8 @@ public class IslandManager {
 
                     if (LocationUtil.isLocationAtLocationRadius(location, islandLocation, size)) {
                         UUID islandOwnerUUID = UUID.fromString(fileList.getName().replace(".yml", ""));
-                        return this.loadIsland(Bukkit.getOfflinePlayer(islandOwnerUUID));
+                        // return this.loadIsland(Bukkit.getOfflinePlayer(islandOwnerUUID));
+                        return;
                     }
                 } catch (Exception e) {
                     e.printStackTrace();
@@ -815,7 +815,7 @@ public class IslandManager {
             }
         }
 
-        return null;
+        return;
     }
 
     public void unloadIsland(Island island, org.bukkit.OfflinePlayer player) {
@@ -1203,12 +1203,11 @@ public class IslandManager {
             }
         } else {
             OfflinePlayer offlinePlayerData = new OfflinePlayer(offlinePlayer.getUniqueId());
+            loadIsland(offlinePlayer);
 
             if (offlinePlayerData.getOwner() != null && islandStorage.containsKey(offlinePlayer.getUniqueId())) {
                 return islandStorage.get(offlinePlayerData.getOwner());
             }
-
-            return loadIsland(offlinePlayer); // TODO That could be done first, needs testing - Fabrimat
         }
 
         return null;
@@ -1391,7 +1390,7 @@ public class IslandManager {
         if (Bukkit.getServer().getPluginManager().getPlugin("Residence") != null) {
             ClaimedResidence res = Residence.getInstance().getResidenceManagerAPI().getByLoc(player.getLocation());
             if(res != null){
-                if(res.getPermissions().has(Flags.fly, false)){
+                if (res.getPermissions().has(Flags.fly, false) || res.getPermissions().has(Flags.nofly, false)) {
                     return;
                 }
             }
diff --git a/src/main/java/com/songoda/skyblock/listeners/Join.java b/src/main/java/com/songoda/skyblock/listeners/Join.java
index 9777b402..0b3883dd 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Join.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Join.java
@@ -50,7 +50,8 @@ public class Join implements Listener {
             userCacheManager.saveAsync();
 
             try {
-                Island island = islandManager.loadIsland(player);
+                islandManager.loadIsland(player);
+                Island island = islandManager.getIsland(player);
                 boolean teleportedToIsland = false;
 
                 Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml"));
diff --git a/src/main/java/com/songoda/skyblock/listeners/Move.java b/src/main/java/com/songoda/skyblock/listeners/Move.java
index e3ef3789..6ba945aa 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Move.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Move.java
@@ -169,7 +169,8 @@ public class Move implements Listener {
             }
 
             // Load the island they are now on if one exists
-            Island loadedIsland = islandManager.loadIslandAtLocation(player.getLocation());
+            islandManager.loadIslandAtLocation(player.getLocation());
+            Island loadedIsland = islandManager.getIslandAtLocation(player.getLocation());
             if (loadedIsland != null) {
                 if (player.hasPermission("fabledskyblock.bypass")) {
                     playerData.setIsland(loadedIsland.getOwnerUUID());

From 66e3dfbc01e849ff0b8938926d315c383e78694d Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 22:48:11 +0200
Subject: [PATCH 41/55] Fix for Residence compatibility

---
 .../java/com/songoda/skyblock/listeners/Teleport.java    | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Teleport.java b/src/main/java/com/songoda/skyblock/listeners/Teleport.java
index b8263ca1..81c52552 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Teleport.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Teleport.java
@@ -54,17 +54,20 @@ public class Teleport implements Listener {
         Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml"));
         FileConfiguration configLoad = config.getFileConfiguration();
 
-        Bukkit.getScheduler().runTaskLater(skyblock, () -> islandManager.updateFlight(player), 1L);
+        if(worldManager.isIslandWorld(event.getFrom().getWorld())
+                 || (event.getTo() != null && worldManager.isIslandWorld(event.getTo().getWorld()))) {
+            Bukkit.getScheduler().runTaskLater(skyblock, () -> islandManager.updateFlight(player), 1L);
+        }
         islandManager.loadPlayer(player);
 
 
         // Fix for bug that tp you in the real Nether/End when entering in a portal in an island
-        if (worldManager.isIslandWorld(event.getFrom().getWorld())
+        if (event.getTo() != null && (worldManager.isIslandWorld(event.getFrom().getWorld())
                 && !worldManager.isIslandWorld(event.getTo().getWorld())
                 && (event.getFrom().getBlock().getType().equals(CompatibleMaterial.END_PORTAL.getMaterial())
                     || event.getFrom().getBlock().getType().equals(CompatibleMaterial.NETHER_PORTAL.getMaterial())) && (event.getTo().getWorld() != null
                 && event.getTo().getWorld().getEnvironment().equals(World.Environment.NETHER)
-                    || event.getTo().getWorld().getEnvironment().equals(World.Environment.THE_END))) {
+                    || event.getTo().getWorld().getEnvironment().equals(World.Environment.THE_END)))) {
             event.setCancelled(true);
         }
 

From 969306bf6bf3b87c4eb4ae183c24c4eeeedc2b01 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 22:48:26 +0200
Subject: [PATCH 42/55] Added Damage setting to settings.yml

---
 src/main/resources/settings.yml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml
index 5b408de9..63f8fe53 100644
--- a/src/main/resources/settings.yml
+++ b/src/main/resources/settings.yml
@@ -48,6 +48,7 @@ Settings:
         ExperienceOrbPickup: false
         Trapdoor: false
         Noteblock: false
+        Damage: true
     Member:
         Destroy: true
         Place: true
@@ -97,6 +98,7 @@ Settings:
         ExperienceOrbPickup: true
         Trapdoor: true
         Noteblock: true
+        Damage: true
     Operator:
         Invite: true
         Kick: true
@@ -158,6 +160,7 @@ Settings:
         Hopper: true
         EntityPlacement: true
         ExperienceOrbPickup: true
+        Damage: true
     Owner:
         NaturalMobSpawning: true
         MobGriefing: false
@@ -165,5 +168,4 @@ Settings:
         FireSpread: true
         LeafDecay: true
         KeepItemsOnDeath: true
-        Damage: true
         Hunger: true
\ No newline at end of file

From 824145276e7cf8f43c2743936ce3d13c17ac5a50 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 22:49:09 +0200
Subject: [PATCH 43/55] Fix for portals

---
 .../com/songoda/skyblock/permission/PermissionManager.java    | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
index 27ab7761..64dcca9c 100644
--- a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
+++ b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
@@ -164,8 +164,6 @@ public class PermissionManager {
 
             BasicPermission permission = wrapper.getPermission();
 
-            //if(cancellable instanceof PlayerMoveEvent) Bukkit.broadcastMessage("A " + permission.getName());
-
             if (hasPermission(player, island, permission, reversePermission))
                 continue;
 
@@ -175,7 +173,7 @@ public class PermissionManager {
                 e.printStackTrace();
             }
         }
-        return true;
+        return !cancellable.isCancelled();
     }
 
     public boolean hasPermission(Player player, Island island, BasicPermission permission, boolean reversePermission){

From dfdf0ae259461c9c4ff2f6d6bf5d8b3dd4d6eb79 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 23:01:36 +0200
Subject: [PATCH 44/55] Removed old admin Settings file

---
 .../commands/admin/SettingsCommand.java       |  10 -
 .../skyblock/menus/admin/Settings.java        | 686 ------------------
 2 files changed, 696 deletions(-)
 delete mode 100644 src/main/java/com/songoda/skyblock/menus/admin/Settings.java

diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java
index d19e3fd9..7e05dfdb 100644
--- a/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java
+++ b/src/main/java/com/songoda/skyblock/command/commands/admin/SettingsCommand.java
@@ -2,21 +2,11 @@ package com.songoda.skyblock.command.commands.admin;
 
 import com.songoda.core.compatibility.CompatibleSound;
 import com.songoda.skyblock.command.SubCommand;
-import com.songoda.skyblock.config.FileManager;
 import com.songoda.skyblock.gui.GuiPermissionsSelector;
-import com.songoda.skyblock.island.Island;
-import com.songoda.skyblock.island.IslandManager;
-import com.songoda.skyblock.island.IslandRole;
-import com.songoda.skyblock.menus.admin.Settings;
-import com.songoda.skyblock.message.MessageManager;
-import com.songoda.skyblock.permission.PermissionManager;
 import com.songoda.skyblock.sound.SoundManager;
 import org.bukkit.command.ConsoleCommandSender;
-import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Player;
 
-import java.io.File;
-
 public class SettingsCommand extends SubCommand {
 
     @Override
diff --git a/src/main/java/com/songoda/skyblock/menus/admin/Settings.java b/src/main/java/com/songoda/skyblock/menus/admin/Settings.java
deleted file mode 100644
index 4704431b..00000000
--- a/src/main/java/com/songoda/skyblock/menus/admin/Settings.java
+++ /dev/null
@@ -1,686 +0,0 @@
-package com.songoda.skyblock.menus.admin;
-
-import com.songoda.core.compatibility.CompatibleMaterial;
-import com.songoda.core.compatibility.CompatibleSound;
-import com.songoda.skyblock.SkyBlock;
-import com.songoda.skyblock.config.FileManager;
-import com.songoda.skyblock.config.FileManager.Config;
-import com.songoda.skyblock.island.IslandRole;
-import com.songoda.skyblock.message.MessageManager;
-import com.songoda.skyblock.sound.SoundManager;
-import com.songoda.skyblock.utils.item.nInventoryUtil;
-
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.Material;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemFlag;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Settings {
-
-    private static Settings instance;
-
-    public static Settings getInstance() {
-        if (instance == null) {
-            instance = new Settings();
-        }
-
-        return instance;
-    }
-
-    public void open(Player player, Settings.Type menuType, IslandRole role) {
-        SkyBlock skyblock = SkyBlock.getInstance();
-
-        MessageManager messageManager = skyblock.getMessageManager();
-        SoundManager soundManager = skyblock.getSoundManager();
-        FileManager fileManager = skyblock.getFileManager();
-
-        Config mainConfig = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml"));
-        Config languageConfig = fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml"));
-        FileConfiguration configLoad = languageConfig.getFileConfiguration();
-
-        if (menuType == Settings.Type.Categories) {
-            nInventoryUtil nInv = new nInventoryUtil(player, event -> {
-                if (!(player.hasPermission("fabledskyblock.admin.settings") || player.hasPermission("fabledskyblock.admin.*")
-                        || player.hasPermission("fabledskyblock.*"))) {
-                    messageManager.sendMessage(player,
-                            configLoad.getString("Island.Admin.Settings.Permission.Message"));
-                    soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);
-
-                    return;
-                }
-
-                ItemStack is = event.getItem();
-
-                if ((is.getType() == CompatibleMaterial.OAK_FENCE_GATE.getMaterial()) && (is.hasItemMeta())
-                        && (is.getItemMeta().getDisplayName().equals(ChatColor.translateAlternateColorCodes('&',
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Exit.Displayname"))))) {
-                    soundManager.playSound(player, CompatibleSound.BLOCK_CHEST_CLOSE.getSound(), 1.0F, 1.0F);
-                } else if ((is.hasItemMeta()) && (is.getItemMeta().getDisplayName()
-                        .equals(ChatColor.translateAlternateColorCodes('&', configLoad
-                                .getString("Menu.Admin.Settings.Categories.Item.Visitor.Displayname"))))) {
-                    soundManager.playSound(player, CompatibleSound.BLOCK_NOTE_BLOCK_PLING.getSound(), 1.0F, 1.0F);
-
-                    Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> open(player, Type.Role, IslandRole.Visitor), 1L);
-                } else if ((is.getType() == Material.PAINTING) && (is.hasItemMeta())
-                        && (is.getItemMeta().getDisplayName().equals(ChatColor.translateAlternateColorCodes('&',
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Member.Displayname"))))) {
-                    soundManager.playSound(player, CompatibleSound.BLOCK_NOTE_BLOCK_PLING.getSound(), 1.0F, 1.0F);
-
-                    Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> open(player, Type.Role, IslandRole.Member), 1L);
-                } else if ((is.getType() == Material.ITEM_FRAME) && (is.hasItemMeta())
-                        && (is.getItemMeta().getDisplayName()
-                        .equals(ChatColor.translateAlternateColorCodes('&', configLoad
-                                .getString("Menu.Admin.Settings.Categories.Item.Operator.Displayname"))))) {
-                    soundManager.playSound(player, CompatibleSound.BLOCK_NOTE_BLOCK_PLING.getSound(), 1.0F, 1.0F);
-
-                    Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> open(player, Type.Role, IslandRole.Operator), 1L);
-                } else if ((is.getType() == Material.NAME_TAG) && (is.hasItemMeta())
-                        && (is.getItemMeta().getDisplayName().equals(ChatColor.translateAlternateColorCodes('&',
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Coop.Displayname"))))) {
-                    soundManager.playSound(player, CompatibleSound.BLOCK_NOTE_BLOCK_PLING.getSound(), 1.0F, 1.0F);
-
-                    Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> open(player, Type.Role, IslandRole.Coop), 1L);
-                } else if ((is.getType() == CompatibleMaterial.OAK_SAPLING.getMaterial()) && (is.hasItemMeta())
-                        && (is.getItemMeta().getDisplayName().equals(ChatColor.translateAlternateColorCodes('&',
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Owner.Displayname"))))) {
-                    soundManager.playSound(player, CompatibleSound.BLOCK_NOTE_BLOCK_PLING.getSound(), 1.0F, 1.0F);
-
-                    Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> open(player, Type.Role, IslandRole.Owner), 1L);
-                }
-            });
-
-            nInv.addItem(nInv.createItem(new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial()),
-                    configLoad.getString("Menu.Admin.Settings.Categories.Item.Visitor.Displayname"),
-                    configLoad.getStringList("Menu.Admin.Settings.Categories.Item.Visitor.Lore"), null, null, null), 2);
-            nInv.addItem(nInv.createItem(new ItemStack(Material.PAINTING),
-                    configLoad.getString("Menu.Admin.Settings.Categories.Item.Member.Displayname"),
-                    configLoad.getStringList("Menu.Admin.Settings.Categories.Item.Member.Lore"), null, null, null), 3);
-            nInv.addItem(nInv.createItem(new ItemStack(Material.ITEM_FRAME),
-                    configLoad.getString("Menu.Admin.Settings.Categories.Item.Operator.Displayname"),
-                    configLoad.getStringList("Menu.Admin.Settings.Categories.Item.Operator.Lore"), null, null, null),
-                    4);
-
-            if (fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration()
-                    .getBoolean("Island.Coop.Enable")) {
-                nInv.addItem(nInv.createItem(CompatibleMaterial.OAK_FENCE_GATE.getItem(),
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Exit.Displayname"), null, null, null,
-                        null), 0);
-                nInv.addItem(nInv.createItem(new ItemStack(Material.NAME_TAG),
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Coop.Displayname"),
-                        configLoad.getStringList("Menu.Admin.Settings.Categories.Item.Coop.Lore"), null, null, null),
-                        6);
-                nInv.addItem(nInv.createItem(CompatibleMaterial.OAK_SAPLING.getItem(),
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Owner.Displayname"),
-                        configLoad.getStringList("Menu.Admin.Settings.Categories.Item.Owner.Lore"), null, null, null),
-                        7);
-            } else {
-                nInv.addItem(nInv.createItem(CompatibleMaterial.OAK_FENCE_GATE.getItem(),
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Exit.Displayname"), null, null, null,
-                        null), 0, 8);
-                nInv.addItem(nInv.createItem(CompatibleMaterial.OAK_SAPLING.getItem(),
-                        configLoad.getString("Menu.Admin.Settings.Categories.Item.Owner.Displayname"),
-                        configLoad.getStringList("Menu.Admin.Settings.Categories.Item.Owner.Lore"), null, null, null),
-                        6);
-            }
-
-            nInv.setTitle(ChatColor.translateAlternateColorCodes('&',
-                    configLoad.getString("Menu.Admin.Settings.Categories.Title")));
-            nInv.setRows(1);
-
-            Bukkit.getServer().getScheduler().runTask(skyblock, () -> nInv.open());
-        } else if (menuType == Settings.Type.Role) {
-            nInventoryUtil nInv = new nInventoryUtil(player, event -> {
-                if (!(player.hasPermission("fabledskyblock.admin.settings") || player.hasPermission("fabledskyblock.admin.*")
-                        || player.hasPermission("fabledskyblock.*"))) {
-                    messageManager.sendMessage(player,
-                            configLoad.getString("Island.Admin.Settings.Permission.Message"));
-                    soundManager.playSound(player, CompatibleSound.BLOCK_ANVIL_LAND.getSound(), 1.0F, 1.0F);
-
-                    return;
-                }
-
-                ItemStack is = event.getItem();
-
-                if ((is.getType() == CompatibleMaterial.OAK_FENCE_GATE.getMaterial()) && (is.hasItemMeta()) && (is
-                        .getItemMeta().getDisplayName()
-                        .equals(ChatColor.translateAlternateColorCodes('&',
-                                configLoad.getString("Menu.Admin.Settings.Visitor.Item.Return.Displayname")))
-                        || is.getItemMeta().getDisplayName()
-                        .equals(ChatColor.translateAlternateColorCodes('&',
-                                configLoad.getString("Menu.Admin.Settings.Member.Item.Return.Displayname")))
-                        || is.getItemMeta().getDisplayName()
-                        .equals(ChatColor.translateAlternateColorCodes('&',
-                                configLoad
-                                        .getString("Menu.Admin.Settings.Operator.Item.Return.Displayname")))
-                        || is.getItemMeta().getDisplayName().equals(ChatColor.translateAlternateColorCodes('&',
-                        configLoad.getString("Menu.Admin.Settings.Owner.Item.Return.Displayname"))))) {
-                    soundManager.playSound(player, CompatibleSound.ENTITY_ARROW_HIT.getSound(), 1.0F, 1.0F);
-
-                    Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> open(player, Type.Categories, null), 1L);
-                } else if (is.hasItemMeta()) {
-                    String roleName = getRoleName(role);
-
-                    FileConfiguration settingsConfigLoad = skyblock.getFileManager()
-                            .getConfig(new File(skyblock.getDataFolder(), "settings.yml")).getFileConfiguration();
-
-                    for (String settingList : settingsConfigLoad.getConfigurationSection("Settings." + role.name())
-                            .getKeys(false)) {
-                        if (is.getItemMeta().getDisplayName()
-                                .equals(ChatColor.translateAlternateColorCodes('&',
-                                        configLoad.getString("Menu.Admin.Settings." + roleName + ".Item.Setting."
-                                                + settingList + ".Displayname")))) {
-                            if (settingsConfigLoad.getBoolean("Settings." + role.name() + "." + settingList)) {
-                                settingsConfigLoad.set("Settings." + role.name() + "." + settingList, false);
-                            } else {
-                                settingsConfigLoad.set("Settings." + role.name() + "." + settingList, true);
-                            }
-
-                            Bukkit.getServer().getScheduler().runTaskAsynchronously(skyblock, () -> {
-                                try {
-                                    Config config = skyblock.getFileManager()
-                                            .getConfig(new File(skyblock.getDataFolder(), "settings.yml"));
-                                    config.getFileConfiguration().save(config.getFile());
-                                } catch (IOException e) {
-                                    e.printStackTrace();
-                                }
-                            });
-
-                            break;
-                        }
-                    }
-
-                    soundManager.playSound(player, CompatibleSound.BLOCK_WOODEN_BUTTON_CLICK_ON.getSound(), 1.0F, 1.0F);
-
-                    Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> open(player, Type.Role, role), 1L);
-                }
-            });
-
-            if (role == IslandRole.Visitor
-                    || role == IslandRole.Member
-                    || role == IslandRole.Coop) {
-                nInv.addItemStack(createItem(role, "Destroy", new ItemStack(Material.DIAMOND_PICKAXE)), 9);
-                nInv.addItemStack(createItem(role, "Place", new ItemStack(Material.GRASS)), 10);
-                nInv.addItemStack(createItem(role, "Anvil", new ItemStack(Material.ANVIL)), 11);
-                nInv.addItemStack(createItem(role, "ArmorStandUse", new ItemStack(Material.ARMOR_STAND)), 12);
-                nInv.addItemStack(createItem(role, "Beacon", new ItemStack(Material.BEACON)), 13);
-                nInv.addItemStack(createItem(role, "Bed", CompatibleMaterial.WHITE_BED.getItem()), 14);
-                nInv.addItemStack(createItem(role, "AnimalBreeding", new ItemStack(Material.WHEAT)), 15);
-                nInv.addItemStack(
-                        createItem(role, "Brewing", new ItemStack(CompatibleMaterial.BREWING_STAND.getMaterial())),
-                        16);
-                nInv.addItemStack(createItem(role, "Bucket", new ItemStack(Material.BUCKET)), 17);
-                nInv.addItemStack(createItem(role, "WaterCollection", new ItemStack(Material.POTION)), 18);
-                nInv.addItemStack(createItem(role, "Storage", new ItemStack(Material.CHEST)), 19);
-                nInv.addItemStack(createItem(role, "Workbench", CompatibleMaterial.CRAFTING_TABLE.getItem()), 20);
-                nInv.addItemStack(createItem(role, "Crop", CompatibleMaterial.WHEAT_SEEDS.getItem()), 21);
-                nInv.addItemStack(createItem(role, "Door", CompatibleMaterial.OAK_DOOR.getItem()), 22);
-                nInv.addItemStack(createItem(role, "Gate", CompatibleMaterial.OAK_FENCE_GATE.getItem()), 23);
-                nInv.addItemStack(createItem(role, "Projectile", new ItemStack(Material.ARROW)), 24);
-                nInv.addItemStack(createItem(role, "Enchant", CompatibleMaterial.ENCHANTING_TABLE.getItem()), 25);
-                nInv.addItemStack(createItem(role, "Fire", new ItemStack(Material.FLINT_AND_STEEL)), 26);
-                nInv.addItemStack(createItem(role, "Furnace", new ItemStack(Material.FURNACE)), 27);
-                nInv.addItemStack(createItem(role, "HorseInventory", CompatibleMaterial.CHEST_MINECART.getItem()), 28);
-                nInv.addItemStack(createItem(role, "MobRiding", new ItemStack(Material.SADDLE)), 29);
-                nInv.addItemStack(createItem(role, "MonsterHurting", CompatibleMaterial.BONE.getItem()), 30);
-                nInv.addItemStack(createItem(role, "MobHurting", CompatibleMaterial.WOODEN_SWORD.getItem()), 31);
-                nInv.addItemStack(createItem(role, "MobTaming", CompatibleMaterial.POPPY.getItem()), 32);
-                nInv.addItemStack(createItem(role, "Leash", CompatibleMaterial.LEAD.getItem()), 33);
-                nInv.addItemStack(createItem(role, "LeverButton", new ItemStack(Material.LEVER)), 34);
-                nInv.addItemStack(createItem(role, "Milking", new ItemStack(Material.MILK_BUCKET)), 35);
-                nInv.addItemStack(createItem(role, "Jukebox", new ItemStack(Material.JUKEBOX)), 36);
-                nInv.addItemStack(createItem(role, "PressurePlate", CompatibleMaterial.OAK_PRESSURE_PLATE.getItem()), 37);
-                nInv.addItemStack(createItem(role, "Redstone", new ItemStack(Material.REDSTONE)), 38);
-                nInv.addItemStack(createItem(role, "Shearing", new ItemStack(Material.SHEARS)), 39);
-                nInv.addItemStack(createItem(role, "Trading", new ItemStack(Material.EMERALD)), 40);
-                nInv.addItemStack(createItem(role, "ItemDrop", new ItemStack(Material.PUMPKIN_SEEDS)), 41);
-                nInv.addItemStack(createItem(role, "ItemPickup", new ItemStack(Material.MELON_SEEDS)), 42);
-                nInv.addItemStack(createItem(role, "Fishing", new ItemStack(Material.FISHING_ROD)), 43);
-                nInv.addItemStack(createItem(role, "DropperDispenser", new ItemStack(Material.DISPENSER)), 44);
-                nInv.addItemStack(createItem(role, "SpawnEgg", new ItemStack(Material.EGG)), 45);
-                nInv.addItemStack(createItem(role, "HangingDestroy", new ItemStack(Material.ITEM_FRAME)), 46);
-                nInv.addItemStack(createItem(role, "Cake", new ItemStack(Material.CAKE)), 47);
-                nInv.addItemStack(createItem(role, "DragonEggUse", new ItemStack(Material.DRAGON_EGG)), 48);
-                nInv.addItemStack(createItem(role, "MinecartBoat", new ItemStack(Material.MINECART)), 49);
-                nInv.addItemStack(createItem(role, "Portal", new ItemStack(Material.ENDER_PEARL)), 50);
-                nInv.addItemStack(createItem(role, "Hopper", new ItemStack(Material.HOPPER)), 51);
-                nInv.addItemStack(createItem(role, "EntityPlacement", new ItemStack(Material.ARMOR_STAND)), 52);
-                nInv.addItemStack(createItem(role, "ExperienceOrbPickup", CompatibleMaterial.EXPERIENCE_BOTTLE.getItem()), 53);
-
-                nInv.setRows(6);
-            } else if (role == IslandRole.Operator) {
-                if (mainConfig.getFileConfiguration().getBoolean("Island.Visitor.Banning")) {
-                    if (mainConfig.getFileConfiguration().getBoolean("Island.Coop.Enable")) {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.WorldBorder.Enable")) {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 9);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 10);
-                            nInv.addItemStack(createItem(role, "Ban", new ItemStack(Material.IRON_AXE)), 11);
-                            nInv.addItemStack(createItem(role, "Unban", CompatibleMaterial.RED_DYE.getItem()), 12);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 13);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 14);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 15);
-                            nInv.addItemStack(createItem(role, "Coop", new ItemStack(Material.NAME_TAG)), 16);
-                            nInv.addItemStack(createItem(role, "CoopPlayers", new ItemStack(Material.BOOK)), 17);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 20);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    21);
-                            nInv.addItemStack(createItem(role, "Border", new ItemStack(Material.BEACON)), 22);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 23);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 24);
-                        } else {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 9);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 10);
-                            nInv.addItemStack(createItem(role, "Ban", new ItemStack(Material.IRON_AXE)), 11);
-                            nInv.addItemStack(createItem(role, "Unban", CompatibleMaterial.RED_DYE.getItem()), 12);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 13);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 14);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 15);
-                            nInv.addItemStack(createItem(role, "Coop", new ItemStack(Material.NAME_TAG)), 16);
-                            nInv.addItemStack(createItem(role, "CoopPlayers", new ItemStack(Material.BOOK)), 17);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 20);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    21);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 23);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 24);
-                        }
-                    } else {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.WorldBorder.Enable")) {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 10);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 11);
-                            nInv.addItemStack(createItem(role, "Ban", new ItemStack(Material.IRON_AXE)), 12);
-                            nInv.addItemStack(createItem(role, "Unban", CompatibleMaterial.RED_DYE.getItem()), 13);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 14);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 15);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 16);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 20);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    21);
-                            nInv.addItemStack(createItem(role, "Border", new ItemStack(Material.BEACON)), 22);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 23);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 24);
-                        } else {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 10);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 11);
-                            nInv.addItemStack(createItem(role, "Ban", new ItemStack(Material.IRON_AXE)), 12);
-                            nInv.addItemStack(createItem(role, "Unban", CompatibleMaterial.RED_DYE.getItem()), 13);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 14);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 15);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 16);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 20);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    21);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 23);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 24);
-                        }
-                    }
-
-                    nInv.setRows(3);
-                } else {
-                    if (mainConfig.getFileConfiguration().getBoolean("Island.Coop.Enable")) {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.WorldBorder.Enable")) {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 10);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 11);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 12);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 13);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 14);
-                            nInv.addItemStack(createItem(role, "Coop", new ItemStack(Material.NAME_TAG)), 15);
-                            nInv.addItemStack(createItem(role, "CoopPlayers", new ItemStack(Material.BOOK)), 16);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 20);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    21);
-                            nInv.addItemStack(createItem(role, "Border", new ItemStack(Material.BEACON)), 22);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 23);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 24);
-                        } else {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 10);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 11);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 12);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 13);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 14);
-                            nInv.addItemStack(createItem(role, "Coop", new ItemStack(Material.NAME_TAG)), 15);
-                            nInv.addItemStack(createItem(role, "CoopPlayers", new ItemStack(Material.BOOK)), 16);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 20);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    21);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 23);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 24);
-                        }
-
-                        nInv.setRows(3);
-                    } else {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.WorldBorder.Enable")) {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 10);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 11);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 12);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 13);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 14);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 15);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    16);
-                            nInv.addItemStack(createItem(role, "Border", new ItemStack(Material.BEACON)), 21);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 22);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 23);
-
-                            nInv.setRows(3);
-                        } else {
-                            nInv.addItemStack(createItem(role, "Invite", CompatibleMaterial.WRITABLE_BOOK.getItem()), 9);
-                            nInv.addItemStack(createItem(role, "Kick", new ItemStack(Material.IRON_DOOR)), 10);
-                            nInv.addItemStack(createItem(role, "Visitor", new ItemStack(CompatibleMaterial.OAK_SIGN.getMaterial())), 11);
-                            nInv.addItemStack(createItem(role, "Member", new ItemStack(Material.PAINTING)), 12);
-                            nInv.addItemStack(createItem(role, "Island", CompatibleMaterial.OAK_SAPLING.getItem()), 13);
-                            nInv.addItemStack(createItem(role, "MainSpawn", new ItemStack(Material.EMERALD)), 14);
-                            nInv.addItemStack(createItem(role, "VisitorSpawn", new ItemStack(Material.NETHER_STAR)),
-                                    15);
-                            nInv.addItemStack(createItem(role, "Biome", new ItemStack(Material.MAP)), 16);
-                            nInv.addItemStack(createItem(role, "Weather", CompatibleMaterial.CLOCK.getItem()), 17);
-
-                            nInv.setRows(2);
-                        }
-                    }
-                }
-            } else if (role == IslandRole.Owner) {
-                if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.PvP.Enable")) {
-                    if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.KeepItemsOnDeath.Enable")) {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Damage.Enable")) {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()), 9);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 13);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 14);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 15);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 16);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 17);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()), 9);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 16);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 17);
-                            }
-                        } else {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()), 9);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 16);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 17);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 12);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 13);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 16);
-                            }
-                        }
-                    } else {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Damage.Enable")) {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()), 9);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 16);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 17);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 12);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 13);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 16);
-                            }
-                        } else {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 12);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 13);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 16);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "PvP", new ItemStack(Material.DIAMOND_SWORD)), 12);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 14);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 15);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 16);
-                            }
-                        }
-                    }
-                } else {
-                    if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.KeepItemsOnDeath.Enable")) {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Damage.Enable")) {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()), 9);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 11);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 12);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 14);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 15);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 16);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 17);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 13);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 14);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 15);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 16);
-                            }
-                        } else {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 13);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 14);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 15);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 16);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(
-                                        createItem(role, "KeepItemsOnDeath", new ItemStack(Material.ITEM_FRAME)), 16);
-                            }
-                        }
-                    } else {
-                        if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Damage.Enable")) {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 13);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 14);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 15);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 16);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(createItem(role, "Damage", CompatibleMaterial.RED_DYE.getItem()), 16);
-                            }
-                        } else {
-                            if (mainConfig.getFileConfiguration().getBoolean("Island.Settings.Hunger.Enable")) {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        10);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 12);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                                nInv.addItemStack(createItem(role, "Hunger", new ItemStack(Material.COOKED_BEEF)), 16);
-                            } else {
-                                nInv.addItemStack(
-                                        createItem(role, "NaturalMobSpawning", CompatibleMaterial.PIG_SPAWN_EGG.getItem()),
-                                        11);
-                                nInv.addItemStack(createItem(role, "MobGriefing", CompatibleMaterial.IRON_SHOVEL.getItem()),
-                                        12);
-                                nInv.addItemStack(createItem(role, "Explosions", CompatibleMaterial.GUNPOWDER.getItem()), 13);
-                                nInv.addItemStack(
-                                        createItem(role, "FireSpread", new ItemStack(Material.FLINT_AND_STEEL)), 14);
-                                nInv.addItemStack(createItem(role, "LeafDecay", CompatibleMaterial.OAK_LEAVES.getItem()), 15);
-                            }
-                        }
-                    }
-                }
-
-                nInv.setRows(2);
-            }
-
-            nInv.addItem(nInv.createItem(CompatibleMaterial.OAK_FENCE_GATE.getItem(),
-                    configLoad.getString("Menu.Admin.Settings." + role.name() + ".Item.Return.Displayname"), null, null,
-                    null, null), 0, 8);
-            nInv.setTitle(ChatColor.translateAlternateColorCodes('&',
-                    configLoad.getString("Menu.Admin.Settings." + role.name() + ".Title")));
-
-            Bukkit.getServer().getScheduler().runTask(skyblock, () -> nInv.open());
-        }
-    }
-
-    private ItemStack createItem(IslandRole role, String setting, ItemStack is) {
-        SkyBlock skyblock = SkyBlock.getInstance();
-
-        FileManager fileManager = skyblock.getFileManager();
-
-        Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml"));
-        FileConfiguration configLoad = config.getFileConfiguration();
-
-        List<String> itemLore = new ArrayList<>();
-
-        ItemMeta im = is.getItemMeta();
-
-        String roleName = role.name();
-
-        if (role == IslandRole.Visitor
-                || role == IslandRole.Member
-                || role == IslandRole.Coop) {
-            roleName = "Default";
-        }
-
-        im.setDisplayName(ChatColor.translateAlternateColorCodes('&',
-                configLoad.getString("Menu.Admin.Settings." + roleName + ".Item.Setting." + setting + ".Displayname")));
-
-        if (fileManager.getConfig(new File(skyblock.getDataFolder(), "settings.yml")).getFileConfiguration()
-                .getBoolean("Settings." + role.name() + "." + setting)) {
-            for (String itemLoreList : configLoad
-                    .getStringList("Menu.Admin.Settings." + roleName + ".Item.Setting.Status.Enabled.Lore")) {
-                itemLore.add(ChatColor.translateAlternateColorCodes('&', itemLoreList));
-            }
-        } else {
-            for (String itemLoreList : configLoad
-                    .getStringList("Menu.Admin.Settings." + roleName + ".Item.Setting.Status.Disabled.Lore")) {
-                itemLore.add(ChatColor.translateAlternateColorCodes('&', itemLoreList));
-            }
-        }
-
-        im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
-        im.setLore(itemLore);
-        is.setItemMeta(im);
-
-        return is;
-    }
-
-    private String getRoleName(IslandRole role) {
-        if (role == IslandRole.Visitor
-                || role == IslandRole.Member
-                || role == IslandRole.Coop) {
-            return "Default";
-        }
-
-        return role.name();
-    }
-
-    public enum Type {
-
-        Categories, Panel, Role
-
-    }
-}

From 6b6386864f36072b6b3d4309bab1e37961c65b07 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 23:31:29 +0200
Subject: [PATCH 45/55] Let settings auto generate with respect for other
 plugins

---
 .../songoda/skyblock/config/FileManager.java  |  2 +-
 .../permission/PermissionManager.java         | 37 +++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/config/FileManager.java b/src/main/java/com/songoda/skyblock/config/FileManager.java
index f83418a6..07432f50 100644
--- a/src/main/java/com/songoda/skyblock/config/FileManager.java
+++ b/src/main/java/com/songoda/skyblock/config/FileManager.java
@@ -98,7 +98,7 @@ public class FileManager {
             }
 
             if (configFile.exists()) {
-                if (fileName.equals("config.yml") || fileName.equals("language.yml") || fileName.equals("settings.yml") || fileName.equals("worlds.yml")) {
+                if (fileName.equals("config.yml") || fileName.equals("language.yml") || fileName.equals("worlds.yml")) {
                     FileChecker fileChecker;
 
                     if (fileName.equals("config.yml")) {
diff --git a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
index 64dcca9c..9bb7d17d 100644
--- a/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
+++ b/src/main/java/com/songoda/skyblock/permission/PermissionManager.java
@@ -15,6 +15,7 @@ import org.bukkit.event.Cancellable;
 import org.bukkit.event.player.PlayerMoveEvent;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.*;
@@ -114,7 +115,43 @@ public class PermissionManager {
         })).collect(Collectors.toList());
     }
 
+    private void updateSettingsConfig(BasicPermission permission){
+        FileManager.Config settingsConfig = plugin.getFileManager().getConfig(new File(plugin.getDataFolder(), "settings.yml"));
+        FileConfiguration settingsConfigLoad = settingsConfig.getFileConfiguration();
+
+        switch (permission.getType()){
+            case GENERIC:
+                if(settingsConfigLoad.getString("Settings.Visitor." + permission.getName()) == null){
+                    settingsConfigLoad.set("Settings.Visitor." + permission.getName(), true);
+                }
+                if(settingsConfigLoad.getString("Settings.Member." + permission.getName()) == null){
+                    settingsConfigLoad.set("Settings.Member." + permission.getName(), true);
+                }
+                if(settingsConfigLoad.getString("Settings.Coop." + permission.getName()) == null){
+                    settingsConfigLoad.set("Settings.Coop." + permission.getName(), true);
+                }
+                break;
+            case OPERATOR:
+                if(settingsConfigLoad.getString("Settings.Operator." + permission.getName()) == null){
+                    settingsConfigLoad.set("Settings.Operator." + permission.getName(), true);
+                }
+                break;
+            case ISLAND:
+                if(settingsConfigLoad.getString("Settings.Owner." + permission.getName()) == null){
+                    settingsConfigLoad.set("Settings.Owner." + permission.getName(), true);
+                }
+                break;
+        }
+        try {
+            settingsConfigLoad.save(settingsConfig.getFile());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
     public boolean registerPermission(BasicPermission permission) {
+        updateSettingsConfig(permission);
+
         registeredPermissions.put(permission.getName().toUpperCase(), permission);
         Set<Method> methods;
         try {

From c3fc22917788b0ce97529e0b83081f7c52e2e084 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Fri, 19 Jun 2020 23:32:02 +0200
Subject: [PATCH 46/55] Removed Hunger from island default settings

---
 src/main/resources/settings.yml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml
index 63f8fe53..cbaed5f7 100644
--- a/src/main/resources/settings.yml
+++ b/src/main/resources/settings.yml
@@ -167,5 +167,4 @@ Settings:
         Explosions: false
         FireSpread: true
         LeafDecay: true
-        KeepItemsOnDeath: true
-        Hunger: true
\ No newline at end of file
+        KeepItemsOnDeath: true
\ No newline at end of file

From d40ac674b7e81297510ccdaf1984c554a6ad2ab7 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 00:38:20 +0200
Subject: [PATCH 47/55] Simplify and fix problem from formatted placeholder in
 Scoreboard

---
 .../songoda/skyblock/scoreboard/Scoreboard.java | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/scoreboard/Scoreboard.java b/src/main/java/com/songoda/skyblock/scoreboard/Scoreboard.java
index f233a755..8b5af07a 100644
--- a/src/main/java/com/songoda/skyblock/scoreboard/Scoreboard.java
+++ b/src/main/java/com/songoda/skyblock/scoreboard/Scoreboard.java
@@ -1,10 +1,6 @@
 package com.songoda.skyblock.scoreboard;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
 
 import org.bukkit.Bukkit;
 import org.bukkit.ChatColor;
@@ -118,9 +114,9 @@ public class Scoreboard {
 
                                         if (displayLine.length() >= 16) {
                                             String prefixLine = displayLine.substring(0, Math.min(displayLine.length(), 16));
-                                            String suffixLine = displayLine.substring(16, Math.min(displayLine.length(), displayLine.length()));
+                                            String suffixLine = displayLine.substring(16);
 
-                                            if (prefixLine.substring(prefixLine.length() - 1).equals("&")) {
+                                            if (prefixLine.endsWith("&")) {
                                                 prefixLine = ChatColor.translateAlternateColorCodes('&', prefixLine.substring(0, prefixLine.length() - 1));
                                                 suffixLine = ChatColor.translateAlternateColorCodes('&', "&" + suffixLine);
                                             } else {
@@ -175,7 +171,8 @@ public class Scoreboard {
 
         IslandManager islandManager = skyblock.getIslandManager();
 
-        displayLine = displayLine.replace("%players_online", "" + Bukkit.getServer().getOnlinePlayers().size()).replace("%players_max", "" + Bukkit.getServer().getMaxPlayers());
+        displayLine = displayLine.replace("%players_online", String.valueOf(Bukkit.getServer().getOnlinePlayers().size()));
+        displayLine = displayLine.replace("%players_max", String.valueOf(Bukkit.getServer().getMaxPlayers()));
 
         Island island = islandManager.getIsland(player);
 
@@ -212,9 +209,9 @@ public class Scoreboard {
         PlaceholderManager placeholderManager = skyblock.getPlaceholderManager();
 
         if (placeholderManager.isPlaceholderAPIEnabled()) {
-            displayLine = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, displayLine.replace("&", "clr")).replace("clr", "&");
+            displayLine = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, displayLine);
         }
 
-        return displayLine;
+        return displayLine.replace("ยง", "&"); // Returning unformatted line to avoid issues in next step
     }
 }

From b46473e9fddcc6f161b033c70269413d709f6d8c Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 00:48:27 +0200
Subject: [PATCH 48/55] Heavier checks for portals teleporting to real
 Nether/End

---
 .../com/songoda/skyblock/listeners/Teleport.java | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Teleport.java b/src/main/java/com/songoda/skyblock/listeners/Teleport.java
index 81c52552..5b39d75f 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Teleport.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Teleport.java
@@ -61,13 +61,23 @@ public class Teleport implements Listener {
         islandManager.loadPlayer(player);
 
 
-        // Fix for bug that tp you in the real Nether/End when entering in a portal in an island
+        // Fix for bug that tp you in the real Nether/End when entering in a portal in an island // TODO Simplify
         if (event.getTo() != null && (worldManager.isIslandWorld(event.getFrom().getWorld())
                 && !worldManager.isIslandWorld(event.getTo().getWorld())
                 && (event.getFrom().getBlock().getType().equals(CompatibleMaterial.END_PORTAL.getMaterial())
-                    || event.getFrom().getBlock().getType().equals(CompatibleMaterial.NETHER_PORTAL.getMaterial())) && (event.getTo().getWorld() != null
+                || event.getFrom().getBlock().getType().equals(CompatibleMaterial.NETHER_PORTAL.getMaterial()))
+                && (event.getTo().getWorld() != null
                 && event.getTo().getWorld().getEnvironment().equals(World.Environment.NETHER)
-                    || event.getTo().getWorld().getEnvironment().equals(World.Environment.THE_END)))) {
+                || event.getTo().getWorld().getEnvironment().equals(World.Environment.THE_END)))
+                || event.getTo() != null
+                && (worldManager.isIslandWorld(event.getFrom().getWorld())
+                && !worldManager.isIslandWorld(event.getTo().getWorld())
+                && (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL)
+                || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)
+                || event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL))
+                && (event.getTo().getWorld() != null
+                && event.getTo().getWorld().getEnvironment().equals(World.Environment.NETHER)
+                || event.getTo().getWorld().getEnvironment().equals(World.Environment.THE_END)))) {
             event.setCancelled(true);
         }
 

From d8e38a25500c5bb6d87acfc63ec61cd3c9babbf9 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 01:42:00 +0200
Subject: [PATCH 49/55] Protect visitors Spawn point

---
 src/main/java/com/songoda/skyblock/listeners/Block.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Block.java b/src/main/java/com/songoda/skyblock/listeners/Block.java
index cb737dd9..451846df 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Block.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Block.java
@@ -129,7 +129,8 @@ public class Block implements Listener {
         IslandWorld world = worldManager.getIslandWorld(block.getWorld());
 
         if (LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Main).clone().subtract(0.0D, 1.0D, 0.0D))
-                || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Main).clone())) {
+                || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Main).clone()) || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Visitor).clone().subtract(0.0D, 1.0D, 0.0D))
+                || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Visitor).clone())) {
             if (configLoad.getBoolean("Island.Spawn.Protection")) {
                 event.setCancelled(true);
                 skyblock.getMessageManager().sendMessage(player, skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "language.yml")).getFileConfiguration().getString("Island.SpawnProtection.Break.Message"));

From 92ea9f4404d104f0bc1a74ec1bf2c9e03fe8e6c3 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 01:42:10 +0200
Subject: [PATCH 50/55] Fix conversion error in challenges

---
 .../com/songoda/skyblock/challenge/challenge/Challenge.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java b/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java
index 28ff0685..6a3c26b7 100644
--- a/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java
+++ b/src/main/java/com/songoda/skyblock/challenge/challenge/Challenge.java
@@ -244,7 +244,7 @@ public class Challenge {
 				Island is = SkyBlock.getInstance().getIslandManager().getIsland(p);
 				// Player doesn't have an island
 				if (is != null && obj instanceof Number) {
-					return is.getLevel().getLevel() >= (Long) obj;
+					return is.getLevel().getLevel() >= ((Number) obj).longValue();
 				}
 				return false;
 			}

From fc8a95d1c1a0d6f9ae2a756f45366ff9bcdc2dde Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 03:39:25 +0200
Subject: [PATCH 51/55] Fixed ArmorStand and ItemFrame that can be destroyed

---
 .../songoda/skyblock/listeners/Entity.java    |  8 +++++
 .../listening/DestroyPermission.java          | 30 ++++++++++++-------
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Entity.java b/src/main/java/com/songoda/skyblock/listeners/Entity.java
index ad47df64..4083abf2 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Entity.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Entity.java
@@ -16,6 +16,7 @@ import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.*;
+import org.bukkit.entity.Projectile;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.EventPriority;
 import org.bukkit.event.Listener;
@@ -111,6 +112,13 @@ public class Entity implements Listener {
             skyblock.getPermissionManager()
                     .processPermission(event, player, islandManager.getIslandAtLocation(player.getLocation()), true);
 
+        } else if((event.getDamager() instanceof org.bukkit.entity.Projectile
+                    && ((Projectile) event.getDamager()).getShooter() instanceof Player)
+                && (event.getEntity().getType().equals(EntityType.ARMOR_STAND)
+                    || event.getEntity().getType().equals(EntityType.ITEM_FRAME))){
+            Player player = (Player) ((Projectile) event.getDamager()).getShooter();
+            skyblock.getPermissionManager()
+                    .processPermission(event, player, islandManager.getIslandAtLocation(player.getLocation()));
         } else { // Make it work with all the entities, not just TNT
             org.bukkit.entity.Entity entity = event.getEntity();
 
diff --git a/src/main/java/com/songoda/skyblock/permission/permissions/listening/DestroyPermission.java b/src/main/java/com/songoda/skyblock/permission/permissions/listening/DestroyPermission.java
index 9dd2f7f8..b6f1439e 100644
--- a/src/main/java/com/songoda/skyblock/permission/permissions/listening/DestroyPermission.java
+++ b/src/main/java/com/songoda/skyblock/permission/permissions/listening/DestroyPermission.java
@@ -6,9 +6,8 @@ import com.songoda.skyblock.message.MessageManager;
 import com.songoda.skyblock.permission.ListeningPermission;
 import com.songoda.skyblock.permission.PermissionHandler;
 import com.songoda.skyblock.permission.PermissionType;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.EntityType;
-import org.bukkit.entity.Player;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.*;
 import org.bukkit.event.block.Action;
 import org.bukkit.event.block.BlockBreakEvent;
 import org.bukkit.event.entity.EntityDamageByEntityEvent;
@@ -27,8 +26,6 @@ public class DestroyPermission extends ListeningPermission {
 
     @PermissionHandler
     public void onInteract(PlayerInteractEvent event) {
-
-
         if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.LEFT_CLICK_BLOCK)
             return;
 
@@ -42,13 +39,24 @@ public class DestroyPermission extends ListeningPermission {
 
     @PermissionHandler
     public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
-        if (!(event.getDamager() instanceof Player)) return;
-        Player player = (Player)event.getDamager();
-        Entity entity = event.getEntity();
+        Player player = null;
+        if (event.getDamager() instanceof Player) {
+            player = (Player) event.getDamager();
+        }
+        if(event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof Player){
+            player = (Player) ((Projectile) event.getDamager()).getShooter();
+        }
+        if(player != null){
+            Entity entity = event.getEntity();
 
-        if (entity.getType() != EntityType.ARMOR_STAND) return;
-
-        cancelAndMessage(event, player, plugin, messageManager);
+            switch (entity.getType()){
+                case ARMOR_STAND:
+                case PAINTING:
+                case ITEM_FRAME:
+                    cancelAndMessage(event, player, plugin, messageManager);
+                    break;
+            }
+        }
     }
 
     @PermissionHandler

From 0496fe629db0e4ffeda044580215390e5fad372f Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 03:39:55 +0200
Subject: [PATCH 52/55] Little optimization in island spawn checking

---
 src/main/java/com/songoda/skyblock/listeners/Block.java  | 5 ++---
 src/main/java/com/songoda/skyblock/listeners/Entity.java | 2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Block.java b/src/main/java/com/songoda/skyblock/listeners/Block.java
index 451846df..ce16ea0d 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Block.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Block.java
@@ -128,9 +128,8 @@ public class Block implements Listener {
 
         IslandWorld world = worldManager.getIslandWorld(block.getWorld());
 
-        if (LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Main).clone().subtract(0.0D, 1.0D, 0.0D))
-                || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Main).clone()) || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Visitor).clone().subtract(0.0D, 1.0D, 0.0D))
-                || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Visitor).clone())) {
+        if (LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Main).clone().subtract(0.0D, 1.0D, 0.0D))  || LocationUtil.isLocationLocation(block.getLocation(), island.getLocation(world, IslandEnvironment.Visitor).clone().subtract(0.0D, 1.0D, 0.0D))
+                || LocationUtil.isLocationAffectingIslandSpawn(block.getLocation(), island, world)) {
             if (configLoad.getBoolean("Island.Spawn.Protection")) {
                 event.setCancelled(true);
                 skyblock.getMessageManager().sendMessage(player, skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "language.yml")).getFileConfiguration().getString("Island.SpawnProtection.Break.Message"));
diff --git a/src/main/java/com/songoda/skyblock/listeners/Entity.java b/src/main/java/com/songoda/skyblock/listeners/Entity.java
index 4083abf2..342b2b87 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Entity.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Entity.java
@@ -304,7 +304,7 @@ public class Entity implements Listener {
         }
 
         if ((event.getEntityType() == EntityType.FALLING_BLOCK)
-                && LocationUtil.isLocationLocation(event.getBlock().getLocation(), island.getLocation(world, IslandEnvironment.Main).clone())
+                && LocationUtil.isLocationAffectingIslandSpawn(block.getLocation(), island, world)
                 && configLoad.getBoolean("Island.Spawn.Protection")) {
             FallingBlock fallingBlock = (FallingBlock) event.getEntity();
             if (fallingBlock.getDropItem()) {

From 8be6bdfe7e718a362050a676febd2dd1202dc038 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 03:40:18 +0200
Subject: [PATCH 53/55] New method take() for Stackable

---
 .../java/com/songoda/skyblock/stackable/Stackable.java     | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/main/java/com/songoda/skyblock/stackable/Stackable.java b/src/main/java/com/songoda/skyblock/stackable/Stackable.java
index 54db7f92..948b1665 100644
--- a/src/main/java/com/songoda/skyblock/stackable/Stackable.java
+++ b/src/main/java/com/songoda/skyblock/stackable/Stackable.java
@@ -110,6 +110,13 @@ public class Stackable {
         this.save();
     }
 
+    public void take(int n) {
+        this.size-=n;
+        this.updateDisplay();
+        SkyBlock.getInstance().getSoundManager().playSound(this.location, CompatibleSound.ENTITY_ARROW_HIT.getSound(), 1.0F, 1.0F);
+        this.save();
+    }
+
     public boolean isMaxSize(){
         return size > maxSize;
     }

From 9ae191c4c4d5833eac9cad5d6a559d5ec6d43534 Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 05:00:58 +0200
Subject: [PATCH 54/55] Protect Stackables from explosions

---
 .../songoda/skyblock/listeners/Entity.java    | 115 +++++++++++-------
 1 file changed, 74 insertions(+), 41 deletions(-)

diff --git a/src/main/java/com/songoda/skyblock/listeners/Entity.java b/src/main/java/com/songoda/skyblock/listeners/Entity.java
index 342b2b87..1a0a954d 100644
--- a/src/main/java/com/songoda/skyblock/listeners/Entity.java
+++ b/src/main/java/com/songoda/skyblock/listeners/Entity.java
@@ -6,6 +6,7 @@ import com.songoda.skyblock.config.FileManager;
 import com.songoda.skyblock.config.FileManager.Config;
 import com.songoda.skyblock.island.*;
 import com.songoda.skyblock.limit.impl.EntityLimitaton;
+import com.songoda.skyblock.stackable.Stackable;
 import com.songoda.skyblock.stackable.StackableManager;
 import com.songoda.skyblock.upgrade.Upgrade;
 import com.songoda.skyblock.utils.version.NMSUtil;
@@ -14,6 +15,7 @@ import com.songoda.skyblock.world.WorldManager;
 import org.bukkit.Bukkit;
 import org.bukkit.Location;
 import org.bukkit.Material;
+import org.bukkit.block.Block;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.*;
 import org.bukkit.entity.Projectile;
@@ -343,21 +345,8 @@ public class Entity implements Listener {
                 .getBoolean("Island.Block.Level.Enable"))
             return;
 
-        CompatibleMaterial materials = CompatibleMaterial.getBlockMaterial(block.getType());
-
-        if (materials != null) {
-            IslandLevel level = island.getLevel();
-
-            if (level.hasMaterial(materials.name())) {
-                long materialAmount = level.getMaterialAmount(materials.name());
-
-                if (materialAmount - 1 <= 0) {
-                    level.removeMaterial(materials.name());
-                } else {
-                    level.setMaterialAmount(materials.name(), materialAmount - 1);
-                }
-            }
-        }
+        removeBlockFromLevel(island, block);
+        CompatibleMaterial materials;
 
         if (event.getTo() != null && event.getTo() != Material.AIR) {
             materials = CompatibleMaterial.getBlockMaterial(event.getTo());
@@ -377,7 +366,7 @@ public class Entity implements Listener {
 
     }
 
-    @EventHandler
+    @EventHandler(priority = EventPriority.LOW)
     public void onEntityExplode(EntityExplodeEvent event) {
         org.bukkit.entity.Entity entity = event.getEntity();
 
@@ -387,47 +376,91 @@ public class Entity implements Listener {
         if (skyblock.getWorldManager().isIslandWorld(entity.getWorld())) {
             // Check permissions.
             Island island = islandManager.getIslandAtLocation(entity.getLocation());
-
             skyblock.getPermissionManager().processPermission(event, null, island);
 
             if (!event.isCancelled()) {
-                if (skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration()
-                        .getBoolean("Island.Block.Level.Enable")) {
-                    for (org.bukkit.block.Block blockList : event.blockList()) {
-                        @SuppressWarnings("deprecation")
-                        CompatibleMaterial materials = CompatibleMaterial.getBlockMaterial(blockList.getType());
 
-                        if (materials != null) {
-                            IslandLevel level = island.getLevel();
+                StackableManager stackableManager = skyblock.getStackableManager();
 
-                            if (level.hasMaterial(materials.name())) {
-                                long materialAmount = level.getMaterialAmount(materials.name());
+                boolean removed;
+                Iterator<org.bukkit.block.Block> it = event.blockList().iterator();
+                while (it.hasNext()){
+                    removed = false;
+                    org.bukkit.block.Block block = it.next();
+                    if (SkyBlock.getInstance().getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration()
+                            .getBoolean("Island.Spawn.Protection")) {
+                        IslandWorld world = worldManager.getIslandWorld(event.getEntity().getWorld());
+                        if (LocationUtil.isLocationLocation(block.getLocation(),
+                                island.getLocation(world, IslandEnvironment.Main).clone().subtract(0.0D, 1.0D, 0.0D))) {
+                            it.remove();
+                            removed = true;
+                        }
+                    }
 
-                                if (materialAmount - 1 <= 0) {
-                                    level.removeMaterial(materials.name());
-                                } else {
-                                    level.setMaterialAmount(materials.name(), materialAmount - 1);
-                                }
+                    Location blockLocation = block.getLocation();
+
+                    if (stackableManager != null && stackableManager.isStacked(blockLocation)) {
+                        Stackable stackable = stackableManager.getStack(block.getLocation(), CompatibleMaterial.getMaterial(block));
+                        if (stackable != null) {
+                            CompatibleMaterial material = CompatibleMaterial.getMaterial(block);
+                            byte data = block.getData();
+
+                            int removedAmount = (int) (Math.random() * Math.min(64, stackable.getSize()-1));
+                            stackable.take(removedAmount);
+                            Bukkit.getScheduler().runTask(skyblock, () -> {
+                                block.getWorld().dropItemNaturally(blockLocation.clone().add(.5, 1, .5),
+                                        new ItemStack(material.getMaterial(), (int) (Math.random() * removedAmount), data));
+                            });
+
+                            if (stackable.getSize() <= 1) {
+                                stackableManager.removeStack(stackable);
+                            }
+
+                            Config config = skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml"));
+                            FileConfiguration configLoad = config.getFileConfiguration();
+
+                            if (configLoad.getBoolean("Island.Block.Level.Enable")) {
+                                removeBlockFromLevel(island, block);
+                            }
+
+                            it.remove();
+                            if(!removed){
+                                removed = true;
                             }
                         }
                     }
-                }
-
-                if (SkyBlock.getInstance().getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration()
-                        .getBoolean("Island.Spawn.Protection")) {
-                    IslandWorld world = worldManager.getIslandWorld(event.getEntity().getWorld());
-                    for (org.bukkit.block.Block block : event.blockList()) {
-                        if (LocationUtil.isLocationLocation(block.getLocation(),
-                                island.getLocation(world, IslandEnvironment.Main).clone().subtract(0.0D, 1.0D, 0.0D))) {
-                            event.blockList().remove(block);
-                            break;
+                    if (skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration()
+                            .getBoolean("Island.Block.Level.Enable")) {
+                        if(!removed){
+                            removeBlockFromLevel(island, block);
                         }
+
                     }
                 }
             }
         }
     }
 
+    private void removeBlockFromLevel(Island island, CompatibleMaterial material){
+        if (material != null) {
+            IslandLevel level = island.getLevel();
+
+            if (level.hasMaterial(material.name())) {
+                long materialAmount = level.getMaterialAmount(material.name());
+
+                if (materialAmount - 1 <= 0) {
+                    level.removeMaterial(material.name());
+                } else {
+                    level.setMaterialAmount(material.name(), materialAmount - 1);
+                }
+            }
+        }
+    }
+
+    private void removeBlockFromLevel(Island island, Block block) {
+        removeBlockFromLevel(island, CompatibleMaterial.getBlockMaterial(block.getType()));
+    }
+
     @EventHandler(priority = EventPriority.MONITOR)
     public void onEntityDeath(EntityDeathEvent event) {
         LivingEntity livingEntity = event.getEntity();

From a6c1601836acf559de4025e73aaec32ff2b5c57f Mon Sep 17 00:00:00 2001
From: Fabrizio La Rosa <lr.fabrizio@gmail.com>
Date: Sat, 20 Jun 2020 05:01:20 +0200
Subject: [PATCH 55/55] 2.3.3-DEV

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 0839c7df..b90c4dd9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>com.songoda</groupId>
 	<artifactId>skyblock</artifactId>
-	<version>2.3.2</version>
+	<version>2.3.3-DEV</version>
 	<packaging>jar</packaging>
 	<build>
 		<defaultGoal>clean install</defaultGoal>