diff --git a/src/main/java/xyz/soukup/ecoCraftCore/genericMenus/PlayerSelector.java b/src/main/java/xyz/soukup/ecoCraftCore/genericMenus/PlayerSelector.java new file mode 100644 index 0000000..4b2a8ee --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/genericMenus/PlayerSelector.java @@ -0,0 +1,68 @@ +package xyz.soukup.ecoCraftCore.genericMenus; + +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; +import com.github.stefvanschie.inventoryframework.pane.OutlinePane; +import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; +import com.github.stefvanschie.inventoryframework.pane.component.PagingButtons; +import com.github.stefvanschie.inventoryframework.pane.util.Slot; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import xyz.soukup.ecoCraftCore.gui.GuiItemBuilder; +import xyz.soukup.ecoCraftCore.messages.Messages; +import xyz.soukup.ecoCraftCore.messages.Replace; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +public class PlayerSelector { + public static ChestGui selectPlayer(Player viewer, List players, BiConsumer selectAction){ + ChestGui chestGui = new ChestGui(3, Messages.getAsString("gui.player-selector.title")); + PaginatedPane pane = new PaginatedPane(0,0, 9, 2); + List guiItems = new ArrayList<>(); + + chestGui.setOnGlobalClick(event -> event.setCancelled(true)); + + for (Player player : players){ + ItemStack itemStack = new ItemStack(Material.PLAYER_HEAD); + SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta(); + Component name = Messages.get("gui.player-selector.name-format", new Replace("name", player.displayName())); + + skullMeta.setOwningPlayer(player); + skullMeta.displayName(name); + itemStack.setItemMeta(skullMeta); + + GuiItem guiItem = new GuiItem(itemStack); + guiItem.setAction(event -> selectAction.accept(viewer, player)); + guiItems.add(guiItem); + } + + pane.populateWithGuiItems(guiItems); + PagingButtons pagingButtons = new PagingButtons(Slot.fromXY(0, 2),9, pane); + + chestGui.addPane(pane); + + + return chestGui; + } + + public static ChestGui selectPlayer(Player viewer, List players, BiConsumer selectAction, Consumer backAction){ + ChestGui chestGui = selectPlayer(viewer, players, selectAction); + OutlinePane pane = new OutlinePane(4,2, 1, 1); + GuiItem backButton = new GuiItemBuilder(Material.REDSTONE, + "gui.player-selector.back-button.name", + "gui.player-selector.back-button.lore", + (event -> backAction.accept(viewer))) + .build(); + + pane.addItem(backButton); + chestGui.addPane(pane); + + return chestGui; + } +} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/genericMenus/TextInput.java b/src/main/java/xyz/soukup/ecoCraftCore/genericMenus/TextInput.java new file mode 100644 index 0000000..09939d3 --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/genericMenus/TextInput.java @@ -0,0 +1,4 @@ +package xyz.soukup.ecoCraftCore.genericMenus; + +public class TextInput { +} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/gui/GuiItemBuilder.java b/src/main/java/xyz/soukup/ecoCraftCore/gui/GuiItemBuilder.java index 3c38f46..6ec70af 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/gui/GuiItemBuilder.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/gui/GuiItemBuilder.java @@ -4,21 +4,35 @@ import com.github.stefvanschie.inventoryframework.gui.GuiItem; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import xyz.soukup.ecoCraftCore.messages.Messages; import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.function.Consumer; import java.util.stream.Collectors; public class GuiItemBuilder { private final ItemStack itemStack; private final ItemMeta itemMeta; + private Consumer onClick; public GuiItemBuilder(Material material){ this.itemStack = new ItemStack(material); this.itemMeta = this.itemStack.getItemMeta(); + + } + + public GuiItemBuilder(Material material, String nameKey, String loreKey, Consumer onClick){ + this.itemStack = new ItemStack(material); + this.itemMeta = this.itemStack.getItemMeta(); + this.itemMeta.displayName(Messages.get(nameKey)); + this.itemMeta.lore(Arrays.stream(Messages.getAsString(loreKey).split("\\R")).map(MiniMessage.miniMessage()::deserialize).collect(Collectors.toList())); + this.onClick = onClick; + } public GuiItemBuilder setName(Component component){ @@ -43,6 +57,13 @@ public class GuiItemBuilder { public GuiItem build(){ this.itemStack.setItemMeta(this.itemMeta); - return new GuiItem(this.itemStack); + GuiItem guiItem = new GuiItem(this.itemStack); + + if(this.onClick != null){ + guiItem.setAction(this.onClick); + } + + return guiItem; } + } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/messages/Replace.java b/src/main/java/xyz/soukup/ecoCraftCore/messages/Replace.java index 56cda2c..de07673 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/messages/Replace.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/messages/Replace.java @@ -1,9 +1,17 @@ package xyz.soukup.ecoCraftCore.messages; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; + public class Replace { private final String key; private final String value; + public Replace(String key, Component value){ + this.key = key; + this.value = MiniMessage.miniMessage().serialize(value); + } + public Replace(String key, String value) { this.key = key; this.value = value; diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/Permission.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Permission.java index 035bac6..e333dd6 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/objects/Permission.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Permission.java @@ -1,43 +1,43 @@ -package xyz.soukup.ecoCraftCore.objects; + 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); + 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), + MANAGE_INFO(26); - private final int mask; + private final int mask; - Permission(int position) { - // This creates the power of two: 1, 2, 4, 8, 16... - this.mask = 1 << position; - } + Permission(int position) { + this.mask = 1 << position; + } - public int getMask() { - return mask; + public int getMask() { + return mask; + } } -} diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/PermissionGroup.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/PermissionGroup.java index f442b0a..7aaba92 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/objects/PermissionGroup.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/PermissionGroup.java @@ -4,6 +4,7 @@ import com.j256.ormlite.dao.Dao; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; import org.bukkit.Material; +import org.bukkit.entity.Player; import java.sql.SQLException; @@ -125,6 +126,10 @@ public class PermissionGroup { this.permissionsNumber &= ~permission.getMask(); } + public int getPermissionsNumber() { + return permissionsNumber; + } + public String getName() { return name; } @@ -157,10 +162,39 @@ public class PermissionGroup { this.weight = weight; } + public static Status changeGroupDisplayNameSafely(int id, String groupName, String displayName, Player senderPlayer){ + Region region = Region.findById(id); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup permissionGroup = region.getPermissionGroup(groupName); + + if (permissionGroup == null){ + return Status.NOT_EXIST_GROUP; + } + + PermissionGroup senderGroup = region.getRegionMember(senderPlayer).getPermissionGroup(); + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_GROUPS) && senderGroup.getWeight() > permissionGroup.getWeight())){ + return Status.NO_PERMISSION; + } + + permissionGroup.setDisplayName(displayName); + permissionGroup.save(); + + return Status.OK; + } + + public void setDescription(String description) { + this.description = description; + } + public void save(){ try { getDao().createOrUpdate(this); - region.refreshCache(); + region.dropCache(); } catch (SQLException e) { throw new RuntimeException(e); } @@ -173,4 +207,16 @@ public class PermissionGroup { throw new RuntimeException(e); } } + + public void delete() { + Dao memberDao = RegionMember.getDao(); + try { + memberDao.delete(memberDao.queryBuilder().where().eq("permission_group", this.id).query()); + getDao().delete(this); + } catch (SQLException e) { + throw new RuntimeException(e); + } + + region.dropCache(); + } } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/Region.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Region.java index 7ab23e6..f8c7dc4 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/objects/Region.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Region.java @@ -5,7 +5,6 @@ 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; @@ -91,7 +90,7 @@ public class Region { 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.regionLevel = parentRegion.getLevel() + 1; this.x1 = Math.min(x1, x2); this.y1 = Math.min(y1, y2); this.x2 = Math.max(x1, x2); @@ -151,7 +150,7 @@ public class Region { return id; } - public int getRegionLevel() { + public int getLevel() { return regionLevel; } @@ -220,20 +219,9 @@ public class Region { } } - public void refreshCache(){ - List regions = cache.get(island); + public void dropCache(){ + cache.remove(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){ @@ -261,10 +249,13 @@ public class Region { public void removeRegionMember(String memberType, String member){ try { - RegionMember.getDao().queryBuilder().where().eq("region", this).query(); + DeleteBuilder deletion = RegionMember.getDao().deleteBuilder(); + deletion.where().eq("region_id", this.id).and().eq("member_type", memberType).and().eq("member_name", member); + deletion.delete(); } catch (SQLException e) { throw new RuntimeException(e); } + dropCache(); } public RegionMember getRegionMember(Player player){ @@ -338,7 +329,7 @@ public class Region { return null; } - return regions.stream().max(Comparator.comparingInt(Region::getRegionLevel)).orElse(null); + return regions.stream().max(Comparator.comparingInt(Region::getLevel)).orElse(null); } public RegionMember getRegionMember(String type, String name){ @@ -391,7 +382,7 @@ public class Region { public static Region findRegion(int x, int y, int z, String island) { Region region = null; - int highestType = -1; + int highestType = -2; if (!cache.containsKey(island)) { cacheRegions(island); @@ -401,7 +392,7 @@ public class Region { if (!cachedRegion.isInside(x, y, z)) { continue; } - if (highestType >= cachedRegion.getRegionLevel()){ + if (highestType >= cachedRegion.getLevel()){ continue; } region = cachedRegion; @@ -464,5 +455,15 @@ public class Region { throw new RuntimeException(e); } } + + public void addPermissionGroup(String name, int weight, Material icon, String displayName, String description, int permissionsNumber) { + PermissionGroup group = new PermissionGroup(this, name, displayName, description, icon, true, true, weight, permissionsNumber); + group.save(); + } + + public void transferOwnership(Player oldOwner, Player newOwner) { + removeRegionMember(oldOwner); + addRegionMember(newOwner, this.getPermissionGroup("owner")); + } } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/RegionMember.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/RegionMember.java index 0758ab4..4cd5d05 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/objects/RegionMember.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/RegionMember.java @@ -73,7 +73,7 @@ public class RegionMember { public void save(){ try { getDao().createOrUpdate(this); - region.refreshCache(); + region.dropCache(); } catch (SQLException e) { throw new RuntimeException(e); } @@ -82,7 +82,7 @@ public class RegionMember { public void delete(){ try { getDao().delete(this); - region.refreshCache(); + region.dropCache(); } catch (SQLException e) { throw new RuntimeException(e); } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/objects/Status.java b/src/main/java/xyz/soukup/ecoCraftCore/objects/Status.java index a3f1838..64ff0f5 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/objects/Status.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/objects/Status.java @@ -9,7 +9,8 @@ public enum Status { NOT_EXIST, PLAYER_NOT_ON_ISLAND, NOT_EXIST_GROUP, + NOT_EXIST_PERMISSION, ALREADY_MEMBER, - NOT_MEMBER, + NOT_MEMBER, ALREADY_EXISTS, } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionCommand.java index e36a4b2..a24a81c 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionCommand.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionCommand.java @@ -13,8 +13,6 @@ 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; @@ -33,9 +31,14 @@ 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 memberArgument = Commands.argument("member", StringArgumentType.word()).suggests(RegionCommand::memberSuggestions); RequiredArgumentBuilder groupArgument = Commands.argument("group", StringArgumentType.word()).suggests(RegionCommand::memberGroupSuggestions); - RequiredArgumentBuilder materialArgument = Commands.argument("icon", ArgumentTypes.itemStack()); + RequiredArgumentBuilder nameArgument = Commands.argument("name", StringArgumentType.word()); + RequiredArgumentBuilder weightArgument = Commands.argument("weight", IntegerArgumentType.integer()); + RequiredArgumentBuilder iconArgument = Commands.argument("icon", ArgumentTypes.itemStack()); + RequiredArgumentBuilder displayNameArgument = Commands.argument("display-name", StringArgumentType.string()); + RequiredArgumentBuilder descriptionArgument = Commands.argument("description", StringArgumentType.greedyString()); + RequiredArgumentBuilder permissionArgument = Commands.argument("permission", StringArgumentType.word()).suggests(RegionCommand::permissionSuggestions); LiteralArgumentBuilder create = Commands.literal("create") .executes(RegionCommand::create); @@ -44,31 +47,251 @@ public class RegionCommand { .executes(RegionCommand::delete) .then(confirm.executes(RegionCommand::delete)); - LiteralArgumentBuilder addMember = Commands.literal("add-member") + LiteralArgumentBuilder addMember = Commands.literal("add") .then(playerArgument.then(groupArgument.executes(RegionCommand::addMember))); - LiteralArgumentBuilder removeMember = Commands.literal("remove-member") - .then(playerArgument.executes(RegionCommand::removeMember)); + LiteralArgumentBuilder removeMember = Commands.literal("remove") + .then(memberArgument.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"); + LiteralArgumentBuilder groupCreate = Commands.literal("create") + .then(nameArgument + .then(weightArgument + .then(iconArgument + .then(displayNameArgument + .then(descriptionArgument + .executes(RegionCommand::createGroup)))))); + + LiteralArgumentBuilder groupRemove = Commands.literal("remove") + .executes(RegionCommand::removeGroup); + + LiteralArgumentBuilder addPermission = Commands.literal("add-permission") + .then(permissionArgument.executes(RegionCommand::addPermission)); + + LiteralArgumentBuilder removePermission = Commands.literal("remove-permission") + .then(permissionArgument.executes(RegionCommand::removePermission)); + + Commands.literal("transfer-ownership").then(playerArgument + .executes(RegionCommand::transferOwnership) + .then(confirm.executes(RegionCommand::transferOwnership))); + + LiteralArgumentBuilder changeIcon = Commands.literal("change-icon") + .then(iconArgument.executes(RegionCommand::changeIcon)); + + LiteralArgumentBuilder changeDisplayName = Commands.literal("change-display-name") + .then(displayNameArgument.executes(RegionCommand::changeDisplayName)); + + LiteralArgumentBuilder changeDescription = Commands.literal("change-description") + .then(descriptionArgument.executes(RegionCommand::changeDescription)); + + RequiredArgumentBuilder groupEdit = nameArgument.suggests(RegionCommand::memberGroupSuggestions) + .then(groupRemove) + .then(addPermission) + .then(removePermission) + .then(changeIcon) + .then(changeDisplayName) + .then(changeDescription); + + LiteralArgumentBuilder group = Commands.literal("group") + .then(groupCreate) + .then(groupEdit); + RequiredArgumentBuilder regionEdits = Commands.argument("id", IntegerArgumentType.integer(1, 2147483647)) + .suggests(RegionCommand::regionIdSuggestions) .then(delete) .then(member) .then(group); return Commands.literal("region") .requires(c -> c.getSender() instanceof Player) - .then(create) - .then(regionEdits); + .then(regionEdits) + .then(create); + } + + private static int changeIcon(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + String name = context.getArgument("name", String.class); + ItemStack itemStack = context.getArgument("icon", ItemStack.class); + + switch (RegionManager.changeGroupIconSafely(id, name, itemStack, player)){ + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NOT_EXIST_GROUP -> Messages.send(player, "region.command.error.not-exist-group"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case OK -> Messages.send(player, "region.command.icon-changed"); + } + + return 0; + } + + private static int changeDescription(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + String name = context.getArgument("name", String.class); + String description = context.getArgument("description", String.class); + + switch (RegionManager.changeGroupDescriptionSafely(id, name, description, player)){ + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NOT_EXIST_GROUP -> Messages.send(player, "region.command.error.not-exist-group"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case OK -> Messages.send(player, "region.command.description-changed"); + } + + return 0; + } + + private static int changeDisplayName(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + String name = context.getArgument("name", String.class); + String displayName = context.getArgument("display-name", String.class); + + switch (RegionManager.changeGroupDisplayNameSafely(id, name, displayName, player)){ + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NOT_EXIST_GROUP -> Messages.send(player, "region.command.error.not-exist-group"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case OK -> Messages.send(player, "region.command.display-name-changed"); + } + + return 0; + } + + private static int transferOwnership(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + + PlayerSelectorArgumentResolver newOwnerResolver = context.getArgument("new-owner", PlayerSelectorArgumentResolver.class); + Player newOwner; + try { + newOwner = newOwnerResolver.resolve(context.getSource()).getFirst(); + } catch (CommandSyntaxException e) { + Messages.send(player, "region.command.error.not-exist"); + return 1; + } + + if (!context.getInput().endsWith("confirm")){ + Messages.send(player, "region.command.confirm-warning.transfer-ownership", + new Replace("id", String.valueOf(id)), + new Replace("name", newOwner.getName())); + return 1; + } + + switch (RegionManager.transferOwnershipSafely(id, player, newOwner)){ + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case OK -> Messages.send(player, "region.command.transferred-ownership"); + } + + + + return 0; + } + + private static int removePermission(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + String name = context.getArgument("name", String.class); + String permission = context.getArgument("permission", String.class); + + switch (RegionManager.removeGroupPermissionSafely(player, id, name, permission)){ + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NOT_EXIST_GROUP -> Messages.send(player, "region.command.error.not-exist-group"); + case NOT_EXIST_PERMISSION -> Messages.send(player, "region.command.error.not-exist-permission"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case OK -> Messages.send(player, "region.command.removed-permission"); + } + + return 0; + } + + private static int addPermission(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + String name = context.getArgument("name", String.class); + String permission = context.getArgument("permission", String.class); + + switch (RegionManager.addGroupPermissionSafely(player, id, name, permission)){ + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NOT_EXIST_GROUP -> Messages.send(player, "region.command.error.not-exist-group"); + case NOT_EXIST_PERMISSION -> Messages.send(player, "region.command.error.not-exist-permission"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case OK -> Messages.send(player, "region.command.added-permission"); + } + + return 0; + } + + private static int removeGroup(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + String name = context.getArgument("name", String.class); + + switch (RegionManager.removeRegionGroupSafely(id, player, name)){ + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NOT_EXIST_GROUP -> Messages.send(player, "region.command.error.not-exist-group"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case OK -> Messages.send(player, "region.command.deleted-group"); + } + + return 0; + } + + private static int createGroup(CommandContext context) { + Player player = (Player) context.getSource().getSender(); + int id = context.getArgument("id", Integer.class); + String name = context.getArgument("name", String.class); + int weight = context.getArgument("weight", Integer.class); + ItemStack icon = context.getArgument("icon", ItemStack.class); + String displayName = context.getArgument("display-name", String.class); + String description = context.getArgument("description", String.class); + + + switch (RegionManager.addRegionGroupSafely(id, player, name, weight, icon, displayName, description)){ + case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); + case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); + case ALREADY_EXISTS -> Messages.send(player, "region.command.error.already-exist"); + case OK -> Messages.send(player, "region.command.created-group"); + } + + return 0; + } + + private static CompletableFuture permissionSuggestions(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(); + } + + String remaining = builder.getRemaining().toUpperCase(); + + for (Permission permission : Permission.values()){ + if (permission.name().contains(remaining) && region.hasPermission(player, permission)){ + + builder.suggest(permission.name()); + } + } + + return builder.buildFuture(); + } + + private static CompletableFuture regionIdSuggestions(CommandContext context, SuggestionsBuilder builder) { + Player player = (Player) context.getSource().getSender(); + Region region = Region.findRegion(player.getLocation()); + + if (region != null){ + builder.suggest(region.getId()); + } + + return builder.buildFuture(); } private static CompletableFuture memberGroupSuggestions(CommandContext context, SuggestionsBuilder builder){ @@ -92,13 +315,22 @@ public class RegionCommand { PermissionGroup senderGroup = regionMember.getPermissionGroup(); + if (senderGroup == null){ + return builder.buildFuture(); + } + + QueryBuilder queryBuilder = PermissionGroup.getDao().queryBuilder(); + String remaining = builder.getRemaining().toUpperCase(); + 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()); + if (permissionGroup.getName().contains(remaining)){ + builder.suggest(permissionGroup.getName()); + } } } catch (SQLException e) { throw new RuntimeException(e); @@ -108,6 +340,8 @@ public class RegionCommand { return builder.buildFuture(); } + + private static CompletableFuture memberSuggestions(CommandContext context, SuggestionsBuilder builder){ Player player = (Player) context.getSource().getSender(); int id = context.getArgument("id", Integer.class); @@ -117,28 +351,17 @@ public class RegionCommand { 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(); + String remaining = builder.getRemaining().toUpperCase(); + 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; + if (member.getName().toUpperCase().contains(remaining)){ + builder.suggest(member.getName()); } - builder.suggest(member.getName()); } } catch (SQLException e) { throw new RuntimeException(e); diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java index 8f529d5..a89bdf4 100644 --- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java +++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java @@ -1,13 +1,19 @@ package xyz.soukup.ecoCraftCore.regions; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import xyz.soukup.ecoCraftCore.objects.*; import xyz.soukup.ecoCraftCore.positionMarker.MarkerEvent; +import java.security.InvalidParameterException; +import java.util.List; + public class RegionManager { - public static PermissionGroup defaultPermissions = new PermissionGroup(409696); + public static final PermissionGroup defaultPermissions = new PermissionGroup(409696); + public static final List onlyAdmin = List.of(Permission.EXIT, Permission.TRANSFER_OWNERSHIP); public static int createRegion(Player player, Integer level, String owner, String ownerType){ Location primaryLocation = MarkerEvent.primaryLocations.get(player); @@ -101,6 +107,7 @@ public class RegionManager { } if (region == null){ + player.sendMessage("Region not found"); return defaultPermissions.hasPermission(permission); } @@ -178,6 +185,141 @@ public class RegionManager { return Status.OK; } + public static Status transferOwnershipSafely(int id, Player sender, Player newOwner){ + Region region = Region.findById(id); + + if (region == null){ + return Status.NOT_EXIST; + } + RegionMember regionMember = region.getRegionMember(sender); + + if (regionMember == null){ + return Status.NO_PERMISSION; + } + + if (!regionMember.getPermissionGroup().hasPermission(Permission.TRANSFER_OWNERSHIP)){ + return Status.NO_PERMISSION; + } + + region.transferOwnership(sender, newOwner); + return Status.OK; + } + + public static Status addRegionGroupSafely(int regionId, Player senderPlayer, String name, int weight, ItemStack icon, String displayName, String description) { + Region region = Region.findById(regionId); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup senderGroup = region.getRegionMember(senderPlayer).getPermissionGroup(); + + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_GROUPS) && senderGroup.getWeight() > weight)){ + return Status.NO_PERMISSION; + } + + if (region.getPermissionGroup(name) != null){ + return Status.ALREADY_EXISTS; + } + + region.addPermissionGroup(name, weight, icon.getType(), displayName, description, defaultPermissions.getPermissionsNumber()); + return Status.OK; + + } + + public static Status removeRegionGroupSafely(int regionId, Player senderPlayer, String name){ + Region region = Region.findById(regionId); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup senderGroup = region.getRegionMember(senderPlayer).getPermissionGroup(); + PermissionGroup removeGroup = region.getPermissionGroup(name); + + if (removeGroup == null){ + return Status.NOT_EXIST_GROUP; + } + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_GROUPS) && senderGroup.getWeight() > removeGroup.getWeight())){ + return Status.NO_PERMISSION; + } + + removeGroup.delete(); + return Status.OK; + } + + + + public static Status addGroupPermissionSafely(Player sender, int regionId, String name, String permissionName) { + Permission permission; + + try { + permission = Permission.valueOf(permissionName.toUpperCase()); + }catch (InvalidParameterException e){ + return Status.NOT_EXIST_PERMISSION; + } + + Region region = Region.findById(regionId); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup group = region.getPermissionGroup(name); + + if (group == null){ + return Status.NOT_EXIST_GROUP; + } + + PermissionGroup senderGroup = region.getRegionMember(sender).getPermissionGroup(); + + if (!(senderGroup.hasPermission(Permission.MANAGE_GROUPS) && senderGroup.hasPermission(permission) && senderGroup.getWeight() > group.getWeight())){ + return Status.NO_PERMISSION; + } + + group.addPermission(permission); + group.save(); + + return Status.OK; + + } + + public static Status removeGroupPermissionSafely(Player sender, int regionId, String name, String permissionName) { + Permission permission; + + try { + permission = Permission.valueOf(permissionName.toUpperCase()); + }catch (InvalidParameterException e){ + return Status.NOT_EXIST_PERMISSION; + } + + Region region = Region.findById(regionId); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup group = region.getPermissionGroup(name); + + if (group == null){ + return Status.NOT_EXIST_GROUP; + } + + PermissionGroup senderGroup = region.getRegionMember(sender).getPermissionGroup(); + + if (!(senderGroup.hasPermission(Permission.MANAGE_GROUPS) && senderGroup.hasPermission(permission) && senderGroup.getWeight() > group.getWeight())){ + return Status.NO_PERMISSION; + } + + group.removePermission(permission); + group.save(); + + return Status.OK; + + } + public static Status addMemberSafely(int id, Player playerToAdd, Player senderPlayer, String permissionGroupName) { Region region = Region.findById(id); @@ -193,7 +335,7 @@ public class RegionManager { return Status.NOT_EXIST_GROUP; } - if (playerToAdd.getWorld().getName().equals(region.getIsland())){ + if (!playerToAdd.getWorld().getName().equals(region.getIsland())){ return Status.PLAYER_NOT_ON_ISLAND; } @@ -239,6 +381,80 @@ public class RegionManager { region.removeRegionMember("player", memberToRemove); return Status.OK; + } + + public static Status changeGroupIconSafely(int id, String groupName, ItemStack icon, Player senderPlayer){ + Region region = Region.findById(id); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup permissionGroup = region.getPermissionGroup(groupName); + + if (permissionGroup == null){ + return Status.NOT_EXIST_GROUP; + } + + PermissionGroup senderGroup = region.getRegionMember(senderPlayer).getPermissionGroup(); + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_GROUPS) && senderGroup.getWeight() > permissionGroup.getWeight())){ + return Status.NO_PERMISSION; + } + + permissionGroup.setIcon(icon.getType()); + permissionGroup.save(); + + return Status.OK; + } + + public static Status changeGroupDisplayNameSafely(int id, String groupName, String displayName, Player senderPlayer){ + Region region = Region.findById(id); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup permissionGroup = region.getPermissionGroup(groupName); + if (permissionGroup == null){ + return Status.NOT_EXIST_GROUP; + } + + PermissionGroup senderGroup = region.getRegionMember(senderPlayer).getPermissionGroup(); + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_GROUPS) && senderGroup.getWeight() > permissionGroup.getWeight())){ + return Status.NO_PERMISSION; + } + + permissionGroup.setDisplayName(displayName); + permissionGroup.save(); + + return Status.OK; + } + + public static Status changeGroupDescriptionSafely(int id, String groupName, String description, Player senderPlayer){ + Region region = Region.findById(id); + + if (region == null){ + return Status.NOT_EXIST; + } + + PermissionGroup permissionGroup = region.getPermissionGroup(groupName); + + if (permissionGroup == null){ + return Status.NOT_EXIST_GROUP; + } + + PermissionGroup senderGroup = region.getRegionMember(senderPlayer).getPermissionGroup(); + + if (!(region.hasPermission(senderPlayer, Permission.MANAGE_GROUPS) && senderGroup.getWeight() > permissionGroup.getWeight())){ + return Status.NO_PERMISSION; + } + + permissionGroup.setDescription(description); + permissionGroup.save(); + + return Status.OK; } } diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionMenu.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionMenu.java new file mode 100644 index 0000000..2cafb19 --- /dev/null +++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionMenu.java @@ -0,0 +1,46 @@ +package xyz.soukup.ecoCraftCore.regions; + +import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; +import com.github.stefvanschie.inventoryframework.pane.OutlinePane; +import org.bukkit.event.inventory.InventoryClickEvent; +import xyz.soukup.ecoCraftCore.messages.Messages; +import xyz.soukup.ecoCraftCore.objects.Region; +import xyz.soukup.ecoCraftCore.objects.RegionMember; + +public class RegionMenu { + public static ChestGui regionGui(RegionMember regionMember, Region region){ + + return buildGui(regionMember, region); + } + + private static ChestGui buildGui(RegionMember regionMember, Region region){ + String title; + int regionLevel = region.getLevel(); + + if (regionLevel == -1){ + title = Messages.getAsString("gui.region.title-island"); + } else { + title = Messages.getAsString("gui.region.title"); + } + + ChestGui gui = new ChestGui(2, title); + OutlinePane outlinePane = new OutlinePane(0, 0, 9, 2); + + addIslandSettings(outlinePane, regionMember, region); + + + return gui; + } + + private static void addIslandSettings(OutlinePane outlinePane, RegionMember regionMember, Region region) { + + } + + private static void setIslandDescription(InventoryClickEvent event, Region region, RegionMember regionMember) { + } + + private static void setIslandName(InventoryClickEvent inventoryClickEvent, Region region, RegionMember regionMember) { + + } + +} diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index acd83ec..727bd76 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -14,21 +14,33 @@ generic: shop: "Obchod nemá dostatek itemů" region: command: - created: "Pozemek vytvořen." - deleted: "Pozemek odstraněn." + created: "Úspěšně vytvořeno." + deleted: "Úspěšně odstraněno." + created-region: "Pozemek vytvořen." + deleted-region: "Pozemek odsraněn." + created-group: "Skupina vytvořena." + deleted-group: "Skupina odstraněna." added-member: "Hráč přidán do pozemku." removed-member: "Hráč odebrán z pozemku." + added-permission: "Oprávnění přidáno." + removed-permission: "Oprávnění odebráno." + icon-changed: "Ikona změněna." + display-name-changed: "Display name změněno." + description-changed: "Popis změněno." 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 <-" + transfer-ownership: "!! Chystáš se přenést vlastnictví pozemeku !!
Nad pozemkem již nebudeš mít kontrolu
PŘENÉST VLASTNICTVÍ
NELZE VRÁTIT ZPĚT'> transfer-ownership confirm'>-> POTVRDIT A PŘEVÉST <-" error: no-selection: "Musíš označit pozice" - no-permission: "Zde nemáš povolení vytvořit pozemky" + no-permission: "Na toto nemáš dostatečné oprávnění" 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" + not-exist: "Pozemek neexistuje" + not-exist-group: "Daná skupina neexistuje." + not-exist-permission: "Dané oprávnění neexistuje." player-not-on-island: "Hráš musí být na stejném ostrově jako pozemek" already-member: "Hráč je již členem tohoto pozemku" + already-exist: "Již existuje." not-member: "Hráč není členem tohoto pozemku" permission-groups: owner: @@ -98,6 +110,21 @@ menu: buy: "Koupit ks za $" sell: "Prodat ks za $" gui: + player-selector: + title: "Vyber Hráče" + name-format: "" + back-button: + name: "Zpět" + lore : "" + region: + title: "Nastavení pozemku" + title-island: "Nastavení ostrovního pozemku" + name-island: + name: "Změnit název ostrova" + description: "Změní název jenž se
zobrauje ve výběru ostrovů" + description-island: + name: "Změnit popis ostrova" + description: "Změní popis jenž se
zobrauje ve výběru ostrovů" error: invalid-input: "Vámi zadané hodnoty nejsou platné." all: "Seznam guis: <1>, <2>"