diff --git a/src/main/java/com/massivecraft/factions/Faction.java b/src/main/java/com/massivecraft/factions/Faction.java index 3cb39583..17588592 100644 --- a/src/main/java/com/massivecraft/factions/Faction.java +++ b/src/main/java/com/massivecraft/factions/Faction.java @@ -5,6 +5,8 @@ import com.massivecraft.factions.iface.RelationParticipator; import com.massivecraft.factions.struct.Relation; import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.util.LazyLocation; +import com.massivecraft.factions.zcore.fperms.Access; +import com.massivecraft.factions.zcore.fperms.Action; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -136,6 +138,12 @@ public interface Faction extends EconomyParticipator { public int getDeaths(); + public Access hasPerm(FPlayer fPlayer, Action perm); + + public void setPermission(Relation relation, Action action, Access access); + + public void resetPerms(); + // ------------------------------- // Relation and relation colors // ------------------------------- diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdPerm.java b/src/main/java/com/massivecraft/factions/cmd/CmdPerm.java new file mode 100644 index 00000000..aef64468 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/cmd/CmdPerm.java @@ -0,0 +1,71 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.zcore.fperms.Access; +import com.massivecraft.factions.zcore.fperms.Action; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdPerm extends FCommand { + + public CmdPerm() { + super(); + this.aliases.add("perm"); + this.aliases.add("perms"); + this.aliases.add("permission"); + this.aliases.add("permissions"); + + this.optionalArgs.put("relation", "relation"); + this.optionalArgs.put("action", "action"); + this.optionalArgs.put("access", "access"); + + this.permission = Permission.SET_PEACEFUL.node; + this.disableOnLock = false; + + senderMustBePlayer = true; + senderMustBeMember = true; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if (optionalArgs.size() == 0) { + // TODO: Open the GUI. + return; + } + + // If not opening GUI, then setting the permission manually. + if (args.size() != 3) { + fme.msg(TL.COMMAND_PERM_DESCRIPTION); + return; + } + + Relation relation = Relation.fromString(argAsString(0)); + Action action = Action.fromString(argAsString(1)); + Access access = Access.fromString(argAsString(2)); + if (relation == null) { + fme.msg(TL.COMMAND_PERM_INVALID_RELATION); + return; + } + if (action == null) { + fme.msg(TL.COMMAND_PERM_INVALID_ACTION); + return; + } + if (access == null) { + fme.msg(TL.COMMAND_PERM_INVALID_ACCESS); + return; + } + + fme.getFaction().setPermission(relation, action, access); + fme.msg(TL.COMMAND_PERM_SET, action.getName(), relation.nicename, access.name()); + P.p.log(String.format(TL.COMMAND_PERM_SET.toString(), action.getName(), relation.nicename, access.name()) + " for faction " + fme.getTag()); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_PERM_DESCRIPTION; + } + +} diff --git a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java index 48f49fc5..a30ad8dd 100644 --- a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java +++ b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java @@ -69,6 +69,7 @@ public class FCmdRoot extends FCommand { public CmdClaimLine cmdClaimLine = new CmdClaimLine(); public CmdTop cmdTop = new CmdTop(); public CmdAHome cmdAHome = new CmdAHome(); + public CmdPerm cmdPerm = new CmdPerm(); public FCmdRoot() { super(); @@ -152,6 +153,7 @@ public class FCmdRoot extends FCommand { this.addSubCommand(this.cmdClaimLine); this.addSubCommand(this.cmdTop); this.addSubCommand(this.cmdAHome); + this.addSubCommand(this.cmdPerm); if (P.p.isHookedPlayervaults()) { P.p.log("Found playervaults hook, adding /f vault and /f setmaxvault commands."); this.addSubCommand(new CmdSetMaxVaults()); diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java index 0bd8ba93..eca300a1 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -4,6 +4,8 @@ import com.massivecraft.factions.*; import com.massivecraft.factions.integration.Worldguard; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; +import com.massivecraft.factions.zcore.fperms.Access; +import com.massivecraft.factions.zcore.fperms.Action; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -145,7 +147,7 @@ public class FactionsBlockListener implements Listener { } // Check if they have build permissions here. If not, block this from happening. - if (!playerCanBuildDestroyBlock(player, location, "frost walk", justCheck)) { + if (!playerCanBuildDestroyBlock(player, location, "frostwalk", justCheck)) { event.setCancelled(true); } } @@ -250,6 +252,12 @@ public class FactionsBlockListener implements Listener { } } + Access access = otherFaction.hasPerm(me, Action.valueOf(action)); + if (access != null && access != Access.UNDEFINED) { + // TODO: Update this once new access values are added other than just allow / deny. + return access == Access.ALLOW; + } + // cancel building/destroying in other territory? if (deny) { if (!justCheck) { diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java index 01a7f3fa..68b90e8e 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -10,6 +10,7 @@ import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.util.VisualizeUtil; +import com.massivecraft.factions.zcore.fperms.Access; import com.massivecraft.factions.zcore.persist.MemoryFPlayer; import com.massivecraft.factions.zcore.util.TL; import com.massivecraft.factions.zcore.util.TextUtil; @@ -353,6 +354,13 @@ public class FactionsPlayerListener implements Listener { Faction myFaction = me.getFaction(); Relation rel = myFaction.getRelationTo(otherFaction); + + Access access = otherFaction.hasPerm(me, com.massivecraft.factions.zcore.fperms.Action.valueOf("items")); + if (access != null && access != Access.UNDEFINED) { + // TODO: Update this once new access values are added other than just allow / deny. + return access == Access.ALLOW; + } + // Cancel if we are not in our own territory if (rel.confDenyUseage()) { if (!justCheck) { @@ -400,8 +408,8 @@ public class FactionsPlayerListener implements Listener { // Dupe fix. Faction myFaction = me.getFaction(); Relation rel = myFaction.getRelationTo(otherFaction); - if (!rel.isMember() || !otherFaction.playerHasOwnershipRights(me, loc) && player.getItemInHand() != null) { - switch (player.getItemInHand().getType()) { + if (!rel.isMember() || !otherFaction.playerHasOwnershipRights(me, loc) && player.getInventory().getItemInMainHand() != null) { + switch (player.getInventory().getItemInMainHand().getType()) { case CHEST: case SIGN_POST: case TRAPPED_CHEST: @@ -414,6 +422,12 @@ public class FactionsPlayerListener implements Listener { } } + Access access = otherFaction.hasPerm(me, com.massivecraft.factions.zcore.fperms.Action.BUILD); + if (access != null && access != Access.UNDEFINED) { + // TODO: Update this once new access values are added other than just allow / deny. + return access == Access.ALLOW; + } + // We only care about some material types. if (otherFaction.hasPlayersOnline()) { if (!Conf.territoryProtectedMaterials.contains(material)) { diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/Access.java b/src/main/java/com/massivecraft/factions/zcore/fperms/Access.java new file mode 100644 index 00000000..43df0354 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/Access.java @@ -0,0 +1,22 @@ +package com.massivecraft.factions.zcore.fperms; + +public enum Access { + ALLOW, + DENY, + UNDEFINED; + + /** + * Case insensitive check for access. + * @param check + * @return + */ + public static Access fromString(String check) { + for (Access access : values()) { + if (access.name().equalsIgnoreCase(check)) { + return access; + } + } + + return null; + } +} diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/Action.java b/src/main/java/com/massivecraft/factions/zcore/fperms/Action.java new file mode 100644 index 00000000..1810a530 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/Action.java @@ -0,0 +1,51 @@ +package com.massivecraft.factions.zcore.fperms; + +public enum Action { + BUILD("build"), + DESTROY("destroy"), + FROST_WALK("frostwalk"), + PAIN_BUILD("painbuild"), + DOOR("door"), + BUTTON("button"), + LEVER("lever"), + CONTAINER("container"), + INVITE("invite"), + KICK("kick"), + ITEM("items"), // generic for most items + SETHOME("sethome"), + WITHDRAW("withdraw"), + TERRITORY("territory"), + ACCESS("access"), + DISBAND("disband"), + PERMS("perms"); + + private String name; + + Action(String name) { + this.name = name; + } + + /** + * Get the friendly name of this action. Used for editing in commands. + * + * @return friendly name of the action as a String. + */ + public String getName() { + return this.name; + } + + /** + * Case insensitive check for action. + * @param check + * @return + */ + public static Action fromString(String check) { + for (Action action : values()) { + if (action.name().equalsIgnoreCase(check)) { + return action; + } + } + + return null; + } +} diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java index 8613ee37..6e2a37e5 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java @@ -10,6 +10,8 @@ import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.util.LazyLocation; import com.massivecraft.factions.util.MiscUtil; import com.massivecraft.factions.util.RelationUtil; +import com.massivecraft.factions.zcore.fperms.Access; +import com.massivecraft.factions.zcore.fperms.Action; import com.massivecraft.factions.zcore.util.TL; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -20,6 +22,7 @@ import org.bukkit.entity.Player; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; public abstract class MemoryFaction implements Faction, EconomyParticipator { protected String id = null; @@ -44,6 +47,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { protected ConcurrentHashMap warpPasswords = new ConcurrentHashMap<>(); private long lastDeath; protected int maxVaults; + protected Map> permissions = new HashMap<>(); public HashMap> getAnnouncements() { return this.announcements; @@ -314,6 +318,45 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return deaths; } + // -------------------------------------------- // + // F Permissions stuff + // -------------------------------------------- // + + + public Access hasPerm(FPlayer fPlayer, Action action) { + Relation relation = fPlayer.getRelationTo(this); + Map accessMap = permissions.get(relation); + if (accessMap != null && accessMap.containsKey(action)) { + return accessMap.get(action); + } + + return null; + } + + public void setPermission(Relation relation, Action action, Access access) { + Map accessMap = permissions.get(relation); + if (accessMap == null) { + accessMap = new HashMap<>(); + } + + accessMap.put(action, access); + } + + public void resetPerms() { + P.p.log(Level.WARNING, "Resetting permissions for Faction: " + tag); + + // First populate a map with undefined as the permission for each action. + Map freshMap = new HashMap<>(); + for (Action action : Action.values()) { + freshMap.put(action, Access.UNDEFINED); + } + + // Put the map in there for each relation. + for (Relation relation : Relation.values()) { + permissions.put(relation, freshMap); + } + } + // -------------------------------------------- // // Construct // -------------------------------------------- // @@ -333,6 +376,8 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { this.powerBoost = 0.0; this.foundedDate = System.currentTimeMillis(); this.maxVaults = Conf.defaultMaxVaults; + + resetPerms(); // Reset on new Faction so it has default values. } public MemoryFaction(MemoryFaction old) { @@ -354,6 +399,8 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { fplayers = new HashSet<>(); invites = old.invites; announcements = old.announcements; + + resetPerms(); // Reset on new Faction so it has default values. } // -------------------------------------------- // diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TL.java b/src/main/java/com/massivecraft/factions/zcore/util/TL.java index ec1a9581..ef605788 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TL.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TL.java @@ -364,6 +364,12 @@ public enum TL { COMMAND_PEACEFUL_GRANT("granted peaceful status to"), COMMAND_PEACEFUL_REVOKE("removed peaceful status from"), + COMMAND_PERM_DESCRIPTION("Edit or list your Faction's permissions."), + COMMAND_PERM_INVALID_RELATION("Invalid relation defined. Try something like 'ally'"), + COMMAND_PERM_INVALID_ACCESS("Invalid access defined. Try something like 'allow'"), + COMMAND_PERM_INVALID_ACTION("Invalid action defined. Try something like 'build'"), + COMMAND_PERM_SET("Set permission %1$s to %2$s for relation %3$s"), + COMMAND_PERMANENT_DESCRIPTION("Toggles a faction's permanence"), //TODO: Real word? COMMAND_PERMANENT_GRANT("added permanent status to"), COMMAND_PERMANENT_REVOKE("removed permanent status from"), diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 662b3cff..0f29173c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Factions -version: ${project.version} +version: ${project.version}-b${build.number} main: com.massivecraft.factions.P authors: [Olof Larsson, Brett Flannigan, drtshock] softdepend: [PlayerVaults, PlaceholderAPI, PermissionsEx, Permissions, Essentials, EssentialsChat, HeroChat, iChat, LocalAreaChat, LWC, nChat, ChatManager, CAPI, AuthMe, Vault, Spout, WorldEdit, WorldGuard, AuthDB, CaptureThePoints, CombatTag, dynmap]