Work on TerritoryAccess and permissions.

This commit is contained in:
Olof Larsson 2013-04-29 12:48:11 +02:00
parent 3a6bca872f
commit 709c1fe80d
12 changed files with 132 additions and 189 deletions

View File

@ -2,19 +2,17 @@ package com.massivecraft.factions;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.bukkit.command.CommandSender;
import com.massivecraft.factions.entity.BoardColls; import com.massivecraft.factions.entity.BoardColls;
import com.massivecraft.factions.entity.UPlayer; import com.massivecraft.factions.entity.UPlayer;
import com.massivecraft.factions.entity.Faction; import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.UConf; import com.massivecraft.factions.entity.UConf;
import com.massivecraft.mcore.ps.PS; import com.massivecraft.mcore.ps.PS;
import com.massivecraft.mcore.util.Txt;
/** /**
* Permissions that you (a player) may or may not have in the territory of a certain faction. * Permissions that you (a player) may or may not have in the territory of a certain faction.
@ -26,21 +24,21 @@ public enum FPerm
// ENUM // ENUM
// -------------------------------------------- // // -------------------------------------------- //
BUILD("build", "edit the terrain", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY), BUILD(true, "build", "edit the terrain", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY),
PAINBUILD("painbuild", "edit, take damage"), PAINBUILD(true, "painbuild", "edit, take damage"),
DOOR("door", "use doors", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), DOOR(true, "door", "use doors", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY),
BUTTON("button", "use stone buttons", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), BUTTON(true, "button", "use stone buttons", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY),
LEVER("lever", "use levers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY), LEVER(true, "lever", "use levers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY),
CONTAINER("container", "use containers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER), CONTAINER(true, "container", "use containers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER),
INVITE("invite", "invite players", Rel.LEADER, Rel.OFFICER), INVITE(false, "invite", "invite players", Rel.LEADER, Rel.OFFICER),
KICK("kick", "kick members", Rel.LEADER, Rel.OFFICER), KICK(false, "kick", "kick members", Rel.LEADER, Rel.OFFICER),
SETHOME("sethome", "set the home", Rel.LEADER, Rel.OFFICER), SETHOME(false, "sethome", "set the home", Rel.LEADER, Rel.OFFICER),
WITHDRAW("withdraw", "withdraw money", Rel.LEADER, Rel.OFFICER), WITHDRAW(false, "withdraw", "withdraw money", Rel.LEADER, Rel.OFFICER),
TERRITORY("territory", "claim or unclaim", Rel.LEADER, Rel.OFFICER), TERRITORY(false, "territory", "claim or unclaim", Rel.LEADER, Rel.OFFICER),
ACCESS("access", "grant territory", Rel.LEADER, Rel.OFFICER), ACCESS(false, "access", "grant territory", Rel.LEADER, Rel.OFFICER),
DISBAND("disband", "disband the faction", Rel.LEADER), DISBAND(false, "disband", "disband the faction", Rel.LEADER),
PERMS("perms", "manage permissions", Rel.LEADER), PERMS(false, "perms", "manage permissions", Rel.LEADER),
// END OF LIST // END OF LIST
; ;
@ -49,6 +47,9 @@ public enum FPerm
// FIELDS // FIELDS
// -------------------------------------------- // // -------------------------------------------- //
private final boolean territoryPerm;
public boolean isTerritoryPerm() { return this.territoryPerm; }
private final String nicename; private final String nicename;
public String getNicename() { return this.nicename; } public String getNicename() { return this.nicename; }
@ -62,8 +63,9 @@ public enum FPerm
// CONSTRUCT // CONSTRUCT
// -------------------------------------------- // // -------------------------------------------- //
private FPerm(final String nicename, final String desc, final Rel... rels) private FPerm(boolean territoryPerm, final String nicename, final String desc, final Rel... rels)
{ {
this.territoryPerm = territoryPerm;
this.nicename = nicename; this.nicename = nicename;
this.desc = desc; this.desc = desc;
@ -120,7 +122,62 @@ public enum FPerm
} }
// -------------------------------------------- // // -------------------------------------------- //
// UTIL // HAS?
// -------------------------------------------- //
public String createDeniedMessage(UPlayer uplayer, Faction hostFaction)
{
String ret = Txt.parse("%s<b> does not allow you to %s<b>.", hostFaction.describeTo(uplayer, true), this.getDescription());
if (Perm.ADMIN.has(uplayer.getPlayer()))
{
ret += Txt.parse("\n<i>You can bypass by using " + Factions.get().getOuterCmdFactions().cmdFactionsAdmin.getUseageTemplate(false));
}
return ret;
}
public boolean has(Faction faction, Faction hostFaction)
{
Rel rel = faction.getRelationTo(hostFaction);
return hostFaction.getPermittedRelations(this).contains(rel);
}
public boolean has(UPlayer uplayer, Faction hostFaction, boolean verboose)
{
if (uplayer.isUsingAdminMode()) return true;
Faction faction = uplayer.getFaction();
if (this.has(faction, hostFaction)) return true;
if (verboose) uplayer.sendMessage(this.createDeniedMessage(uplayer, hostFaction));
return false;
}
public boolean has(UPlayer uplayer, PS ps, boolean verboose)
{
if (uplayer.isUsingAdminMode()) return true;
TerritoryAccess ta = BoardColls.get().getTerritoryAccessAt(ps);
Faction hostFaction = ta.getHostFaction(ps);
if (this.isTerritoryPerm())
{
Boolean hasTerritoryAccess = ta.hasTerritoryAccess(uplayer);
if (hasTerritoryAccess != null)
{
if (verboose && !hasTerritoryAccess)
{
uplayer.sendMessage(this.createDeniedMessage(uplayer, hostFaction));
}
return hasTerritoryAccess;
}
}
return this.has(uplayer, hostFaction, verboose);
}
// -------------------------------------------- //
// UTIL: ASCII
// -------------------------------------------- // // -------------------------------------------- //
public static String getStateHeaders() public static String getStateHeaders()
@ -160,82 +217,5 @@ public enum FPerm
} }
return ret; return ret;
} }
// Perms which apply strictly to granting territory access
// TODO: This should be a boolean field within the class itself!
private static final Set<FPerm> TerritoryPerms = EnumSet.of(BUILD, DOOR, BUTTON, LEVER, CONTAINER);
public boolean isTerritoryPerm()
{
return TerritoryPerms.contains(this);
}
private static final String errorpattern = "%s<b> does not allow you to %s<b>.";
public boolean has(Object testSubject, Faction hostFaction, boolean informIfNot)
{
RelationParticipator rpSubject = null;
if (testSubject instanceof CommandSender)
{
rpSubject = UPlayer.get(testSubject);
}
else if (testSubject instanceof RelationParticipator)
{
rpSubject = (RelationParticipator) testSubject;
}
else
{
return false;
}
Rel rel = rpSubject.getRelationTo(hostFaction);
// TODO: Create better description messages like: "You must at least be officer".
boolean ret = hostFaction.getPermittedRelations(this).contains(rel);
if (rpSubject instanceof UPlayer && ret == false && ((UPlayer)rpSubject).isUsingAdminMode()) ret = true;
if (!ret && informIfNot && rpSubject instanceof UPlayer)
{
UPlayer uplayer = (UPlayer)rpSubject;
uplayer.msg(errorpattern, hostFaction.describeTo(uplayer, true), this.getDescription());
if (Perm.ADMIN.has(uplayer.getPlayer()))
{
uplayer.msg("<i>You can bypass by using " + Factions.get().getOuterCmdFactions().cmdFactionsAdmin.getUseageTemplate(false));
}
}
return ret;
}
public boolean has(Object testSubject, Faction hostFaction)
{
return this.has(testSubject, hostFaction, false);
}
public boolean has(Object testSubject, PS ps, boolean informIfNot)
{
TerritoryAccess access = BoardColls.get().getTerritoryAccessAt(ps);
if (this.isTerritoryPerm())
{
if (access.subjectHasAccess(testSubject)) return true;
if (access.subjectAccessIsRestricted(testSubject))
{
if (informIfNot)
{
UPlayer notify = null;
if (testSubject instanceof CommandSender)
notify = UPlayer.get(testSubject);
else if (testSubject instanceof UPlayer)
notify = (UPlayer)testSubject;
if (notify != null)
notify.msg("<b>This territory owned by your faction has restricted access.");
}
return false;
}
}
return this.has(testSubject, BoardColls.get().getFactionAt(ps), informIfNot);
}
public boolean has(Object testSubject, PS ps)
{
return this.has(testSubject, ps, false);
}
} }

View File

@ -7,9 +7,6 @@ import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.massivecraft.factions.entity.FactionColl; import com.massivecraft.factions.entity.FactionColl;
import com.massivecraft.factions.entity.UPlayer; import com.massivecraft.factions.entity.UPlayer;
import com.massivecraft.factions.entity.Faction; import com.massivecraft.factions.entity.Faction;
@ -199,66 +196,24 @@ public class TerritoryAccess
{ {
return this.isHostFactionAllowed() && this.getFactionIds().isEmpty() && this.getPlayerIds().isEmpty(); return this.isHostFactionAllowed() && this.getFactionIds().isEmpty() && this.getPlayerIds().isEmpty();
} }
// -------------------------------------------- //
// HAS CHECK
// -------------------------------------------- //
// TODO: This looks like an extractor in my eyes. // true means elevated access
// TODO: Perhaps create a factionId extractor? // false means decreased access
public boolean doesHostFactionMatch(Object testSubject) // null means standard access
public Boolean hasTerritoryAccess(UPlayer uplayer)
{ {
String factionId = null; if (this.getPlayerIds().contains(uplayer.getId())) return true;
if (testSubject instanceof String)
{ String factionId = uplayer.getFactionId();
factionId = (String)testSubject; if (this.getFactionIds().contains(factionId)) return true;
}
else if (testSubject instanceof CommandSender) if (this.getHostFactionId().equals(factionId) && !this.isHostFactionAllowed()) return false;
{
factionId = UPlayer.get(testSubject).getFactionId(); return null;
}
else if (testSubject instanceof UPlayer)
{
factionId = ((UPlayer)testSubject).getFactionId();
}
else if (testSubject instanceof Faction)
{
factionId = ((Faction)testSubject).getId();
}
return this.getHostFactionId().equals(factionId);
}
// -------------------------------------------- //
// DERPINGTON CHECKS
// -------------------------------------------- //
// these return false if not granted explicit access, or true if granted explicit access (in FPlayer or Faction lists)
// they do not take into account hostFactionAllowed, which will need to be checked separately (as to not override FPerms which are denied for faction members and such)
public boolean subjectHasAccess(Object testSubject)
{
if (testSubject instanceof Player)
{
return fPlayerHasAccess(UPlayer.get(testSubject));
}
else if (testSubject instanceof UPlayer)
{
return fPlayerHasAccess((UPlayer)testSubject);
}
else if (testSubject instanceof Faction)
{
return factionHasAccess((Faction)testSubject);
}
return false;
}
public boolean fPlayerHasAccess(UPlayer fplayer)
{
return this.isPlayerIdGranted(fplayer.getId()) || this.isFactionIdGranted(fplayer.getFaction().getId());
}
public boolean factionHasAccess(Faction faction)
{
return this.isFactionIdGranted(faction.getId());
}
// this should normally only be checked after running subjectHasAccess() or fPlayerHasAccess() above to see if they have access explicitly granted
public boolean subjectAccessIsRestricted(Object testSubject)
{
return (!this.isHostFactionAllowed() && this.doesHostFactionMatch(testSubject));
} }
} }

View File

@ -39,7 +39,7 @@ public class CmdFactionsClaim extends FCommand
if (forFaction == null) return; if (forFaction == null) return;
// FPerm // FPerm
if (forFaction.isNormal() && !FPerm.TERRITORY.has(sender, forFaction, true)) return; if (forFaction.isNormal() && !FPerm.TERRITORY.has(usender, forFaction, true)) return;
// Validate // Validate
if (radius < 1) if (radius < 1)

View File

@ -36,7 +36,7 @@ public class CmdFactionsDisband extends FCommand
if (faction == null) return; if (faction == null) return;
// FPerm // FPerm
if ( ! FPerm.DISBAND.has(sender, faction, true)) return; if ( ! FPerm.DISBAND.has(usender, faction, true)) return;
// Verify // Verify
if (faction.getFlag(FFlag.PERMANENT)) if (faction.getFlag(FFlag.PERMANENT))

View File

@ -46,7 +46,7 @@ public class CmdFactionsInvite extends FCommand
} }
// FPerm // FPerm
if ( ! FPerm.INVITE.has(sender, usenderFaction, true)) return; if ( ! FPerm.INVITE.has(usender, usenderFaction, true)) return;
// Event // Event
FactionsEventInvitedChange event = new FactionsEventInvitedChange(sender, uplayer, usenderFaction, newInvited); FactionsEventInvitedChange event = new FactionsEventInvitedChange(sender, uplayer, usenderFaction, newInvited);

View File

@ -57,7 +57,7 @@ public class CmdFactionsKick extends FCommand
// FPerm // FPerm
Faction uplayerFaction = uplayer.getFaction(); Faction uplayerFaction = uplayer.getFaction();
if (!FPerm.KICK.has(sender, uplayerFaction, true)) return; if (!FPerm.KICK.has(usender, uplayerFaction, true)) return;
// Event // Event
FactionsEventMembershipChange event = new FactionsEventMembershipChange(sender, uplayer, FactionColls.get().get(uplayer).getNone(), MembershipChangeReason.KICK); FactionsEventMembershipChange event = new FactionsEventMembershipChange(sender, uplayer, FactionColls.get().get(uplayer).getNone(), MembershipChangeReason.KICK);

View File

@ -57,7 +57,7 @@ public class CmdFactionsPerm extends FCommand
} }
// Do the sender have the right to change perms for this faction? // Do the sender have the right to change perms for this faction?
if ( ! FPerm.PERMS.has(sender, faction, true)) return; if ( ! FPerm.PERMS.has(usender, faction, true)) return;
Rel rel = this.arg(2, ARRel.get()); Rel rel = this.arg(2, ARRel.get());
if (rel == null) return; if (rel == null) return;

View File

@ -42,7 +42,7 @@ public class CmdFactionsSethome extends FCommand
} }
// FPerm // FPerm
if ( ! FPerm.SETHOME.has(sender, faction, true)) return; if ( ! FPerm.SETHOME.has(usender, faction, true)) return;
// Verify // Verify
if (!usender.isUsingAdminMode() && !faction.isValidHome(newHome)) if (!usender.isUsingAdminMode() && !faction.isValidHome(newHome))

View File

@ -30,7 +30,7 @@ public class CmdFactionsUnclaim extends FCommand
Faction newFaction = FactionColls.get().get(me).getNone(); Faction newFaction = FactionColls.get().get(me).getNone();
// FPerm // FPerm
if (!FPerm.TERRITORY.has(sender, usenderFaction, true)) return; if (!FPerm.TERRITORY.has(usender, usenderFaction, true)) return;
// Apply // Apply
if (usender.tryClaim(newFaction, chunk, true, true)) return; if (usender.tryClaim(newFaction, chunk, true, true)) return;

View File

@ -38,7 +38,7 @@ public class CmdFactionsUnclaimall extends FCommand
Faction newFaction = FactionColls.get().get(faction).getNone(); Faction newFaction = FactionColls.get().get(faction).getNone();
// FPerm // FPerm
if (!FPerm.TERRITORY.has(sender, faction, true)) return; if (!FPerm.TERRITORY.has(usender, faction, true)) return;
// Apply // Apply
BoardColl boardColl = BoardColls.get().get(faction); BoardColl boardColl = BoardColls.get().get(faction);

View File

@ -89,7 +89,7 @@ public class Econ
if (i == fI && fI == fYou) return true; if (i == fI && fI == fYou) return true;
// Factions can be controlled by those that have permissions // Factions can be controlled by those that have permissions
if (you instanceof Faction && FPerm.WITHDRAW.has(i, fYou, false)) return true; if (you instanceof Faction && FPerm.WITHDRAW.has(fI, fYou)) return true;
// Otherwise you may not! ;,,; // Otherwise you may not! ;,,;
i.msg("<h>%s<i> lacks permission to control <h>%s's<i> money.", i.describeTo(i, true), you.describeTo(i)); i.msg("<h>%s<i> lacks permission to control <h>%s's<i> money.", i.describeTo(i, true), you.describeTo(i));

View File

@ -138,17 +138,26 @@ public class FactionsListenerMain implements Listener
player.sendMessage(msg); player.sendMessage(msg);
} }
// show access info message if needed // Show access level message if it changed.
TerritoryAccess accessFrom = BoardColls.get().getTerritoryAccessAt(chunkFrom);
Boolean hasTerritoryAccessFrom = accessFrom.hasTerritoryAccess(uplayer);
TerritoryAccess accessTo = BoardColls.get().getTerritoryAccessAt(chunkTo); TerritoryAccess accessTo = BoardColls.get().getTerritoryAccessAt(chunkTo);
if (!accessTo.isDefault()) Boolean hasTerritoryAccessTo = accessTo.hasTerritoryAccess(uplayer);
if (!MUtil.equals(hasTerritoryAccessFrom, hasTerritoryAccessTo))
{ {
if (accessTo.subjectHasAccess(uplayer)) if (hasTerritoryAccessTo == null)
{ {
uplayer.msg("<g>You have access to this area."); uplayer.msg("<i>You have standard access to this area.");
} }
else if (accessTo.subjectAccessIsRestricted(uplayer)) else if (hasTerritoryAccessTo)
{ {
uplayer.msg("<b>This area has restricted access."); uplayer.msg("<g>You have elevated access to this area.");
}
else
{
uplayer.msg("<b>You have decreased access to this area.");
} }
} }
} }
@ -691,33 +700,32 @@ public class FactionsListenerMain implements Listener
// FLAG: BUILD // FLAG: BUILD
// -------------------------------------------- // // -------------------------------------------- //
public static boolean canPlayerBuildAt(Player player, PS ps, boolean justCheck) public static boolean canPlayerBuildAt(Player player, PS ps, boolean verboose)
{ {
String name = player.getName(); String name = player.getName();
if (MConf.get().playersWhoBypassAllProtection.contains(name)) return true; if (MConf.get().playersWhoBypassAllProtection.contains(name)) return true;
UPlayer me = UPlayer.get(player); UPlayer uplayer = UPlayer.get(player);
if (me.isUsingAdminMode()) return true; if (uplayer.isUsingAdminMode()) return true;
Faction factionHere = BoardColls.get().getFactionAt(ps); if (!FPerm.BUILD.has(uplayer, ps, false) && FPerm.PAINBUILD.has(uplayer, ps, false))
if ( ! FPerm.BUILD.has(me, ps) && FPerm.PAINBUILD.has(me, ps))
{ {
if (!justCheck) if (verboose)
{ {
me.msg("<b>It is painful to build in the territory of %s<b>.", factionHere.describeTo(me)); Faction hostFaction = BoardColls.get().getFactionAt(ps);
uplayer.msg("<b>It is painful to build in the territory of %s<b>.", hostFaction.describeTo(uplayer));
player.damage(UConf.get(player).actionDeniedPainAmount); player.damage(UConf.get(player).actionDeniedPainAmount);
} }
return true; return true;
} }
return FPerm.BUILD.has(me, ps, true); return FPerm.BUILD.has(uplayer, ps, verboose);
} }
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockBuild(HangingPlaceEvent event) public void blockBuild(HangingPlaceEvent event)
{ {
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getEntity()), false)) return; if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getEntity()), true)) return;
event.setCancelled(true); event.setCancelled(true);
} }
@ -731,7 +739,7 @@ public class FactionsListenerMain implements Listener
Entity breaker = entityEvent.getRemover(); Entity breaker = entityEvent.getRemover();
if (! (breaker instanceof Player)) return; if (! (breaker instanceof Player)) return;
if ( ! canPlayerBuildAt((Player)breaker, PS.valueOf(event.getEntity()), false)) if ( ! canPlayerBuildAt((Player)breaker, PS.valueOf(event.getEntity()), true))
{ {
event.setCancelled(true); event.setCancelled(true);
} }
@ -742,7 +750,7 @@ public class FactionsListenerMain implements Listener
{ {
if (!event.canBuild()) return; if (!event.canBuild()) return;
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), false)) return; if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), true)) return;
event.setBuild(false); event.setBuild(false);
event.setCancelled(true); event.setCancelled(true);
@ -751,7 +759,7 @@ public class FactionsListenerMain implements Listener
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockBuild(BlockBreakEvent event) public void blockBuild(BlockBreakEvent event)
{ {
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), false)) return; if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), true)) return;
event.setCancelled(true); event.setCancelled(true);
} }
@ -761,7 +769,7 @@ public class FactionsListenerMain implements Listener
{ {
if (!event.getInstaBreak()) return; if (!event.getInstaBreak()) return;
if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), false)) return; if (canPlayerBuildAt(event.getPlayer(), PS.valueOf(event.getBlock()), true)) return;
event.setCancelled(true); event.setCancelled(true);
} }
@ -781,7 +789,7 @@ public class FactionsListenerMain implements Listener
if (targetFaction == pistonFaction) return; if (targetFaction == pistonFaction) return;
// if potentially pushing into air/water/lava in another territory, we need to check it out // if potentially pushing into air/water/lava in another territory, we need to check it out
if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && ! FPerm.BUILD.has(pistonFaction, PS.valueOf(targetBlock))) if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && ! FPerm.BUILD.has(pistonFaction, targetFaction))
{ {
event.setCancelled(true); event.setCancelled(true);
} }
@ -811,7 +819,7 @@ public class FactionsListenerMain implements Listener
Faction targetFaction = BoardColls.get().getFactionAt(retractPs); Faction targetFaction = BoardColls.get().getFactionAt(retractPs);
if (targetFaction == pistonFaction) return; if (targetFaction == pistonFaction) return;
if (!FPerm.BUILD.has(pistonFaction, retractPs)) if (!FPerm.BUILD.has(pistonFaction, targetFaction))
{ {
event.setCancelled(true); event.setCancelled(true);
} }