mirror of
https://github.com/ChestShop-authors/ChestShop-3.git
synced 2025-01-24 07:41:20 +01:00
Fix issues with the permissions for using different player names
This adds separate permissions for accessing, creating and destroying of shops. It also adds a config entry to allow using of a shop even if someone have access to it due to their permissions.
This commit is contained in:
parent
b17a471c21
commit
b853afbd52
@ -74,6 +74,9 @@ public class Properties {
|
||||
@ConfigurationComment("Do you want to allow using shops to people in creative mode?")
|
||||
public static boolean IGNORE_CREATIVE_MODE = true;
|
||||
|
||||
@ConfigurationComment("Do you want to allow using shops to people who have access to it due to their permissions? (owners are always ignored)")
|
||||
public static boolean IGNORE_ACCESS_PERMS = true;
|
||||
|
||||
@ConfigurationComment("If true, people will buy with left-click and sell with right-click.")
|
||||
public static boolean REVERSE_BUTTONS = false;
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
package com.Acrobot.ChestShop.Listeners.Block.Break;
|
||||
|
||||
import com.Acrobot.ChestShop.Configuration.Properties;
|
||||
import com.Acrobot.ChestShop.Listeners.Player.PlayerInteract;
|
||||
import com.Acrobot.ChestShop.Plugins.ChestShop;
|
||||
import com.Acrobot.ChestShop.Permission;
|
||||
import com.Acrobot.ChestShop.Signs.ChestShopSign;
|
||||
import com.Acrobot.ChestShop.Utils.uBlock;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -38,10 +38,14 @@ public class ChestBreak implements Listener {
|
||||
}
|
||||
|
||||
private static boolean canBeBroken(Block block, Player breaker) {
|
||||
if (!uBlock.couldBeShopContainer(block) || !Properties.USE_BUILT_IN_PROTECTION || !ChestShopSign.isShopChest(block)) {
|
||||
if (!uBlock.couldBeShopContainer(block) || !Properties.USE_BUILT_IN_PROTECTION) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return breaker != null && (PlayerInteract.canOpenOtherShops(breaker) || ChestShop.canAccess(breaker, block));
|
||||
Sign shopSign = uBlock.findAnyNearbyShopSign(block);
|
||||
if (breaker != null) {
|
||||
return ChestShopSign.hasPermission(breaker, Permission.OTHER_NAME_DESTROY, shopSign);
|
||||
}
|
||||
return shopSign == null;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.Acrobot.ChestShop.Configuration.Properties;
|
||||
import com.Acrobot.ChestShop.Events.ShopDestroyedEvent;
|
||||
import com.Acrobot.ChestShop.Permission;
|
||||
import com.Acrobot.ChestShop.Signs.ChestShopSign;
|
||||
import com.Acrobot.ChestShop.UUIDs.NameManager;
|
||||
import com.Acrobot.ChestShop.Utils.uBlock;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
@ -30,10 +31,8 @@ import java.util.List;
|
||||
|
||||
import static com.Acrobot.Breeze.Utils.BlockUtil.getAttachedBlock;
|
||||
import static com.Acrobot.Breeze.Utils.BlockUtil.isSign;
|
||||
import static com.Acrobot.ChestShop.Permission.ADMIN;
|
||||
import static com.Acrobot.ChestShop.Permission.MOD;
|
||||
import static com.Acrobot.ChestShop.Permission.OTHER_NAME_DESTROY;
|
||||
import static com.Acrobot.ChestShop.Signs.ChestShopSign.NAME_LINE;
|
||||
import static com.Acrobot.ChestShop.UUIDs.NameManager.canUseName;
|
||||
|
||||
/**
|
||||
* @author Acrobot
|
||||
@ -151,11 +150,7 @@ public class SignBreak implements Listener {
|
||||
}
|
||||
|
||||
private static boolean canDestroyShop(Player player, String name) {
|
||||
return player != null && (hasShopBreakingPermission(player) || canUseName(player, name));
|
||||
}
|
||||
|
||||
private static boolean hasShopBreakingPermission(Player player) {
|
||||
return Permission.has(player, ADMIN) || Permission.has(player, MOD);
|
||||
return player != null && NameManager.canUseName(player, OTHER_NAME_DESTROY, name);
|
||||
}
|
||||
|
||||
private static void sendShopDestroyedEvent(Sign sign, Player player) {
|
||||
|
@ -35,6 +35,9 @@ import static com.Acrobot.Breeze.Utils.BlockUtil.isSign;
|
||||
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType;
|
||||
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType.BUY;
|
||||
import static com.Acrobot.ChestShop.Events.TransactionEvent.TransactionType.SELL;
|
||||
import static com.Acrobot.ChestShop.Permission.OTHER_NAME_ACCESS;
|
||||
import static com.Acrobot.ChestShop.Permission.OTHER_NAME_CREATE;
|
||||
import static com.Acrobot.ChestShop.Permission.OTHER_NAME_DESTROY;
|
||||
import static com.Acrobot.ChestShop.Signs.ChestShopSign.*;
|
||||
import static org.bukkit.event.block.Action.LEFT_CLICK_BLOCK;
|
||||
import static org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK;
|
||||
@ -58,7 +61,7 @@ public class PlayerInteract implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canOpenOtherShops(player) && !ChestShop.canAccess(player, block)) {
|
||||
if (!ChestShop.canAccess(player, block)) {
|
||||
player.sendMessage(Messages.prefix(Messages.ACCESS_DENIED));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@ -66,7 +69,7 @@ public class PlayerInteract implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isSign(block) || player.getItemInHand().getType() == Material.SIGN) // Blocking accidental sign edition
|
||||
if (!isSign(block) || player.getInventory().getItemInMainHand().getType() == Material.SIGN) // Blocking accidental sign edition
|
||||
return;
|
||||
|
||||
Sign sign = (Sign) block.getState();
|
||||
@ -74,10 +77,8 @@ public class PlayerInteract implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean canAccess = ChestShopSign.canAccess(player, sign);
|
||||
|
||||
if (Properties.ALLOW_AUTO_ITEM_FILL && ChatColor.stripColor(sign.getLine(ITEM_LINE)).equals(AUTOFILL_CODE)) {
|
||||
if (canAccess) {
|
||||
if (ChestShopSign.hasPermission(player, OTHER_NAME_CREATE, sign)) {
|
||||
ItemStack item = player.getInventory().getItemInMainHand();
|
||||
if (!MaterialUtil.isEmpty(item)) {
|
||||
String itemCode = MaterialUtil.getSignName(item);
|
||||
@ -101,19 +102,22 @@ public class PlayerInteract implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canAccess && !ChestShopSign.isAdminShop(sign)) {
|
||||
if (!Properties.ALLOW_SIGN_CHEST_OPEN
|
||||
|| player.isSneaking() || player.isInsideVehicle()
|
||||
|| (Properties.IGNORE_CREATIVE_MODE && player.getGameMode() == GameMode.CREATIVE)) {
|
||||
if (ChestShopSign.hasPermission(player, OTHER_NAME_ACCESS, sign) && !ChestShopSign.isAdminShop(sign)) {
|
||||
if (Properties.ALLOW_SIGN_CHEST_OPEN) {
|
||||
if (player.isSneaking() || player.isInsideVehicle()
|
||||
|| (Properties.IGNORE_CREATIVE_MODE && player.getGameMode() == GameMode.CREATIVE)
|
||||
|| (Properties.ALLOW_LEFT_CLICK_DESTROYING && action == LEFT_CLICK_BLOCK
|
||||
&& ChestShopSign.hasPermission(player, OTHER_NAME_DESTROY, sign))) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
showChestGUI(player, block, sign);
|
||||
return;
|
||||
} else if (Properties.IGNORE_ACCESS_PERMS || ChestShopSign.isOwner(player, sign)) {
|
||||
// don't allow owners or people with access to buy/sell at this shop
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Properties.ALLOW_LEFT_CLICK_DESTROYING || action != LEFT_CLICK_BLOCK) {
|
||||
event.setCancelled(true);
|
||||
showChestGUI(player, block);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (action == RIGHT_CLICK_BLOCK) {
|
||||
@ -212,19 +216,23 @@ public class PlayerInteract implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link ChestShopSign#hasPermission(Player, Permission, Sign)} with {@link Permission#OTHER_NAME_ACCESS}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean canOpenOtherShops(Player player) {
|
||||
return Permission.has(player, Permission.ADMIN) || Permission.has(player, Permission.MOD);
|
||||
return Permission.has(player, Permission.OTHER_NAME_ACCESS + ".*");
|
||||
}
|
||||
|
||||
private static void showChestGUI(Player player, Block signBlock) {
|
||||
Container container = uBlock.findConnectedContainer(signBlock);
|
||||
private static void showChestGUI(Player player, Block signBlock, Sign sign) {
|
||||
Container container = uBlock.findConnectedContainer(sign);
|
||||
|
||||
if (container == null) {
|
||||
player.sendMessage(Messages.prefix(Messages.NO_CHEST_DETECTED));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canOpenOtherShops(player) && !Security.canAccess(player, signBlock)) {
|
||||
if (!Security.canAccess(player, signBlock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ public class PlayerInventory implements Listener {
|
||||
chest = ((DoubleChest) event.getInventory().getHolder()).getLocation().getBlock();
|
||||
}
|
||||
|
||||
if (!PlayerInteract.canOpenOtherShops(player) && !ChestShop.canAccess(player, chest)) {
|
||||
if (!ChestShop.canAccess(player, chest)) {
|
||||
player.sendMessage(Messages.prefix(Messages.ACCESS_DENIED));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import static com.Acrobot.ChestShop.Permission.OTHER_NAME_CREATE;
|
||||
import static com.Acrobot.ChestShop.Signs.ChestShopSign.NAME_LINE;
|
||||
import static com.Acrobot.ChestShop.Events.PreShopCreationEvent.CreationOutcome.UNKNOWN_PLAYER;
|
||||
|
||||
@ -22,7 +23,7 @@ public class NameChecker implements Listener {
|
||||
String name = event.getSignLine(NAME_LINE);
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (name.isEmpty() || !NameManager.canUseName(player, name)) {
|
||||
if (name.isEmpty() || !NameManager.canUseName(player, OTHER_NAME_CREATE, name)) {
|
||||
Account account = NameManager.getAccount(player.getName());
|
||||
if (account != null) {
|
||||
event.setSignLine(NAME_LINE, account.getShortName());
|
||||
|
@ -4,6 +4,8 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Acrobot
|
||||
*/
|
||||
@ -24,8 +26,12 @@ public enum Permission {
|
||||
SELL("ChestShop.shop.sell"),
|
||||
|
||||
ADMIN("ChestShop.admin"),
|
||||
ADMIN_SHOP("ChestShop.adminshop"),
|
||||
MOD("ChestShop.mod"),
|
||||
OTHER_NAME("ChestShop.name."),
|
||||
OTHER_NAME("ChestShop.name"),
|
||||
OTHER_NAME_CREATE("ChestShop.othername.create"),
|
||||
OTHER_NAME_DESTROY("ChestShop.othername.destroy"),
|
||||
OTHER_NAME_ACCESS("ChestShop.othername.access"),
|
||||
GROUP("ChestShop.group."),
|
||||
|
||||
NOFEE("ChestShop.nofee"),
|
||||
@ -48,15 +54,21 @@ public enum Permission {
|
||||
}
|
||||
|
||||
public static boolean otherName(Player player, String name) {
|
||||
if (has(player, Permission.ADMIN)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return hasPermissionSet(player, OTHER_NAME + name) || hasPermissionSet(player, OTHER_NAME + name.toLowerCase());
|
||||
return otherName(player, OTHER_NAME, name);
|
||||
}
|
||||
|
||||
private static boolean hasPermissionSet(CommandSender sender, String permission) {
|
||||
return sender.isPermissionSet(permission) && sender.hasPermission(permission);
|
||||
public static boolean otherName(Player player, Permission base, String name) {
|
||||
boolean hasBase = base != OTHER_NAME && otherName(player, OTHER_NAME, name);
|
||||
if (hasBase || has(player, base + ".*")) {
|
||||
return !hasPermissionSetFalse(player, base+ "." + name) && !hasPermissionSetFalse(player, base + "." + name.toLowerCase());
|
||||
}
|
||||
|
||||
return has(player, base + "." + name) || has(player, base + "." + name.toLowerCase());
|
||||
}
|
||||
|
||||
private static boolean hasPermissionSetFalse(CommandSender sender, String permission) {
|
||||
return (sender.isPermissionSet(permission) && !sender.hasPermission(permission))
|
||||
|| (sender.isPermissionSet(permission.toLowerCase()) && !sender.hasPermission(permission.toLowerCase()));
|
||||
}
|
||||
|
||||
public static org.bukkit.permissions.Permission getPermission(Permission permission) {
|
||||
|
@ -33,7 +33,7 @@ public class ChestShop implements Listener {
|
||||
}
|
||||
|
||||
public static boolean canAccess(Player player, Block block) {
|
||||
if (Permission.has(player, Permission.ADMIN) || !canBeProtected(block)) {
|
||||
if (!canBeProtected(block)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -65,6 +65,6 @@ public class ChestShop implements Listener {
|
||||
}
|
||||
|
||||
private static boolean isShopMember(Player player, Sign sign) {
|
||||
return NameManager.canUseName(player, sign.getLine(ChestShopSign.NAME_LINE));
|
||||
return ChestShopSign.hasPermission(player, Permission.OTHER_NAME_ACCESS, sign);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import com.Acrobot.Breeze.Utils.BlockUtil;
|
||||
import com.Acrobot.Breeze.Utils.StringUtil;
|
||||
import com.Acrobot.ChestShop.Configuration.Properties;
|
||||
import com.Acrobot.ChestShop.Containers.AdminInventory;
|
||||
import com.Acrobot.ChestShop.Database.Account;
|
||||
import com.Acrobot.ChestShop.Permission;
|
||||
import com.Acrobot.ChestShop.UUIDs.NameManager;
|
||||
import com.Acrobot.ChestShop.Utils.uBlock;
|
||||
import org.bukkit.block.Block;
|
||||
@ -102,13 +104,30 @@ public class ChestShopSign {
|
||||
}
|
||||
|
||||
public static boolean canAccess(Player player, Sign sign) {
|
||||
return hasPermission(player, Permission.OTHER_NAME_ACCESS, sign);
|
||||
}
|
||||
|
||||
public static boolean hasPermission(Player player, Permission base, Sign sign) {
|
||||
if (player == null) return false;
|
||||
if (sign == null) return true;
|
||||
|
||||
String name = sign.getLine(NAME_LINE);
|
||||
if (name == null || name.isEmpty()) return true;
|
||||
|
||||
return NameManager.canUseName(player, name);
|
||||
return NameManager.canUseName(player, base, name);
|
||||
}
|
||||
|
||||
public static boolean isOwner(Player player, Sign sign) {
|
||||
if (player == null || sign == null) return false;
|
||||
|
||||
String name = sign.getLine(NAME_LINE);
|
||||
if (name == null || name.isEmpty()) return false;
|
||||
|
||||
Account account = NameManager.getAccountFromShortName(name);
|
||||
if (account == null) {
|
||||
return player.getName().equalsIgnoreCase(name);
|
||||
}
|
||||
return account.getUuid().equals(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static boolean isValidPreparedSign(String[] lines) {
|
||||
|
@ -58,8 +58,9 @@ public class RestrictedSign implements Listener {
|
||||
|
||||
Sign sign = (Sign) connectedSign.getState();
|
||||
|
||||
if (!ChestShopSign.canAccess(player, sign)) {
|
||||
if (!ChestShopSign.hasPermission(player, Permission.OTHER_NAME_DESTROY, sign)) {
|
||||
dropSignAndCancelEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendMessage(Messages.prefix(Messages.RESTRICTED_SIGN_CREATED));
|
||||
@ -129,16 +130,11 @@ public class RestrictedSign implements Listener {
|
||||
public static boolean canAccess(Sign sign, Player player) {
|
||||
Block blockUp = sign.getBlock().getRelative(BlockFace.UP);
|
||||
return !BlockUtil.isSign(blockUp) || hasPermission(player, ((Sign) blockUp.getState()).getLines());
|
||||
|
||||
}
|
||||
|
||||
public static boolean canDestroy(Player player, Sign sign) {
|
||||
if (Permission.has(player, ADMIN)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Sign shopSign = getAssociatedSign(sign);
|
||||
return ChestShopSign.canAccess(player, shopSign);
|
||||
return ChestShopSign.hasPermission(player, Permission.OTHER_NAME_DESTROY, shopSign);
|
||||
}
|
||||
|
||||
public static Sign getAssociatedSign(Sign restricted) {
|
||||
@ -152,7 +148,7 @@ public class RestrictedSign implements Listener {
|
||||
}
|
||||
|
||||
for (String line : lines) {
|
||||
if (p.hasPermission(Permission.GROUP.toString() + line)) {
|
||||
if (Permission.has(p, Permission.GROUP + line)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.Acrobot.ChestShop.Permission.OTHER_NAME;
|
||||
|
||||
/**
|
||||
* Lets you save/cache username and UUID relations
|
||||
*
|
||||
@ -295,18 +297,26 @@ public class NameManager {
|
||||
return shortenedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #canUseName(Player, Permission, String)} to provide specific information about how the player wants to use the name
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean canUseName(Player player, String name) {
|
||||
return canUseName(player, OTHER_NAME, name);
|
||||
}
|
||||
|
||||
public static boolean canUseName(Player player, Permission base, String name) {
|
||||
if (ChestShopSign.isAdminShop(name)) {
|
||||
return Permission.has(player, Permission.ADMIN);
|
||||
return Permission.has(player, Permission.ADMIN_SHOP);
|
||||
}
|
||||
|
||||
if (Permission.otherName(player, name)) {
|
||||
if (Permission.otherName(player, base, name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Account account = getAccountFromShortName(name, false);
|
||||
return account != null && (account.getUuid().equals(player.getUniqueId())
|
||||
|| (!account.getName().equalsIgnoreCase(name) && Permission.otherName(player, account.getName())));
|
||||
|| (!account.getName().equalsIgnoreCase(name) && Permission.otherName(player, base, account.getName())));
|
||||
}
|
||||
|
||||
public static boolean isAdminShop(UUID uuid) {
|
||||
|
@ -3,6 +3,7 @@ package com.Acrobot.ChestShop.Utils;
|
||||
import com.Acrobot.Breeze.Utils.BlockUtil;
|
||||
import com.Acrobot.ChestShop.Configuration.Properties;
|
||||
import com.Acrobot.ChestShop.Signs.ChestShopSign;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
@ -67,7 +68,7 @@ public class uBlock {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #findConnectedContainer(Block, BlockFace)}
|
||||
* @deprecated Use {@link #findConnectedContainer(Location, BlockFace)}
|
||||
*/
|
||||
@Deprecated
|
||||
private static org.bukkit.block.Chest findConnectedChest(Block block, BlockFace signFace) {
|
||||
@ -94,7 +95,7 @@ public class uBlock {
|
||||
if (((org.bukkit.material.Sign) sign.getData()).isWallSign()) {
|
||||
signFace = ((Attachable) sign.getData()).getAttachedFace();
|
||||
}
|
||||
return findConnectedContainer(sign.getBlock(), signFace);
|
||||
return findConnectedContainer(sign.getLocation(), signFace);
|
||||
}
|
||||
|
||||
public static Container findConnectedContainer(Block block) {
|
||||
@ -105,12 +106,12 @@ public class uBlock {
|
||||
signFace = ((Attachable) sign.getData()).getAttachedFace();
|
||||
}
|
||||
}
|
||||
return findConnectedContainer(block, signFace);
|
||||
return findConnectedContainer(block.getLocation(), signFace);
|
||||
}
|
||||
|
||||
private static Container findConnectedContainer(Block block, BlockFace signFace) {
|
||||
private static Container findConnectedContainer(Location location, BlockFace signFace) {
|
||||
if (signFace != null) {
|
||||
Block faceBlock = block.getRelative(signFace);
|
||||
Block faceBlock = location.clone().add(signFace.getModX(), signFace.getModY(), signFace.getModZ()).getBlock();
|
||||
if (uBlock.couldBeShopContainer(faceBlock)) {
|
||||
return (Container) faceBlock.getState();
|
||||
}
|
||||
@ -118,7 +119,7 @@ public class uBlock {
|
||||
|
||||
for (BlockFace bf : SHOP_FACES) {
|
||||
if (bf != signFace) {
|
||||
Block faceBlock = block.getRelative(bf);
|
||||
Block faceBlock = location.clone().add(bf.getModX(), bf.getModY(), bf.getModZ()).getBlock();
|
||||
if (uBlock.couldBeShopContainer(faceBlock)) {
|
||||
return (Container) faceBlock.getState();
|
||||
}
|
||||
|
@ -71,10 +71,35 @@ permissions:
|
||||
ChestShop.admin:
|
||||
description: Allows user to modify/destroy other stores and create an Admin Shops
|
||||
default: op
|
||||
children:
|
||||
ChestShop.adminshop: true
|
||||
ChestShop.name.*: true
|
||||
ChestShop.adminshop:
|
||||
description: Allows user to create and destroy Admin Shops
|
||||
ChestShop.mod:
|
||||
description: Allows user only to view other store chests, he can't destroy them or create an Admin Shop
|
||||
children:
|
||||
ChestShop.name.access.*: true
|
||||
ChestShop.name.*:
|
||||
description: Gives you the power to do create and access shops for all names.
|
||||
children:
|
||||
ChestShop.name.create.*: true
|
||||
ChestShop.name.destroy.*: true
|
||||
ChestShop.name.access.*: true
|
||||
ChestShop.name.(some name):
|
||||
description: Gives you the power to do create and access shops for (some name), for example your town.
|
||||
ChestShop.name.create.*:
|
||||
description: Gives you the power to do create shops for all names.
|
||||
ChestShop.name.create.(some name):
|
||||
description: Gives you the power to do create shops for (some name), for example your town.
|
||||
ChestShop.name.destroy.*:
|
||||
description: Gives you the power to do destroy shops with all names.
|
||||
ChestShop.name.destroy.(some name):
|
||||
description: Gives you the power to do destroy shops with (some name), for example your town.
|
||||
ChestShop.name.access.*:
|
||||
description: Gives you the power to do access shops for all names.
|
||||
ChestShop.name.access.(some name):
|
||||
description: Gives you the power to do access shops for (some name), for example your town.
|
||||
ChestShop.shop.create.food:
|
||||
description: Allows to create a shop that sells food
|
||||
children:
|
||||
|
Loading…
Reference in New Issue
Block a user