From 4460438365a4cf397a092331a29d7761aa611c76 Mon Sep 17 00:00:00 2001 From: Brettflan Date: Wed, 16 May 2012 15:29:00 -0500 Subject: [PATCH] Brief access info is now displayed under two circumstances: if you have been granted explicit access to the territory you are in ("access granted"), or if you are a normal member of the faction which owns the territory and access is denied to you ("access restricted"). This info will be displayed through Spout under the faction tag if possible, otherwise it will be displayed through chat. New conf.json setting: "spoutTerritoryAccessShow": true, - whether to show brief access info using Spout --- src/com/massivecraft/factions/Conf.java | 2 +- .../massivecraft/factions/cmd/CmdAccess.java | 5 +- .../factions/integration/SpoutFeatures.java | 21 ++++++ .../integration/SpoutMainListener.java | 70 ++++++++++++++++++- .../listeners/FactionsPlayerListener.java | 19 +++-- .../massivecraft/factions/struct/FPerm.java | 5 +- .../factions/struct/TerritoryAccess.java | 6 ++ 7 files changed, 117 insertions(+), 11 deletions(-) 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