diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..e96e9a7 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2025-2026 Jakub Soukup, Erik Radovan and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, but NOT including the right to run, execute or use the +Software or any executable binaries built from the source code. + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE \ No newline at end of file diff --git a/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java b/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java index 4695378..a843fe1 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java @@ -1,3 +1,25 @@ +/* + ░░░░ + ░░░░ + ░░░░ + ░░░░ + ░░░░ ░░░░ + ░░░░ ░░░░ + ░░░░ + + ▓▓████▓▓▓▓████ + ██▓▓▓▓▓▓████▓▓▓▓▓▓ + ░░██▓▓░░██▓▓██▓▓▓▓██████ + ▒▒░░░░░░░░██░░░░░░▓▓▓▓░░░░░░░░▒▒ + ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░ + + ECOCRAFT CORE + (c) 2025-2026 Jakub Soukup, Erik Radovan and contributors + This software is licensed under Passive Aggressive License + + */ + + package xyz.soukup.ecoCraftCore; import com.github.retrooper.packetevents.event.EventManager; @@ -21,26 +43,22 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import xyz.soukup.ecoCraftCore.database.objects.*; import xyz.soukup.ecoCraftCore.islands.IslandAdminCommand; import xyz.soukup.ecoCraftCore.islands.IslandSelectorCommand; import xyz.soukup.ecoCraftCore.messages.JoinLeaveMessageSupress; import xyz.soukup.ecoCraftCore.mines.MineCommand; import xyz.soukup.ecoCraftCore.mines.MineWorldManager; import xyz.soukup.ecoCraftCore.money.MoneyCommand; +import xyz.soukup.ecoCraftCore.objects.*; import xyz.soukup.ecoCraftCore.player.OnKill; import xyz.soukup.ecoCraftCore.player.PreparePlayer; import xyz.soukup.ecoCraftCore.player.TeleportRequestsHandler; import xyz.soukup.ecoCraftCore.positionMarker.MarkerCommand; import xyz.soukup.ecoCraftCore.regions.RegionAdminCommand; +import xyz.soukup.ecoCraftCore.regions.RegionCommand; import xyz.soukup.ecoCraftCore.regions.RegionEvents; import xyz.soukup.ecoCraftCore.shop.ShopCommand; -import xyz.soukup.ecoCraftCore.database.objects.Account; -import xyz.soukup.ecoCraftCore.database.objects.Island; -import xyz.soukup.ecoCraftCore.database.objects.Shop; -import xyz.soukup.ecoCraftCore.database.objects.Transaction; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; -import xyz.soukup.ecoCraftCore.database.objects.VirtualChest; import xyz.soukup.ecoCraftCore.positionMarker.MarkerEvent; import xyz.soukup.ecoCraftCore.messages.Messages; import xyz.soukup.ecoCraftCore.shop.ShopLogic; @@ -237,6 +255,7 @@ public final class EcoCraftCore extends JavaPlugin { TableUtils.createTableIfNotExists(connectionSource, TeleportRequest.class); TableUtils.createTableIfNotExists(connectionSource, Region.class); TableUtils.createTableIfNotExists(connectionSource, RegionMember.class); + TableUtils.createTableIfNotExists(connectionSource, PermissionGroup.class); ActiveServer.setDao(DaoManager.createDao(connectionSource, ActiveServer.class)); Transaction.setDao(DaoManager.createDao(connectionSource, Transaction.class)); @@ -247,6 +266,7 @@ public final class EcoCraftCore extends JavaPlugin { TeleportRequest.setDao(DaoManager.createDao(connectionSource, TeleportRequest.class)); Region.setDao(DaoManager.createDao(connectionSource, Region.class)); RegionMember.setDao(DaoManager.createDao(connectionSource, RegionMember.class)); + PermissionGroup.setDao(DaoManager.createDao(connectionSource, PermissionGroup.class)); ActiveServer activeServer = new ActiveServer(config.getString("server.name")); @@ -289,6 +309,7 @@ public final class EcoCraftCore extends JavaPlugin { lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(MoneyCommand.getCommand().build())); lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(MineCommand.createCommand().build())); lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(SignEditCommand.getCommand().build())); + lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(RegionCommand.command().build())); } private void registerEvents(){ diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Permission.java b/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Permission.java deleted file mode 100644 index 8497498..0000000 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Permission.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.soukup.ecoCraftCore.database.objects; - -public enum Permission { - PLACE(1), - BREAK(2), - REDSTONE_INTERACT(3), - ENTITY_INTERACT(4), - VEHICLE_INTERACT(5), - ENTER(6), - EXIT(7), - MANAGE_MEMBERS(8), - MANAGE_GROUPS(9), - MANAGE_REGIONS(10), - TRANSFER_OWNERSHIP(11), - USE_HOPPER(12), - HARVEST(13), - PLANT(14), - PICKUP_ITEMS(15), - DROP_ITEMS(16), - PLOUGH(17), - SIT(18), - SHOP_INTERACT(19), - HARM_ENTITIES(20), - HARM_PLAYERS(21); - - private final int bit; - Permission(int bit) { - this.bit = bit; - } - - public int getBit() { - return bit; - } -} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Region.java b/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Region.java deleted file mode 100644 index c0168a5..0000000 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Region.java +++ /dev/null @@ -1,284 +0,0 @@ -package xyz.soukup.ecoCraftCore.database.objects; - -import com.j256.ormlite.dao.Dao; -import com.j256.ormlite.dao.ForeignCollection; -import com.j256.ormlite.field.DatabaseField; -import com.j256.ormlite.field.ForeignCollectionField; -import com.j256.ormlite.table.DatabaseTable; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import xyz.soukup.ecoCraftCore.messages.Messages; - -import java.sql.SQLException; -import java.util.HashMap; -import java.util.List; - -@DatabaseTable(tableName = "regions") -public class Region { - - public static Dao dao; - - public static void setDao(Dao dao) { - Region.dao = dao; - } - - public static Dao getDao() { - return dao; - } - - public static final HashMap> cache = new HashMap<>(); - - @DatabaseField(generatedId = true) - private int id; - - @DatabaseField(canBeNull = false) - private String island; - - @DatabaseField(columnName = "region_type", canBeNull = false) - private int regionType; - - @DatabaseField(canBeNull = false) - private int x1; - - @DatabaseField(canBeNull = false) - private int y1; - - @DatabaseField(canBeNull = false) - private int z1; - - @DatabaseField(canBeNull = false) - private int x2; - - @DatabaseField(canBeNull = false) - private int y2; - - @DatabaseField(canBeNull = false) - private int z2; - - @ForeignCollectionField(eager = true) - private ForeignCollection regionMembers; - - @DatabaseField() - private Integer value; - - public Region() { - - } - - public Region(String island, int regionType, int x1, int y1, int z1, int x2, int y2, int z2) { - this.island = island; - this.regionType = regionType; - this.x1 = Math.min(x1, x2); - this.y1 = Math.min(y1, y2); - this.x2 = Math.max(x1, x2); - this.y2 = Math.max(y1, y2); - this.z1 = Math.min(z1, z2); - this.z2 = Math.max(z1, z2); - - save(); - createDefaultGroupsAndReturnOwner(); - - } - - public PermissionGroup getPermissionGroup(String name){ - return PermissionGroup.getPermissionGroup(this, name); - } - - public Region(String island, int regionType, int x1, int y1, int z1, int x2, int y2, int z2, Player owner) { - this.island = island; - this.regionType = regionType; - this.x1 = Math.min(x1, x2); - this.y1 = Math.min(y1, y2); - this.x2 = Math.max(x1, x2); - this.y2 = Math.max(y1, y2); - this.z1 = Math.min(z1, z2); - this.z2 = Math.max(z1, z2); - - this.save(); - - PermissionGroup ownerGroup = this.createDefaultGroupsAndReturnOwner(); - addRegionMember("player", owner.getName(), ownerGroup); - - - } - - public int getId() { - return id; - } - - public int getRegionType() { - return regionType; - } - - public int getX1() { - return x1; - } - - public int getZ1() { - return z1; - } - - public int getZ2() { - return z2; - } - - public int getY1() { - return y1; - } - - public int getX2() { - return x2; - } - - public int getY2() { - return y2; - } - - public ForeignCollection getRegionMembers() { - return regionMembers; - } - - public Integer getValue() { - return value; - } - - public String getIsland() { - return island; - } - - - - - - public void setRegionType(int regionType) { - this.regionType = regionType; - } - - public void setValue(Integer value) { - this.value = value; - } - - public void save(){ - try { - - getDao().createOrUpdate(this); - List regions = cache.get(island); - - if (regions == null) { - return; - } - - regions.removeIf(region -> region.getId() == this.id); - regions.add(this); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void addRegionMember(String memberType, String member, PermissionGroup permissionGroup){ - RegionMember regionMember = new RegionMember(this, memberType, member, permissionGroup); - regionMember.save(); - - List regions = cache.get(island); - - if (regions == null) { - return; - } - - regions.removeIf(region -> region.getId() == this.id); - regions.add(this); - - } - - public void removeRegionMember(String memberType, String member){ - try { - RegionMember.getDao().queryBuilder().where().eq("region", this).query(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public boolean isInside(int x, int y, int z) { - return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2 && z >= this.z1 && z <= this.z2; - } - - public static Region findById(int id) { - try { - return getDao().queryForId(id); - } catch (Exception e) { - return null; - } - } - - public static void cacheRegions(String island) { - try { - List regions = getDao().queryBuilder() - .where() - .eq("island", island) - .query(); - cache.put(island, regions); - } catch (Exception e) { - - } - } - - public static Region findRegion(int x, int y, int z, String island) { - - Region region = null; - int highestType = -1; - - if (!cache.containsKey(island)) { - cacheRegions(island); - } - - for (Region cachedRegion : cache.get(island)) { - if (!cachedRegion.isInside(x, y, z)) { - continue; - } - if (highestType >= cachedRegion.getRegionType()){ - continue; - } - region = cachedRegion; - } - - return region; - - - } - - public void changeBoundaries(int x1, int y1, int z1, int x2, int y2, int z2){ - this.x1 = Math.min(x1, x2); - this.y1 = Math.min(y1, y2); - this.x2 = Math.max(x1, x2); - this.y2 = Math.max(y1, y2); - this.z1 = Math.min(z1, z2); - this.z2 = Math.max(z1, z2); - } - - public PermissionGroup createDefaultGroupsAndReturnOwner(){ - String ownerDisplayName = Messages.getAsString("region.permission-groups.owner.name"); - String ownerDescription = Messages.getAsString("region.permission-groups.owner.description"); - PermissionGroup owner = new PermissionGroup(this, "owner", ownerDisplayName, ownerDescription, Material.RED_CONCRETE, false, false, 101); - owner.save(); - - String adminDisplayName = Messages.getAsString("region.permission-groups.admin.name"); - String adminDescription = Messages.getAsString("region.permission-groups.admin.description"); - PermissionGroup admin = new PermissionGroup(this, "admin", adminDisplayName, adminDescription, Material.YELLOW_CONCRETE, true, true, 90); - admin.save(); - - String memberDisplayName = Messages.getAsString("region.permission-groups.member.name"); - String memberDescription = Messages.getAsString("region.permission-groups.member.description"); - PermissionGroup member = new PermissionGroup(this, "member", memberDisplayName, memberDescription, Material.GREEN_CONCRETE, true, true, 10); - member.save(); - - String defaultDisplayName = Messages.getAsString("region.permission-groups.default"); - String defaultDescription = Messages.getAsString("region.permission-groups.default.description"); - PermissionGroup defaultGroup = new PermissionGroup(this, "default", defaultDisplayName, defaultDescription, Material.GRAY_CONCRETE, true, true, 0); - defaultGroup.save(); - - return owner; - } - - -} - diff --git a/src/main/java/xyz/soukup/ecoCraftCore/islands/DatabaseIslandLoader.java b/src/main/java/xyz/soukup/ecoCraftCore/islands/DatabaseIslandLoader.java index 1276880..e3ce4ec 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/islands/DatabaseIslandLoader.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/islands/DatabaseIslandLoader.java @@ -2,7 +2,7 @@ package xyz.soukup.ecoCraftCore.islands; import com.infernalsuite.asp.api.exceptions.UnknownWorldException; import com.infernalsuite.asp.api.loaders.SlimeLoader; import com.j256.ormlite.stmt.DeleteBuilder; -import xyz.soukup.ecoCraftCore.database.objects.Island; +import xyz.soukup.ecoCraftCore.objects.Island; import java.io.IOException; import java.sql.SQLException; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandAdminCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandAdminCommand.java index b40b410..458a819 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandAdminCommand.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandAdminCommand.java @@ -16,7 +16,7 @@ import org.bukkit.block.Biome; import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; -import xyz.soukup.ecoCraftCore.database.objects.Island; +import xyz.soukup.ecoCraftCore.objects.Island; import xyz.soukup.ecoCraftCore.messages.Messages; import java.io.IOException; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java index 324e265..070acf2 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java @@ -17,10 +17,10 @@ import com.j256.ormlite.stmt.UpdateBuilder; import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataType; -import xyz.soukup.ecoCraftCore.database.objects.ActiveServer; -import xyz.soukup.ecoCraftCore.database.objects.Island; -import xyz.soukup.ecoCraftCore.database.objects.Region; -import xyz.soukup.ecoCraftCore.database.objects.TeleportRequest; +import xyz.soukup.ecoCraftCore.objects.ActiveServer; +import xyz.soukup.ecoCraftCore.objects.Island; +import xyz.soukup.ecoCraftCore.objects.Region; +import xyz.soukup.ecoCraftCore.objects.TeleportRequest; import xyz.soukup.ecoCraftCore.utilities.PDC; import java.io.IOException; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandSelectorCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandSelectorCommand.java index 1aa62a2..1e88687 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandSelectorCommand.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandSelectorCommand.java @@ -17,9 +17,9 @@ import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.soukup.ecoCraftCore.database.objects.Island; -import xyz.soukup.ecoCraftCore.database.objects.Region; -import xyz.soukup.ecoCraftCore.database.objects.RegionMember; +import xyz.soukup.ecoCraftCore.objects.Island; +import xyz.soukup.ecoCraftCore.objects.Region; +import xyz.soukup.ecoCraftCore.objects.RegionMember; import xyz.soukup.ecoCraftCore.gui.GuiItemBuilder; import xyz.soukup.ecoCraftCore.messages.Messages; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/islands/UnloadIsland.java b/src/main/java/xyz/soukup/ecoCraftCore/islands/UnloadIsland.java deleted file mode 100644 index 9a14b2f..0000000 --- a/src/main/java/xyz/soukup/ecoCraftCore/islands/UnloadIsland.java +++ /dev/null @@ -1,4 +0,0 @@ -package xyz.soukup.ecoCraftCore.islands; - -public class UnloadIsland { -} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/messages/Messages.java b/src/main/java/xyz/soukup/ecoCraftCore/messages/Messages.java index cfc7595..0961674 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/messages/Messages.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/messages/Messages.java @@ -53,9 +53,25 @@ public class Messages { return MiniMessage.miniMessage().deserialize(string, resolverBuilder.build()); } + public static Component get(String key, Replace... replaces){ + String string = getString(key); + + TagResolver.Builder resolverBuilder = TagResolver.builder(); + + for (Replace replace: replaces){ + string = replace.process(string); + } + + + return MiniMessage.miniMessage().deserialize(string, resolverBuilder.build()); + } + public static void send(CommandSender sender, String key){ sender.sendMessage(get(key)); } + public static void send(CommandSender sender, String key, Replace... replaces){ + sender.sendMessage(get(key, replaces)); + } public static void send(CommandSender sender, String key, HashMap placeholders){ sender.sendMessage(get(key, placeholders)); diff --git a/src/main/java/xyz/soukup/ecoCraftCore/messages/PHHM.java b/src/main/java/xyz/soukup/ecoCraftCore/messages/PHHM.java index 0116993..fcb2e16 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/messages/PHHM.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/messages/PHHM.java @@ -2,8 +2,8 @@ package xyz.soukup.ecoCraftCore.messages; import org.bukkit.Location; -import xyz.soukup.ecoCraftCore.database.objects.Account; -import xyz.soukup.ecoCraftCore.database.objects.Transaction; +import xyz.soukup.ecoCraftCore.objects.Account; +import xyz.soukup.ecoCraftCore.objects.Transaction; import java.util.HashMap; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/messages/Replace.java b/src/main/java/xyz/soukup/ecoCraftCore/messages/Replace.java new file mode 100644 index 0000000..56cda2c --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/messages/Replace.java @@ -0,0 +1,15 @@ +package xyz.soukup.ecoCraftCore.messages; + +public class Replace { + private final String key; + private final String value; + + public Replace(String key, String value) { + this.key = key; + this.value = value; + } + + public String process(String input) { + return input.replace("<" + key + ">", value); + } +} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/mines/MineWorldManager.java b/src/main/java/xyz/soukup/ecoCraftCore/mines/MineWorldManager.java index 5419c41..93cf7a0 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/mines/MineWorldManager.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/mines/MineWorldManager.java @@ -21,7 +21,7 @@ import org.bukkit.event.player.PlayerItemDamageEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import xyz.soukup.ecoCraftCore.database.objects.Island; +import xyz.soukup.ecoCraftCore.objects.Island; import xyz.soukup.ecoCraftCore.islands.DatabaseIslandLoader; import java.util.function.Consumer; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/money/MoneyCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/money/MoneyCommand.java index 8129bc1..6143474 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/money/MoneyCommand.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/money/MoneyCommand.java @@ -11,8 +11,8 @@ import io.papermc.paper.command.brigadier.argument.ArgumentTypes; import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import xyz.soukup.ecoCraftCore.database.objects.Account; -import xyz.soukup.ecoCraftCore.database.objects.Transaction; +import xyz.soukup.ecoCraftCore.objects.Account; +import xyz.soukup.ecoCraftCore.objects.Transaction; import xyz.soukup.ecoCraftCore.messages.Messages; import xyz.soukup.ecoCraftCore.messages.PHHM; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Account.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Account.java similarity index 98% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/Account.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/Account.java index 1c1ef2e..bb08619 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Account.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Account.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DatabaseField; @@ -24,7 +24,7 @@ public class Account { } public static void setDao(Dao dao) { - dao = dao; + Account.dao = dao; } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/ActiveServer.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/ActiveServer.java similarity index 94% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/ActiveServer.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/ActiveServer.java index 451f344..3d9a00b 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/ActiveServer.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/ActiveServer.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Island.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Island.java similarity index 98% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/Island.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/Island.java index a0f8df4..914e49f 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Island.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Island.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DataType; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/Permission.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Permission.java new file mode 100644 index 0000000..035bac6 --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Permission.java @@ -0,0 +1,43 @@ +package xyz.soukup.ecoCraftCore.objects; + +public enum Permission { + PLACE(0), + BREAK(1), + INTERACT(2), + ENTITY_INTERACT(3), + OPEN_CHESTS(4), + ENTER(5), + EXIT(6), + MANAGE_MEMBERS(7), + MANAGE_GROUPS(8), + MANAGE_REGIONS(9), + TRANSFER_OWNERSHIP(10), + USE_HOPPER(11), + HARVEST(12), + PLANT(13), + PICKUP_ITEMS(14), + DROP_ITEMS(15), + REDSTONE_INTERACT(16), + SIT(17), + SHOP_INTERACT(18), + HARM_ENTITIES(19), + HARM_PLAYERS(20), + VEHICLE_RIDE(21), + VEHICLE_PLACE(22), + VEHICLE_BREAK(23), + VEHICLE_INTERACT(24), + BUCKET_USE(25); + + + private final int mask; + + Permission(int position) { + // This creates the power of two: 1, 2, 4, 8, 16... + this.mask = 1 << position; + } + + public int getMask() { + return mask; + } +} + diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/PermissionGroup.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/PermissionGroup.java similarity index 81% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/PermissionGroup.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/PermissionGroup.java index 5b96649..f442b0a 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/PermissionGroup.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/PermissionGroup.java @@ -1,11 +1,10 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; import org.bukkit.Material; -import java.security.Permissions; import java.sql.SQLException; @DatabaseTable(tableName = "permission_groups") @@ -55,6 +54,10 @@ public class PermissionGroup { } + public PermissionGroup(int permissionsNumber){ + this.permissionsNumber = permissionsNumber; + } + public PermissionGroup(Region region, String name, String displayName, String description, Material icon){ this.region = region; this.name = name; @@ -90,22 +93,36 @@ public class PermissionGroup { this.permissionsNumber = 0; this.weight = 0; for (Permission permission : permissions) { - this.permissionsNumber |= permission.getBit(); + this.permissionsNumber |= permission.getMask(); } } + public PermissionGroup copyTo(Region region) { + return new PermissionGroup( + region, + this.name, + this.displayName, + this.description, + this.icon, + this.editable, + this.deletable, + this.weight, + this.permissionsNumber + ); + } + public boolean hasPermission(Permission permission) { - return (this.permissionsNumber & permission.getBit()) != 0; + return (this.permissionsNumber & permission.getMask()) != 0; } public void addPermission(Permission... permissions) { for (Permission permission : permissions){ - this.permissionsNumber |= permission.getBit(); + this.permissionsNumber |= permission.getMask(); } } public void removePermission(Permission permission) { - this.permissionsNumber &= ~permission.getBit(); + this.permissionsNumber &= ~permission.getMask(); } public String getName() { @@ -143,6 +160,7 @@ public class PermissionGroup { public void save(){ try { getDao().createOrUpdate(this); + region.refreshCache(); } catch (SQLException e) { throw new RuntimeException(e); } @@ -150,7 +168,7 @@ public class PermissionGroup { public static PermissionGroup getPermissionGroup(Region region, String name){ try { - return getDao().queryBuilder().where().eq("region", region).and().eq("name", name).queryForFirst(); + return getDao().queryBuilder().where().eq("region_id", region.getId()).and().eq("name", name).queryForFirst(); } catch (SQLException e) { throw new RuntimeException(e); } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/Region.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Region.java new file mode 100644 index 0000000..7ab23e6 --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Region.java @@ -0,0 +1,468 @@ +package xyz.soukup.ecoCraftCore.objects; + +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.dao.ForeignCollection; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.field.ForeignCollectionField; +import com.j256.ormlite.stmt.DeleteBuilder; +import com.j256.ormlite.stmt.Where; +import com.j256.ormlite.table.DatabaseTable; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.soukup.ecoCraftCore.messages.Messages; + +import java.sql.SQLException; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@DatabaseTable(tableName = "regions") +public class Region { + + public static Dao dao; + + public static void setDao(Dao dao) { + Region.dao = dao; + } + + public static Dao getDao() { + return dao; + } + + public static final HashMap> cache = new HashMap<>(); + + @DatabaseField(generatedId = true) + private int id; + + @DatabaseField(canBeNull = false) + private String island; + + @DatabaseField(columnName = "region_level", canBeNull = false) + private int regionLevel; + + @DatabaseField(canBeNull = false) + private int x1; + + @DatabaseField(canBeNull = false) + private int y1; + + @DatabaseField(canBeNull = false) + private int z1; + + @DatabaseField(canBeNull = false) + private int x2; + + @DatabaseField(canBeNull = false) + private int y2; + + @DatabaseField(canBeNull = false) + private int z2; + + @ForeignCollectionField(eager = true) + private ForeignCollection regionMembers; + + @DatabaseField() + private Integer value; + + public Region() { + + } + + public Region(String island, int regionLevel, int x1, int y1, int z1, int x2, int y2, int z2) { + this.island = island; + this.regionLevel = regionLevel; + this.x1 = Math.min(x1, x2); + this.y1 = Math.min(y1, y2); + this.x2 = Math.max(x1, x2); + this.y2 = Math.max(y1, y2); + this.z1 = Math.min(z1, z2); + this.z2 = Math.max(z1, z2); + + save(); + createDefaultGroupsAndReturnOwner(); + + } + + public PermissionGroup getPermissionGroup(String name){ + return PermissionGroup.getPermissionGroup(this, name); + } + + public Region(Region parentRegion, int x1, int y1, int z1, int x2, int y2, int z2) { + this.island = parentRegion.getIsland(); + this.regionLevel = parentRegion.getRegionLevel() + 1; + this.x1 = Math.min(x1, x2); + this.y1 = Math.min(y1, y2); + this.x2 = Math.max(x1, x2); + this.y2 = Math.max(y1, y2); + this.z1 = Math.min(z1, z2); + this.z2 = Math.max(z1, z2); + + save(); + + copyDataFrom(parentRegion); + } + + private void copyDataFrom(Region source) { + try { + Map groupMapping = new HashMap<>(); + + List sourceGroups = PermissionGroup.getDao().queryBuilder() + .where().eq("region_id", source.getId()).query(); + + for (PermissionGroup sourceGroup : sourceGroups) { + PermissionGroup clonedGroup = sourceGroup.copyTo(this); + clonedGroup.save(); + groupMapping.put(clonedGroup.getName(), clonedGroup); + } + + for (RegionMember sourceMember : source.getRegionMembers()) { + PermissionGroup targetGroup = groupMapping.get(sourceMember.getPermissionGroup().getName()); + + if (targetGroup != null) { + addRegionMember(sourceMember.getMemberType(), sourceMember.getName(), targetGroup); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public Region(String island, int regionType, int x1, int y1, int z1, int x2, int y2, int z2, Player owner) { + this.island = island; + this.regionLevel = regionType; + this.x1 = Math.min(x1, x2); + this.y1 = Math.min(y1, y2); + this.x2 = Math.max(x1, x2); + this.y2 = Math.max(y1, y2); + this.z1 = Math.min(z1, z2); + this.z2 = Math.max(z1, z2); + + this.save(); + + PermissionGroup ownerGroup = this.createDefaultGroupsAndReturnOwner(); + addRegionMember("player", owner.getName(), ownerGroup); + + + } + + public int getId() { + return id; + } + + public int getRegionLevel() { + return regionLevel; + } + + public int getX1() { + return x1; + } + + public int getZ1() { + return z1; + } + + public int getZ2() { + return z2; + } + + public int getY1() { + return y1; + } + + public int getX2() { + return x2; + } + + public int getY2() { + return y2; + } + + public ForeignCollection getRegionMembers() { + return regionMembers; + } + + public Integer getValue() { + return value; + } + + public String getIsland() { + return island; + } + + + + + + public void setRegionLevel(int regionLevel) { + this.regionLevel = regionLevel; + } + + public void setValue(Integer value) { + this.value = value; + } + + public void save(){ + try { + + getDao().createOrUpdate(this); + List regions = cache.get(island); + + if (regions == null) { + return; + } + + regions.removeIf(region -> region.getId() == this.id); + regions.add(this); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void refreshCache(){ + List regions = cache.get(island); + + if (regions == null) { + return; + } + + try { + Region fefreshedRegion = getDao().queryForId(this.id); + regions.removeIf(region -> region.getId() == this.id); + regions.add(fefreshedRegion); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + public void addRegionMember(Player player, PermissionGroup group){ + addRegionMember("player", player.getName(), group); + } + + public void addRegionMember(String memberType, String member, PermissionGroup permissionGroup){ + RegionMember regionMember = new RegionMember(this, memberType, member, permissionGroup); + regionMember.save(); + + List regions = cache.get(island); + + if (regions == null) { + return; + } + + regions.removeIf(region -> region.getId() == this.id); + regions.add(this); + + } + + public void removeRegionMember(Player player){ + removeRegionMember("player", player.getName()); + } + + public void removeRegionMember(String memberType, String member){ + try { + RegionMember.getDao().queryBuilder().where().eq("region", this).query(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + public RegionMember getRegionMember(Player player){ + return getRegionMember("player", player.getName()); + } + + public boolean hasPermission(Player player, Permission permission){ + RegionMember regionMember = getRegionMember(player); + PermissionGroup permissionGroup; + + if (regionMember == null) { + permissionGroup = getPermissionGroup("default"); + }else { + permissionGroup = regionMember.getPermissionGroup(); + } + + return permissionGroup.hasPermission(permission); + } + + public boolean hasPermission(String memberType, String memberName, Permission permission){ + RegionMember regionMember = getRegionMember(memberType, memberName); + PermissionGroup permissionGroup; + + if (regionMember == null) { + permissionGroup = getPermissionGroup("default"); + }else { + permissionGroup = regionMember.getPermissionGroup(); + } + + return permissionGroup.hasPermission(permission); + } + + + + public static List getOverlappingRegions(Location loc1, Location loc2) { + if (loc1.getWorld() != loc2.getWorld()){ + return null; + } + + String island = loc1.getWorld().getName(); + + List overlapping = new java.util.ArrayList<>(); + + if (!cache.containsKey(island)) { + cacheRegions(island); + } + + int minX = Math.min(loc1.getBlockX(), loc2.getBlockX()); + int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()); + int minY = Math.min(loc1.getBlockY(), loc2.getBlockY()); + int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()); + int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ()); + int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()); + + for (Region region : cache.get(island)) { + if ((region.getX1() <= maxX + && region.getX2() >= minX) && (region.getY1() <= maxY + && region.getY2() >= minY) && (region.getZ1() <= maxZ + && region.getZ2() >= minZ)) { + overlapping.add(region); + } + } + + return overlapping; + } + + public static Region getHighestLevelRegion(Location loc1, Location loc2) { + List regions = getOverlappingRegions(loc1, loc2); + + if (regions.isEmpty()) { + return null; + } + + return regions.stream().max(Comparator.comparingInt(Region::getRegionLevel)).orElse(null); + } + + public RegionMember getRegionMember(String type, String name){ + return this.regionMembers.stream().filter(regionMember -> regionMember.getMemberType().equals(type) && regionMember.getName().equals(name)).findFirst().orElse(null); + } + + + + public boolean isInside(int x, int y, int z) { + return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2 && z >= this.z1 && z <= this.z2; + } + + public boolean envelops(Location loc1, Location loc2) { + int minX = Math.min(loc1.getBlockX(), loc2.getBlockX()); + int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()); + int minY = Math.min(loc1.getBlockY(), loc2.getBlockY()); + int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()); + int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ()); + int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()); + + return this.x1 <= minX && this.x2 >= maxX && + this.y1 <= minY && this.y2 >= maxY && + this.z1 <= minZ && this.z2 >= maxZ; + } + + public static Region findById(int id) { + try { + return getDao().queryForId(id); + } catch (Exception e) { + return null; + } + } + + public static void cacheRegions(String island) { + try { + List regions = getDao().queryBuilder() + .where() + .eq("island", island) + .query(); + cache.put(island, regions); + } catch (Exception e) { + + } + } + + public static Region findRegion(Location location){ + return findRegion(location.getBlockX(), location.getBlockY(), location.getBlockZ(), location.getWorld().getName()); + } + + public static Region findRegion(int x, int y, int z, String island) { + + Region region = null; + int highestType = -1; + + if (!cache.containsKey(island)) { + cacheRegions(island); + } + + for (Region cachedRegion : cache.get(island)) { + if (!cachedRegion.isInside(x, y, z)) { + continue; + } + if (highestType >= cachedRegion.getRegionLevel()){ + continue; + } + region = cachedRegion; + } + + return region; + + + } + + public void changeBoundaries(int x1, int y1, int z1, int x2, int y2, int z2){ + this.x1 = Math.min(x1, x2); + this.y1 = Math.min(y1, y2); + this.x2 = Math.max(x1, x2); + this.y2 = Math.max(y1, y2); + this.z1 = Math.min(z1, z2); + this.z2 = Math.max(z1, z2); + } + + public PermissionGroup createDefaultGroupsAndReturnOwner(){ + String ownerDisplayName = Messages.getAsString("region.permission-groups.owner.name"); + String ownerDescription = Messages.getAsString("region.permission-groups.owner.description"); + PermissionGroup owner = new PermissionGroup(this, "owner", ownerDisplayName, ownerDescription, Material.RED_CONCRETE, false, false, 101, 2147483647); + owner.save(); + + String adminDisplayName = Messages.getAsString("region.permission-groups.admin.name"); + String adminDescription = Messages.getAsString("region.permission-groups.admin.description"); + PermissionGroup admin = new PermissionGroup(this, "admin", adminDisplayName, adminDescription, Material.YELLOW_CONCRETE, true, true, 90, 2147482623); + admin.save(); + + String memberDisplayName = Messages.getAsString("region.permission-groups.member.name"); + String memberDescription = Messages.getAsString("region.permission-groups.member.description"); + PermissionGroup member = new PermissionGroup(this, "member", memberDisplayName, memberDescription, Material.GREEN_CONCRETE, true, true, 10, 2095231); + member.save(); + + String defaultDisplayName = Messages.getAsString("region.permission-groups.default"); + String defaultDescription = Messages.getAsString("region.permission-groups.default.description"); + PermissionGroup defaultGroup = new PermissionGroup(this, "default", defaultDisplayName, defaultDescription, Material.GRAY_CONCRETE, true, false, 0,96); + defaultGroup.save(); + + return owner; + } + + + public void delete() { + try { + getDao().delete(this); + cache.get(this.island).remove(this); + Dao permissionGroupDao = PermissionGroup.getDao(); + Dao regionMemberDao = RegionMember.getDao(); + + DeleteBuilder groupDeleteBuilder = permissionGroupDao.deleteBuilder(); + groupDeleteBuilder.where().eq("region_id", this.id); + groupDeleteBuilder.delete(); + + DeleteBuilder memberDeleteBuilder= regionMemberDao.deleteBuilder(); + memberDeleteBuilder.where().eq("region_id", this.id); + memberDeleteBuilder.delete(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} + diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/RegionMember.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/RegionMember.java similarity index 80% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/RegionMember.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/RegionMember.java index 2cba6f5..0758ab4 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/RegionMember.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/RegionMember.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DatabaseField; @@ -25,8 +25,8 @@ public class RegionMember { @DatabaseField(foreign = true, foreignAutoRefresh = true) private Region region; - @DatabaseField(columnName = "member_group", canBeNull = false) - private String memberGroup; + @DatabaseField(columnName = "member_type", canBeNull = false) + private String memberType; @DatabaseField(columnName = "member_name", canBeNull = false) private String memberName; @@ -40,7 +40,7 @@ public class RegionMember { public RegionMember(Region region, String membertype, String memberName, PermissionGroup permissionGroup){ this.region = region; - this.memberGroup = membertype; + this.memberType = membertype; this.memberName = memberName; this.permissionGroup = permissionGroup; } @@ -49,8 +49,8 @@ public class RegionMember { return region; } - public String getMemberGroup() { - return memberGroup; + public String getMemberType() { + return memberType; } public String getName() { @@ -66,9 +66,14 @@ public class RegionMember { save(); } + public boolean hasPermission(Permission permission){ + return getPermissionGroup().hasPermission(permission); + } + public void save(){ try { getDao().createOrUpdate(this); + region.refreshCache(); } catch (SQLException e) { throw new RuntimeException(e); } @@ -77,6 +82,7 @@ public class RegionMember { public void delete(){ try { getDao().delete(this); + region.refreshCache(); } catch (SQLException e) { throw new RuntimeException(e); } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Shop.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Shop.java similarity index 98% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/Shop.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/Shop.java index 3c8c2fc..b265c32 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Shop.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Shop.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; @@ -27,7 +27,7 @@ public class Shop { } public static void setDao(Dao dao) { - dao = dao; + Shop.dao = dao; } @DatabaseField(generatedId = true) diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/Status.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Status.java new file mode 100644 index 0000000..a3f1838 --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Status.java @@ -0,0 +1,15 @@ +package xyz.soukup.ecoCraftCore.objects; + +public enum Status { + OK, + INVALID_SELECTION, + NO_PERMISSION, + NO_SELECTION, + REGION_NOT_ENVELOPS, + NOT_EXIST, + PLAYER_NOT_ON_ISLAND, + NOT_EXIST_GROUP, + ALREADY_MEMBER, + NOT_MEMBER, + +} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/TeleportRequest.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/TeleportRequest.java similarity index 97% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/TeleportRequest.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/TeleportRequest.java index 500eb91..2e749e0 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/TeleportRequest.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/TeleportRequest.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DatabaseField; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Transaction.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Transaction.java similarity index 98% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/Transaction.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/Transaction.java index 56e6fec..108f606 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Transaction.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Transaction.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DatabaseField; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/VirtualChest.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/VirtualChest.java similarity index 99% rename from src/main/java/xyz/soukup/ecoCraftCore/database/objects/VirtualChest.java rename to src/main/java/xyz/soukup/ecoCraftCore/objects/VirtualChest.java index a11cb83..dd5aeb9 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/VirtualChest.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/VirtualChest.java @@ -1,4 +1,4 @@ -package xyz.soukup.ecoCraftCore.database.objects; +package xyz.soukup.ecoCraftCore.objects; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DataType; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/player/PreparePlayer.java b/src/main/java/xyz/soukup/ecoCraftCore/player/PreparePlayer.java index 991ff68..1c064ab 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/player/PreparePlayer.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/player/PreparePlayer.java @@ -3,7 +3,7 @@ package xyz.soukup.ecoCraftCore.player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import xyz.soukup.ecoCraftCore.database.objects.Account; +import xyz.soukup.ecoCraftCore.objects.Account; public class PreparePlayer implements Listener { diff --git a/src/main/java/xyz/soukup/ecoCraftCore/player/TeleportRequestsHandler.java b/src/main/java/xyz/soukup/ecoCraftCore/player/TeleportRequestsHandler.java index 538c6f8..f6cff89 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/player/TeleportRequestsHandler.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/player/TeleportRequestsHandler.java @@ -5,7 +5,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import xyz.soukup.ecoCraftCore.database.objects.TeleportRequest; +import xyz.soukup.ecoCraftCore.objects.TeleportRequest; import xyz.soukup.ecoCraftCore.islands.IslandManager; import java.sql.SQLException; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java index 524c1bc..08b59ba 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java @@ -9,7 +9,7 @@ import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import xyz.soukup.ecoCraftCore.database.objects.Region; +import xyz.soukup.ecoCraftCore.objects.Region; import xyz.soukup.ecoCraftCore.messages.Messages; import java.sql.SQLException; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionCommand.java new file mode 100644 index 0000000..e36a4b2 --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionCommand.java @@ -0,0 +1,225 @@ +package xyz.soukup.ecoCraftCore.regions; + +import com.j256.ormlite.stmt.QueryBuilder; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import io.papermc.paper.command.brigadier.argument.ArgumentTypes; +import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; +import io.papermc.paper.registry.RegistryKey; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import xyz.soukup.ecoCraftCore.messages.Messages; +import xyz.soukup.ecoCraftCore.messages.Replace; +import xyz.soukup.ecoCraftCore.objects.Permission; +import xyz.soukup.ecoCraftCore.objects.PermissionGroup; +import xyz.soukup.ecoCraftCore.objects.Region; +import xyz.soukup.ecoCraftCore.objects.RegionMember; + +import java.sql.SQLException; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class RegionCommand { + + public static LiteralArgumentBuilder command(){ + LiteralArgumentBuilder confirm = Commands.literal("confirm"); + RequiredArgumentBuilder playerArgument = Commands.argument("player", ArgumentTypes.player()); + RequiredArgumentBuilder memberArgument = Commands.argument("member", StringArgumentType.word()).suggests(RegionCommand::memberGroupSuggestions); + RequiredArgumentBuilder groupArgument = Commands.argument("group", StringArgumentType.word()).suggests(RegionCommand::memberGroupSuggestions); + RequiredArgumentBuilder materialArgument = Commands.argument("icon", ArgumentTypes.itemStack()); + + LiteralArgumentBuilder create = Commands.literal("create") + .executes(RegionCommand::create); + + LiteralArgumentBuilder delete = Commands.literal("delete") + .executes(RegionCommand::delete) + .then(confirm.executes(RegionCommand::delete)); + + LiteralArgumentBuilder addMember = Commands.literal("add-member") + .then(playerArgument.then(groupArgument.executes(RegionCommand::addMember))); + + LiteralArgumentBuilder removeMember = Commands.literal("remove-member") + .then(playerArgument.executes(RegionCommand::removeMember)); + + LiteralArgumentBuilder member = Commands.literal("member") + .then(addMember) + .then(removeMember); + + LiteralArgumentBuilder group = Commands.literal("group"); + + LiteralArgumentBuilder groupAdd = Commands.literal("create") + ; + LiteralArgumentBuilder groupRemove = Commands.literal("remove"); + + RequiredArgumentBuilder regionEdits = Commands.argument("id", IntegerArgumentType.integer(1, 2147483647)) + .then(delete) + .then(member) + .then(group); + + return Commands.literal("region") + .requires(c -> c.getSender() instanceof Player) + .then(create) + .then(regionEdits); + } + + private static CompletableFuture memberGroupSuggestions(CommandContext context, SuggestionsBuilder builder){ + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + Region region = Region.findById(id); + + if (region == null){ + return builder.buildFuture(); + } + + if (!region.hasPermission(player, Permission.MANAGE_MEMBERS)){ + return builder.buildFuture(); + } + + RegionMember regionMember = region.getRegionMember(player); + + if (regionMember == null){ + return builder.buildFuture(); + } + + PermissionGroup senderGroup = regionMember.getPermissionGroup(); + + QueryBuilder queryBuilder = PermissionGroup.getDao().queryBuilder(); + try { + queryBuilder.selectColumns("name"); + queryBuilder.where().eq("region_id", id).and().lt("weight", senderGroup.getWeight()); + List permissionGroups = queryBuilder.query(); + for (PermissionGroup permissionGroup : permissionGroups){ + builder.suggest(permissionGroup.getName()); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + + + return builder.buildFuture(); + } + + private static CompletableFuture memberSuggestions(CommandContext context, SuggestionsBuilder builder){ + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + Region region = Region.findById(id); + + if (region == null){ + return builder.buildFuture(); + } + + if (!region.hasPermission(player, Permission.MANAGE_MEMBERS)){ + return builder.buildFuture(); + } + + RegionMember regionMember = region.getRegionMember(player); + + if (regionMember == null){ + return builder.buildFuture(); + } + + PermissionGroup senderGroup = regionMember.getPermissionGroup(); + + QueryBuilder queryBuilder = RegionMember.getDao().queryBuilder(); + try { + queryBuilder.selectColumns("member_name"); + queryBuilder.where().eq("region_id", id); + List regionMembers = queryBuilder.query(); + for (RegionMember member : regionMembers){ + if (member.getPermissionGroup().getWeight() >= senderGroup.getWeight()){ + continue; + } + builder.suggest(member.getName()); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + + + return builder.buildFuture(); + } + + private static int removeMember(CommandContext context) { + int id = context.getArgument("id", Integer.class); + Player senderPlayer = (Player) context.getSource().getSender(); + String memberToRemove = context.getArgument("member", String.class); + + + switch (RegionManager.removeMemberSafely(id, memberToRemove, senderPlayer)){ + case OK -> Messages.send(senderPlayer, "region.command.removed-member"); + case NOT_EXIST -> Messages.send(senderPlayer, "region.command.error.not-exist"); + case NO_PERMISSION -> Messages.send(senderPlayer, "region.command.error.no-permission"); + case NOT_MEMBER -> Messages.send(senderPlayer, "region.command.error.not-member"); + + } + + return 0; + + } + + private static int addMember(CommandContext context){ + int id = context.getArgument("id", Integer.class); + String groupName = context.getArgument("group", String.class); + Player senderPlayer = (Player) context.getSource().getSender(); + PlayerSelectorArgumentResolver playerSelectorArgumentResolver = context.getArgument("player", PlayerSelectorArgumentResolver.class); + try { + Player playerToAdd = playerSelectorArgumentResolver.resolve(context.getSource()).getFirst(); + + switch (RegionManager.addMemberSafely(id, playerToAdd, senderPlayer, groupName)){ + case OK -> Messages.send(senderPlayer, "region.command.added-member"); + case NOT_EXIST -> Messages.send(senderPlayer, "region.command.error.not-exist"); + case NO_PERMISSION -> Messages.send(senderPlayer, "region.command.error.no-permission"); + case NOT_EXIST_GROUP -> Messages.send(senderPlayer, "region.command.error.not-exist-group"); + case PLAYER_NOT_ON_ISLAND -> Messages.send(senderPlayer, "region.command.error.player-not-on-island"); + case ALREADY_MEMBER -> Messages.send(senderPlayer, "region.command.error.already-member"); + } + } catch (CommandSyntaxException e) { + throw new RuntimeException(e); + } + return 0; + } + + private static int delete(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + + if (!context.getInput().endsWith("confirm")){ + Messages.send(player, "region.command.confirm-warning.delete", new Replace("id", String.valueOf(id))); + return 1; + } + + switch (RegionManager.deleteRegionSafely(id, player)){ + case OK -> Messages.send(player, "region.command.deleted"); + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + } + + return 0; + } + + private static int create(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + + switch (RegionManager.createRegionSafely(player)){ + case OK -> Messages.send(player, "region.command.created"); + case NO_SELECTION -> Messages.send(player, "region.command.error.no-selection"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case INVALID_SELECTION -> Messages.send(player, "region.command.error.invalid-selection"); + case REGION_NOT_ENVELOPS -> Messages.send(player, "region.command.error.region-not-envelops"); + } + return 0; + } + + + + +} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java index 254638d..abdeffc 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java @@ -1,8 +1,13 @@ package xyz.soukup.ecoCraftCore.regions; +import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.NamespacedKey; +import org.bukkit.block.Barrel; import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.block.DoubleChest; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; @@ -12,14 +17,20 @@ import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityMountEvent; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent; import org.bukkit.event.player.*; import org.bukkit.event.vehicle.VehicleDestroyEvent; import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; -import xyz.soukup.ecoCraftCore.database.objects.Region; -import xyz.soukup.ecoCraftCore.database.objects.RegionMember; +import org.bukkit.util.Vector; +import xyz.soukup.ecoCraftCore.objects.Permission; +import xyz.soukup.ecoCraftCore.objects.Region; import static xyz.soukup.ecoCraftCore.EcoCraftCore.plugin; @@ -27,35 +38,31 @@ public class RegionEvents implements Listener { @EventHandler public void onPlayerInteract(PlayerInteractEvent event){ - switch (event.getAction()) { - case RIGHT_CLICK_BLOCK: - case LEFT_CLICK_BLOCK: - break; - default: - return; - } - + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; Block block = event.getClickedBlock(); - ItemStack item = event.getItem(); if (block == null) return; - if (item != null && item.getType().isBlock() && !block.getType().isInteractable()) { + ItemStack item = event.getItem(); + Player player = event.getPlayer(); + + boolean interactable = block.getType().isInteractable(); + + if ((!interactable || player.isSneaking()) && item != null && item.getType().isBlock()) { return; } - boolean allowed = isAllowedToInteract( - block.getWorld().getName(), - event.getPlayer(), - block.getX(), - block.getY(), - block.getZ() - ); + boolean harvestAllowed = RegionManager.hasPermission(player, block.getLocation(), Permission.HARVEST); - if (allowed){ + if (isCrop(block.getType()) && harvestAllowed) { return; } + boolean interactAllowed = RegionManager.hasPermission(player, block.getLocation(), Permission.INTERACT); + + if (interactAllowed) { + return; + } event.setCancelled(true); } @@ -68,13 +75,7 @@ public class RegionEvents implements Listener { Player player = event.getPlayer(); Location location = player.getLocation(); - boolean allowed = isAllowedToInteract( - location.getWorld().getName(), - player, - location.getBlockX(), - location.getBlockY(), - location.getBlockZ() - ); + boolean allowed = RegionManager.hasPermission(player, location, Permission.REDSTONE_INTERACT); if (allowed){ return; @@ -88,15 +89,15 @@ public class RegionEvents implements Listener { public void onBlockPlace(BlockPlaceEvent event) { Block block = event.getBlockPlaced(); - boolean allowed = isAllowedToInteract( - block.getWorld().getName(), - event.getPlayer(), - block.getX(), - block.getY(), - block.getZ() - ); + boolean placeAllowed = RegionManager.hasPermission(event.getPlayer(), block.getLocation(), Permission.PLACE); - if (allowed){ + if (placeAllowed){ + return; + } + + boolean plantAllowed = RegionManager.hasPermission(event.getPlayer(), block.getLocation(), Permission.PLANT); + + if (plantAllowed && isCrop(block.getType())){ return; } @@ -108,15 +109,15 @@ public class RegionEvents implements Listener { Block block = event.getBlock(); - boolean allowed = isAllowedToInteract( - block.getWorld().getName(), - event.getPlayer(), - block.getX(), - block.getY(), - block.getZ() - ); + boolean breakAllowed = RegionManager.hasPermission(event.getPlayer(), block.getLocation(), Permission.BREAK); - if (allowed){ + if (breakAllowed){ + return; + } + + boolean harvestAllowed = RegionManager.hasPermission(event.getPlayer(), block.getLocation(), Permission.HARVEST); + + if (isCrop(block.getType()) && harvestAllowed) { return; } @@ -127,13 +128,7 @@ public class RegionEvents implements Listener { public void onBucketUse(PlayerBucketEmptyEvent event) { Block clickedBlock = event.getBlockClicked(); - boolean allowed = isAllowedToInteract( - clickedBlock.getWorld().getName(), - event.getPlayer(), - clickedBlock.getX(), - clickedBlock.getY(), - clickedBlock.getZ() - ); + boolean allowed = RegionManager.hasPermission(event.getPlayer(), clickedBlock.getLocation(), Permission.BUCKET_USE); if (allowed){ return; @@ -146,13 +141,7 @@ public class RegionEvents implements Listener { public void onBucketUse(PlayerBucketFillEvent event) { Block clickedBlock = event.getBlockClicked(); - boolean allowed = isAllowedToInteract( - clickedBlock.getWorld().getName(), - event.getPlayer(), - clickedBlock.getX(), - clickedBlock.getY(), - clickedBlock.getZ() - ); + boolean allowed = RegionManager.hasPermission(event.getPlayer(), clickedBlock.getLocation(), Permission.BUCKET_USE); if (allowed){ return; @@ -167,12 +156,7 @@ public class RegionEvents implements Listener { Location location = entity.getLocation(); - boolean allowed = isAllowedToInteract( - location.getWorld().getName(), - event.getPlayer(), - location.getBlockX(), - location.getBlockY(), - location.getBlockZ()); + boolean allowed = RegionManager.hasPermission(event.getPlayer(), location, Permission.ENTITY_INTERACT); if (allowed){ return; @@ -191,12 +175,7 @@ public class RegionEvents implements Listener { Entity entity = event.getEntity(); Location location = entity.getLocation(); - boolean allowed = isAllowedToInteract( - location.getWorld().getName(), - player, - location.getBlockX(), - location.getBlockY(), - location.getBlockZ()); + boolean allowed = RegionManager.hasPermission(player, location, Permission.HARM_ENTITIES); if (allowed){ return; @@ -215,48 +194,74 @@ public class RegionEvents implements Listener { Location location = event.getVehicle().getLocation(); - boolean allowed = isAllowedToInteract( - location.getWorld().getName(), - player, - location.getBlockX(), - location.getBlockY(), - location.getBlockZ()); + boolean allowed = RegionManager.hasPermission(player, location, Permission.VEHICLE_INTERACT); if (allowed){ return; } event.setCancelled(true); + event.getVehicle().setVelocity(new Vector(0, 0, 0)); } - //Preventing hopper interaction :P + @EventHandler public void onDrop(PlayerDropItemEvent event) { Player player = event.getPlayer(); Location location = player.getLocation(); - boolean allowed = isAllowedToInteract( - location.getWorld().getName(), - player, - location.getBlockX(), - location.getBlockY(), - location.getBlockZ()); + boolean allowed = RegionManager.hasPermission(player, location, Permission.DROP_ITEMS); - if (allowed){ + if (!allowed){ + event.setCancelled(true); return; } Item item = event.getItemDrop(); - item.getPersistentDataContainer().set(new NamespacedKey(plugin, "hopper_stopper"), PersistentDataType.BYTE, (byte) 1); + item.getPersistentDataContainer().set(new NamespacedKey(plugin, "player-who-dropped"), PersistentDataType.BYTE, (byte) 1); } + @EventHandler + public void onPickup(EntityPickupItemEvent event){ + if (!(event.getEntity() instanceof Player player)){ + return; + } + + Location location = event.getItem().getLocation(); + + boolean allowed = RegionManager.hasPermission(player, location, Permission.PICKUP_ITEMS); + + if (allowed) return; + + event.setCancelled(true); + } + @EventHandler public void onHopperPickup(InventoryPickupItemEvent event) { + Item item = event.getItem(); + PersistentDataContainer dataContainer = item.getPersistentDataContainer(); + + + if (!dataContainer.has(new NamespacedKey(plugin, "player-who-dropped"), PersistentDataType.STRING)) { + return; + } + + String playerName = dataContainer.get(new NamespacedKey(plugin, "player-who-dropped"), PersistentDataType.STRING); + + assert playerName != null; + Player player = Bukkit.getPlayer(playerName); + + if (player == null){ + event.setCancelled(true); + return; + } + + boolean allowed = RegionManager.hasPermission(player, item.getLocation(), Permission.USE_HOPPER); - if (!item.getPersistentDataContainer().has(new NamespacedKey(plugin, "hopper_stopper"), PersistentDataType.BYTE)) { + if (allowed){ return; } @@ -271,12 +276,7 @@ public class RegionEvents implements Listener { Location location = event.getVehicle().getLocation(); - boolean allowed = isAllowedToInteract( - location.getWorld().getName(), - player, - location.getBlockX(), - location.getBlockY(), - location.getBlockZ()); + boolean allowed = RegionManager.hasPermission(player, location, Permission.VEHICLE_BREAK); if (allowed){ return; @@ -285,34 +285,89 @@ public class RegionEvents implements Listener { event.setCancelled(true); } + @EventHandler + public void onOpenChest(InventoryOpenEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + Player player = (Player) event.getPlayer(); + Location location = player.getLocation(); + + if (!(holder instanceof Chest || holder instanceof DoubleChest || holder instanceof Barrel)){ + return; + } + + boolean allowed = RegionManager.hasPermission(player, location, Permission.OPEN_CHESTS); + + if (allowed){ + return; + } + + event.setCancelled(true); + + } + + @EventHandler + public void onMove(PlayerMoveEvent event) { + if (event.getFrom().getBlockX() == event.getTo().getBlockX() + && event.getFrom().getBlockY() == event.getTo().getBlockY() + && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) { + return; + } + + Player player = event.getPlayer(); + Location from = event.getFrom(); + Location to = event.getTo(); + + Region fromRegion = Region.findRegion(from); + Region toRegion = Region.findRegion(to); + if (fromRegion == toRegion){ + return; + } - private boolean isAllowedToInteract(String island, Player player, Location location){ - return isAllowedToInteract(island, player, location.getBlockX(), location.getBlockY(), location.getBlockZ()); + boolean allowedToEnter = RegionManager.hasPermission(player, toRegion, Permission.ENTER); + boolean allowedToExit = RegionManager.hasPermission(player, fromRegion, Permission.EXIT); + + if (allowedToEnter && allowedToExit){ + return; + } + + event.setCancelled(true); } - private boolean isAllowedToInteract(String island, Player player, int x, int y, int z){ - if (player.isOp()){ - return true; + @EventHandler + public void onMountVehicle(EntityMountEvent event) { + if (!(event.getEntity() instanceof Player player)){ + return; } - Region region = Region.findRegion(x, y, z, island); + Entity mount = event.getMount(); + String entityType = mount.getType().name(); - if (region == null){ - return false; + if (!(entityType.contains("BOAT") || entityType.contains("MINECART"))){ + return; } - String name = player.getName(); + Location location = mount.getLocation(); - for (RegionMember regionMember : region.getRegionMembers()){ + boolean allowed = RegionManager.hasPermission(player, location, Permission.VEHICLE_RIDE); - if (regionMember.getMemberGroup().equals("player") && regionMember.getName().equals(name)){ - return true; - } + if (allowed){ + return; } - return false; + event.setCancelled(true); } + private boolean isCrop(Material material) { + String name = material.name(); + return name.endsWith("_SAPLING") || name.endsWith("_CROPS") || + material == Material.WHEAT || material == Material.CARROTS || + material == Material.POTATOES || material == Material.BEETROOTS || + material == Material.NETHER_WART || material == Material.SWEET_BERRY_BUSH || + material == Material.SUGAR_CANE || material == Material.CACTUS || + material == Material.PUMPKIN_STEM || material == Material.MELON_STEM; + } + + } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java index a98bfa7..8f529d5 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java @@ -2,12 +2,14 @@ package xyz.soukup.ecoCraftCore.regions; import org.bukkit.Location; import org.bukkit.entity.Player; -import xyz.soukup.ecoCraftCore.database.objects.Region; -import xyz.soukup.ecoCraftCore.database.objects.RegionMember; +import xyz.soukup.ecoCraftCore.objects.*; import xyz.soukup.ecoCraftCore.positionMarker.MarkerEvent; public class RegionManager { - public static int createRegion(Player player, Integer type, String owner, String ownerType){ + + public static PermissionGroup defaultPermissions = new PermissionGroup(409696); + + public static int createRegion(Player player, Integer level, String owner, String ownerType){ Location primaryLocation = MarkerEvent.primaryLocations.get(player); Location secondaryLocation = MarkerEvent.secondaryLocations.get(player); @@ -27,7 +29,7 @@ public class RegionManager { int y2 = secondaryLocation.getBlockY(); int z2 = secondaryLocation.getBlockZ(); - Region region = new Region(worldName, type, x1, y1, z1, x2, y2, z2); + Region region = new Region(worldName, level, x1, y1, z1, x2, y2, z2); region.save(); region.addRegionMember(ownerType, owner, region.getPermissionGroup("owner")); @@ -68,11 +70,175 @@ public class RegionManager { for (RegionMember regionMember : region.getRegionMembers()){ - if (regionMember.getMemberGroup().equals("player") && regionMember.getName().equals(name)){ + if (regionMember.getMemberType().equals("player") && regionMember.getName().equals(name)){ return true; } } return false; } + + public static boolean hasPermission(Player player, Location location, Permission permission){ + if (player.hasPermission("ecocraftcore.region.bypass")){ + return true; + } + + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + String island = location.getWorld().getName(); + + Region region = Region.findRegion(x, y, z, island); + + return hasPermission(player, region, permission); + + } + + public static boolean hasPermission(Player player, Region region, Permission permission){ + + if (player.hasPermission("ecocraftcore.region.bypass")){ + return true; + } + + if (region == null){ + return defaultPermissions.hasPermission(permission); + } + + return region.hasPermission(player, permission); + } + + public static boolean hasPermission(String memberType, String memberName, Location location, Permission permission){ + + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + String island = location.getWorld().getName(); + + Region region = Region.findRegion(x, y, z, island); + + return hasPermission(memberType, memberName, region, permission); + + } + + public static boolean hasPermission(String memberType, String memberName, Region region, Permission permission){ + + if (region == null){ + return defaultPermissions.hasPermission(permission); + } + + return region.hasPermission(memberType, memberName, permission); + } + + public static Status deleteRegionSafely(int regionId, Player player){ + Region region = Region.findById(regionId); + + if (region == null){ + return Status.NOT_EXIST; + } + + if (!region.hasPermission(player, Permission.MANAGE_REGIONS)){ + return Status.NO_PERMISSION; + } + + region.delete(); + return Status.OK; + } + + public static Status createRegionSafely(Player player){ + Location primaryLocation = MarkerEvent.primaryLocations.get(player); + Location secondaryLocation = MarkerEvent.secondaryLocations.get(player); + + if (primaryLocation == null || secondaryLocation == null){ + return Status.NO_SELECTION; + } + + Region region = Region.getHighestLevelRegion(primaryLocation, secondaryLocation); + + if (region == null){ + return Status.INVALID_SELECTION; + } + + if (!region.hasPermission(player, Permission.MANAGE_REGIONS)){ + return Status.NO_PERMISSION; + } + + if (!region.envelops(primaryLocation, secondaryLocation)){ + return Status.REGION_NOT_ENVELOPS; + } + + int x1 = primaryLocation.getBlockX(); + int y1 = primaryLocation.getBlockY(); + int z1 = primaryLocation.getBlockZ(); + int x2 = secondaryLocation.getBlockX(); + int y2 = secondaryLocation.getBlockY(); + int z2 = secondaryLocation.getBlockZ(); + + new Region(region, x1, y1, z1, x2, y2, z2); + + return Status.OK; + } + + + public static Status addMemberSafely(int id, Player playerToAdd, Player senderPlayer, String permissionGroupName) { + Region region = Region.findById(id); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup group = region.getPermissionGroup(permissionGroupName); + PermissionGroup senderGroup = region.getRegionMember(senderPlayer).getPermissionGroup(); + + if (group == null){ + return Status.NOT_EXIST_GROUP; + } + + if (playerToAdd.getWorld().getName().equals(region.getIsland())){ + return Status.PLAYER_NOT_ON_ISLAND; + } + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_MEMBERS) && senderGroup.getWeight() > group.getWeight())){ + return Status.NO_PERMISSION; + } + + if (region.getRegionMember(playerToAdd) != null){ + return Status.ALREADY_MEMBER; + } + + region.addRegionMember(playerToAdd, group); + return Status.OK; + + } + + public static Status removeMemberSafely(int id, String memberToRemove, Player senderPlayer){ + Region region = Region.findById(id); + + if (region == null){ + return Status.NOT_EXIST; + } + + RegionMember regionMember = region.getRegionMember( "player", memberToRemove); + + if (regionMember == null){ + return Status.NOT_MEMBER; + } + + PermissionGroup GroupOfRemoved = regionMember.getPermissionGroup(); + RegionMember senderAsMember = region.getRegionMember(senderPlayer); + + if (senderAsMember == null){ + return Status.NO_PERMISSION; + } + + PermissionGroup senderGroup = senderAsMember.getPermissionGroup(); + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_MEMBERS) && senderGroup.getWeight() > GroupOfRemoved.getWeight())){ + return Status.NO_PERMISSION; + } + + region.removeRegionMember("player", memberToRemove); + return Status.OK; + + + } } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopCommand.java index a7c98d2..9ffcee6 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopCommand.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopCommand.java @@ -10,8 +10,8 @@ import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import xyz.soukup.ecoCraftCore.positionMarker.MarkerEvent; -import xyz.soukup.ecoCraftCore.database.objects.Shop; -import xyz.soukup.ecoCraftCore.database.objects.VirtualChest; +import xyz.soukup.ecoCraftCore.objects.Shop; +import xyz.soukup.ecoCraftCore.objects.VirtualChest; import xyz.soukup.ecoCraftCore.inventory.InventoryUtils; import xyz.soukup.ecoCraftCore.messages.Messages; import xyz.soukup.ecoCraftCore.utilities.PDC; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopLogic.java b/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopLogic.java index 78a3c0c..a60ac4b 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopLogic.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/shop/ShopLogic.java @@ -31,10 +31,10 @@ import xyz.soukup.ecoCraftCore.virtualChest.VirtualChestLogic; import xyz.soukup.ecoCraftCore.gui.GuiItemBuilder; import xyz.soukup.ecoCraftCore.inventory.InventoryUtils; import xyz.soukup.ecoCraftCore.messages.Messages; -import xyz.soukup.ecoCraftCore.database.objects.Account; -import xyz.soukup.ecoCraftCore.database.objects.Shop; -import xyz.soukup.ecoCraftCore.database.objects.Transaction; -import xyz.soukup.ecoCraftCore.database.objects.VirtualChest; +import xyz.soukup.ecoCraftCore.objects.Account; +import xyz.soukup.ecoCraftCore.objects.Shop; +import xyz.soukup.ecoCraftCore.objects.Transaction; +import xyz.soukup.ecoCraftCore.objects.VirtualChest; import xyz.soukup.ecoCraftCore.utilities.*; import java.util.HashMap; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/sign/SignEditCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/sign/SignEditCommand.java index 3d6b9d3..af96002 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/sign/SignEditCommand.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/sign/SignEditCommand.java @@ -23,12 +23,10 @@ import org.bukkit.block.sign.Side; import org.bukkit.block.sign.SignSide; import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataType; -import xyz.soukup.ecoCraftCore.database.objects.Shop; import xyz.soukup.ecoCraftCore.messages.Messages; import xyz.soukup.ecoCraftCore.regions.RegionManager; import xyz.soukup.ecoCraftCore.utilities.PDC; -import javax.sound.sampled.Line; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/sit/LetMeSit.java b/src/main/java/xyz/soukup/ecoCraftCore/sit/LetMeSit.java index 65a6296..55462ff 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/sit/LetMeSit.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/sit/LetMeSit.java @@ -16,6 +16,8 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.persistence.PersistentDataType; +import xyz.soukup.ecoCraftCore.objects.Permission; +import xyz.soukup.ecoCraftCore.regions.RegionManager; import xyz.soukup.ecoCraftCore.utilities.PDC; @@ -55,6 +57,12 @@ public class LetMeSit implements Listener { return; } + boolean allowed = RegionManager.hasPermission(player, block.getLocation(), Permission.SIT); + + if (!allowed){ + return; + } + float yaw = switch (stairs.getFacing()) { case NORTH -> 0f; case WEST -> -90f; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/virtualChest/VirtualChestLogic.java b/src/main/java/xyz/soukup/ecoCraftCore/virtualChest/VirtualChestLogic.java index 14a6627..eaf154f 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/virtualChest/VirtualChestLogic.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/virtualChest/VirtualChestLogic.java @@ -15,9 +15,8 @@ import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; -import xyz.soukup.ecoCraftCore.database.objects.Shop; import xyz.soukup.ecoCraftCore.gui.GuiItemBuilder; -import xyz.soukup.ecoCraftCore.database.objects.VirtualChest; +import xyz.soukup.ecoCraftCore.objects.VirtualChest; import xyz.soukup.ecoCraftCore.messages.Messages; import xyz.soukup.ecoCraftCore.utilities.PDC; diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index 1cd95d3..acd83ec 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -1,6 +1,6 @@ generic: success: - creat ed: Vytvořeno. + created: Vytvořeno. error: not-player: "Na tuto akci musíš být hráč" no-funds: @@ -13,6 +13,23 @@ generic: self: "Nemáš dostatek itemů" shop: "Obchod nemá dostatek itemů" region: + command: + created: "Pozemek vytvořen." + deleted: "Pozemek odstraněn." + added-member: "Hráč přidán do pozemku." + removed-member: "Hráč odebrán z pozemku." + confirm-warning: + delete: "!! Chystáš se odstranit pozemek !!
Pokud nemáš nadřadný pozemek přijdeš o území
ODSTRANIT POZEMEK
NELZE VRÁTIT ZPĚT'> delete confirm'>-> POTVRDIT A ODSTRANIT <-" + error: + no-selection: "Musíš označit pozice" + no-permission: "Zde nemáš povolení vytvořit pozemky" + invalid-selection: "Neplatná pozice" + region-not-envelops: "Podřadný pozemek musí být vytvořen na jednom stávajícím pozemku" + not-exist: "Region neexistuje" + not-esist-group: "Skupina, do které se snažíš zařadit hráče neexistuje" + player-not-on-island: "Hráš musí být na stejném ostrově jako pozemek" + already-member: "Hráč je již členem tohoto pozemku" + not-member: "Hráč není členem tohoto pozemku" permission-groups: owner: name: "Majitel"