diff --git a/src/com/massivecraft/factions/Conf.java b/src/com/massivecraft/factions/Conf.java index af1fb8ce..c467e7cb 100644 --- a/src/com/massivecraft/factions/Conf.java +++ b/src/com/massivecraft/factions/Conf.java @@ -181,7 +181,7 @@ public class Conf public static int spoutTerritoryDisplayPosition = 3; // permanent territory display, instead of by chat; 0 = disabled, 1 = top left, 2 = top center, 3+ = top right public static float spoutTerritoryDisplaySize = 1.0f; // text scale (size) for territory display public static boolean spoutTerritoryDisplayShowDescription = true; // whether to show the faction description, not just the faction tag - public static boolean spoutTerritoryOwnersShow = true; // show territory owner list as well + public static boolean spoutTerritoryAccessShow = true; // show occasional territory access info as well ("access granted" or "access restricted" if relevant) public static boolean spoutTerritoryNoticeShow = true; // show additional brief territory notice near center of screen, to be sure player notices transition public static int spoutTerritoryNoticeTop = 40; // how far down the screen to place the additional notice public static boolean spoutTerritoryNoticeShowDescription = false; // whether to show the faction description in the notice, not just the faction tag diff --git a/src/com/massivecraft/factions/cmd/CmdAccess.java b/src/com/massivecraft/factions/cmd/CmdAccess.java index 047cd53a..551df73e 100644 --- a/src/com/massivecraft/factions/cmd/CmdAccess.java +++ b/src/com/massivecraft/factions/cmd/CmdAccess.java @@ -4,6 +4,7 @@ import com.massivecraft.factions.Board; import com.massivecraft.factions.Faction; import com.massivecraft.factions.FLocation; import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.integration.SpoutFeatures; import com.massivecraft.factions.struct.FPerm; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.TerritoryAccess; @@ -35,8 +36,9 @@ public class CmdAccess extends FCommand { String type = this.argAsString(0); type = (type == null) ? "" : type.toLowerCase(); + FLocation loc = new FLocation(me.getLocation()); - TerritoryAccess territory = Board.getTerritoryAccessAt(new FLocation(me.getLocation())); + TerritoryAccess territory = Board.getTerritoryAccessAt(loc); Faction locFaction = territory.getHostFaction(); boolean accessAny = Permission.ACCESS_ANY.has(sender, false); @@ -87,6 +89,7 @@ public class CmdAccess extends FCommand } msg("%s has been %s the access list for this territory.", target, TextUtil.parseColor(added ? "added to" : "removed from")); + SpoutFeatures.updateAccessInfoLoc(loc); showAccessList(territory, locFaction); } diff --git a/src/com/massivecraft/factions/integration/SpoutFeatures.java b/src/com/massivecraft/factions/integration/SpoutFeatures.java index 968e16f2..f4e2a4bb 100644 --- a/src/com/massivecraft/factions/integration/SpoutFeatures.java +++ b/src/com/massivecraft/factions/integration/SpoutFeatures.java @@ -268,6 +268,27 @@ public class SpoutFeatures return mainListener.updateTerritoryDisplay(player, true); } + // update access info for all players inside a specified chunk; if specified chunk is null, then simply update everyone online + public static void updateAccessInfoLoc(FLocation fLoc) + { + if ( ! isEnabled()) return; + + Set players = FPlayers.i.getOnline(); + + for (FPlayer player : players) + { + if (fLoc == null || player.getLastStoodAt().equals(fLoc)) + mainListener.updateAccessInfo(player); + } + } + + // update owner list for specified player + public static boolean updateAccessInfo(FPlayer player) + { + if ( ! isEnabled()) return false; + return mainListener.updateAccessInfo(player); + } + public static void playerDisconnect(FPlayer player) { if ( ! isEnabled()) return; diff --git a/src/com/massivecraft/factions/integration/SpoutMainListener.java b/src/com/massivecraft/factions/integration/SpoutMainListener.java index 1f50a174..c2499dfa 100644 --- a/src/com/massivecraft/factions/integration/SpoutMainListener.java +++ b/src/com/massivecraft/factions/integration/SpoutMainListener.java @@ -15,8 +15,10 @@ import com.massivecraft.factions.FPlayer; import com.massivecraft.factions.FPlayers; import com.massivecraft.factions.Faction; import com.massivecraft.factions.P; +import com.massivecraft.factions.struct.TerritoryAccess; import org.getspout.spoutapi.event.spout.SpoutCraftEnableEvent; +import org.getspout.spoutapi.gui.Color; import org.getspout.spoutapi.gui.GenericLabel; import org.getspout.spoutapi.player.SpoutPlayer; import org.getspout.spoutapi.SpoutManager; @@ -40,7 +42,7 @@ public class SpoutMainListener implements Listener private transient static Map territoryLabels = new HashMap(); private transient static Map territoryChangeLabels = new HashMap(); - private transient static Map ownerLabels = new HashMap(); + private transient static Map accessLabels = new HashMap(); private final static int SCREEN_WIDTH = 427; // private final static int SCREEN_HEIGHT = 240; @@ -60,11 +62,28 @@ public class SpoutMainListener implements Listener return true; } + public boolean updateAccessInfo(FPlayer player) + { + Player p = player.getPlayer(); + if (p == null) + return false; + + SpoutPlayer sPlayer = SpoutManager.getPlayer(p); + if (!sPlayer.isSpoutCraftEnabled() || (Conf.spoutTerritoryDisplaySize <= 0 && ! Conf.spoutTerritoryNoticeShow)) + return false; + + FLocation here = new FLocation(player); + + doAccessInfo(player, sPlayer, here); + + return true; + } + public void removeTerritoryLabels(String playerName) { territoryLabels.remove(playerName); territoryChangeLabels.remove(playerName); - ownerLabels.remove(playerName); + accessLabels.remove(playerName); } @@ -130,6 +149,53 @@ public class SpoutMainListener implements Listener label.resetNotice(); label.setDirty(true); } + + // and access info, of course + doAccessInfo(player, sPlayer, here); + } + + private static final Color accessGrantedColor = new Color(0.2f, 1.0f, 0.2f); + private static final Color accessDeniedColor = new Color(1.0f, 0.2f, 0.2f); + private void doAccessInfo(FPlayer player, SpoutPlayer sPlayer, FLocation here) + { + if (Conf.spoutTerritoryDisplayPosition <= 0 || Conf.spoutTerritoryDisplaySize <= 0 || ! Conf.spoutTerritoryAccessShow) return; + + // ----------- + // Access Info + // ----------- + GenericLabel label; + if (accessLabels.containsKey(player.getName())) + label = accessLabels.get(player.getName()); + else + { + label = new GenericLabel(); + label.setWidth(1).setHeight(1); // prevent Spout's questionable new "no default size" warning + label.setScale(Conf.spoutTerritoryDisplaySize); + label.setY((int)(10 * Conf.spoutTerritoryDisplaySize)); + sPlayer.getMainScreen().attachWidget(P.p, label); + accessLabels.put(player.getName(), label); + } + + String msg = ""; + TerritoryAccess access = Board.getTerritoryAccessAt(here); + + if ( ! access.isDefault()) + { + if (access.subjectHasAccess(player)) + { + msg = "access granted"; + label.setTextColor(accessGrantedColor); + } + else if (access.subjectAccessIsRestricted(player)) + { + msg = "access restricted"; + label.setTextColor(accessDeniedColor); + } + } + + label.setText(msg); + alignLabel(label, msg); + label.setDirty(true); } // this is only necessary because Spout text size scaling is currently bugged and breaks their built-in alignment methods diff --git a/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java index 34467b03..db481d8d 100644 --- a/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -32,6 +32,7 @@ import com.massivecraft.factions.integration.SpoutFeatures; import com.massivecraft.factions.struct.FFlag; import com.massivecraft.factions.struct.FPerm; import com.massivecraft.factions.struct.Rel; +import com.massivecraft.factions.struct.TerritoryAccess; import com.massivecraft.factions.util.VisualizeUtil; @@ -81,22 +82,32 @@ public class FactionsPlayerListener implements Listener // Yes we did change coord (: me.setLastStoodAt(to); + TerritoryAccess access = Board.getTerritoryAccessAt(to); // Did we change "host"(faction)? - boolean changedFaction = (Board.getFactionAt(from) != Board.getFactionAt(to)); + boolean changedFaction = (Board.getFactionAt(from) != access.getHostFaction()); - if (changedFaction && SpoutFeatures.updateTerritoryDisplay(me)) - changedFaction = false; + // let Spout handle most of this if it's available + boolean handledBySpout = changedFaction && SpoutFeatures.updateTerritoryDisplay(me); if (me.isMapAutoUpdating()) { me.sendMessage(Board.getMap(me.getFaction(), to, player.getLocation().getYaw())); } - else if (changedFaction) + else if (changedFaction && ! handledBySpout) { me.sendFactionHereMessage(); } + // show access info message if needed + if ( ! handledBySpout && ! SpoutFeatures.updateAccessInfo(me) && ! access.isDefault()) + { + if (access.subjectHasAccess(me)) + me.msg("You have access to this area."); + else if (access.subjectAccessIsRestricted(me)) + me.msg("This area has restricted access."); + } + if (me.getAutoClaimFor() != null) { me.attemptClaim(me.getAutoClaimFor(), player.getLocation(), true); diff --git a/src/com/massivecraft/factions/struct/FPerm.java b/src/com/massivecraft/factions/struct/FPerm.java index 7140afca..797dd8dc 100644 --- a/src/com/massivecraft/factions/struct/FPerm.java +++ b/src/com/massivecraft/factions/struct/FPerm.java @@ -181,11 +181,10 @@ public enum FPerm public boolean has(Object testSubject, FLocation floc, boolean informIfNot) { TerritoryAccess access = Board.getTerritoryAccessAt(floc); - Faction factionThere = access.getHostFaction(); if (this.isTerritoryPerm()) { if (access.subjectHasAccess(testSubject)) return true; - if ( ! access.isHostFactionAllowed() && access.doesHostFactionMatch(testSubject) && ! FPerm.ACCESS.has(testSubject, factionThere)) + if (access.subjectAccessIsRestricted(testSubject)) { if (informIfNot) { @@ -200,7 +199,7 @@ public enum FPerm return false; } } - return this.has(testSubject, factionThere, informIfNot); + return this.has(testSubject, access.getHostFaction(), informIfNot); } public boolean has(Object testSubject, Location loc, boolean informIfNot) { diff --git a/src/com/massivecraft/factions/struct/TerritoryAccess.java b/src/com/massivecraft/factions/struct/TerritoryAccess.java index 6bace464..91c78aef 100644 --- a/src/com/massivecraft/factions/struct/TerritoryAccess.java +++ b/src/com/massivecraft/factions/struct/TerritoryAccess.java @@ -209,6 +209,12 @@ public class TerritoryAccess implements JsonDeserializer, JsonS return factionIDs.contains(factionID); } + // 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) && ! FPerm.ACCESS.has(testSubject, this.getHostFaction())); + } + //----------------------------------------------// // JSON Serialize/Deserialize Type Adapters