Faction admins can now mark already claimed areas as owned by specific faction members. Ownership can include multiple members. New command /f owner *[player name], to set/remove ownership. This command is only available to the faction admin and optionally the faction moderators. If no player name is specified, it will either set ownership to the player running the command (if no owner is currently set) or completely clear ownership of the territory. New command /f ownerlist, to view a list of owners for the current area. Only works inside your own faction's territory. New conf.json options "ownedAreasEnabled", "ownedAreasModeratorsCanSet", "ownedAreaModeratorsBypass", "ownedAreaDenyBuild", "ownedAreaProtectMaterials", and "ownedAreaDenyUseage" (all defaulting to true) to determine whether faction moderators can set or bypass ownership (faction admin always can), and what sort of protection these owned areas have against normal members of the faction (members other than the owner(s), faction admin, and probably faction moderators). New conf.json option "ownedAreasLimitPerFaction" to limit how many owned areas can be set. New permission node "factions.ownershipBypass" which allows a player to bypass ownership protection, but only within the person's own faction.

various little tweaks and improvements to other code
moderate speed boost to FLocation code
made commandDisable permissions work for any command alias of a command, instead of just the first one
This commit is contained in:
Brettflan 2011-07-30 20:17:00 -05:00
parent 63ab41f933
commit 508f953ce9
16 changed files with 643 additions and 49 deletions

View File

@ -42,6 +42,8 @@ public class Board {
} }
public static void setIdAt(int id, FLocation flocation) { public static void setIdAt(int id, FLocation flocation) {
clearOwnershipAt(flocation);
if (id == 0) { if (id == 0) {
removeAt(flocation); removeAt(flocation);
} }
@ -54,10 +56,24 @@ public class Board {
} }
public static void removeAt(FLocation flocation) { public static void removeAt(FLocation flocation) {
clearOwnershipAt(flocation);
flocationIds.remove(flocation); flocationIds.remove(flocation);
} }
// not to be confused with claims, ownership referring to further member-specific ownership of a claim
public static void clearOwnershipAt(FLocation flocation) {
Faction faction = getFactionAt(flocation);
if (faction != null && faction.isNormal()) {
faction.clearClaimOwnership(flocation);
}
}
public static void unclaimAll(int factionId) { public static void unclaimAll(int factionId) {
Faction faction = Faction.get(factionId);
if (faction != null && faction.isNormal()) {
faction.clearAllClaimOwnership();
}
Iterator<Entry<FLocation, Integer>> iter = flocationIds.entrySet().iterator(); Iterator<Entry<FLocation, Integer>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
Entry<FLocation, Integer> entry = iter.next(); Entry<FLocation, Integer> entry = iter.next();
@ -215,10 +231,13 @@ public class Board {
public static Map<String,Map<String,Integer>> dumpAsSaveFormat() { public static Map<String,Map<String,Integer>> dumpAsSaveFormat() {
Map<String,Map<String,Integer>> worldCoordIds = new HashMap<String,Map<String,Integer>>(); Map<String,Map<String,Integer>> worldCoordIds = new HashMap<String,Map<String,Integer>>();
String worldName, coords;
Integer id;
for (Entry<FLocation, Integer> entry : flocationIds.entrySet()) { for (Entry<FLocation, Integer> entry : flocationIds.entrySet()) {
String worldName = entry.getKey().getWorldName(); worldName = entry.getKey().getWorldName();
String coords = entry.getKey().getCoordString(); coords = entry.getKey().getCoordString();
Integer id = entry.getValue(); id = entry.getValue();
if ( ! worldCoordIds.containsKey(worldName)) { if ( ! worldCoordIds.containsKey(worldName)) {
worldCoordIds.put(worldName, new TreeMap<String,Integer>()); worldCoordIds.put(worldName, new TreeMap<String,Integer>());
} }
@ -232,13 +251,17 @@ public class Board {
public static void loadFromSaveFormat(Map<String,Map<String,Integer>> worldCoordIds) { public static void loadFromSaveFormat(Map<String,Map<String,Integer>> worldCoordIds) {
flocationIds.clear(); flocationIds.clear();
String worldName;
String[] coords;
int x, z, factionId;
for (Entry<String,Map<String,Integer>> entry : worldCoordIds.entrySet()) { for (Entry<String,Map<String,Integer>> entry : worldCoordIds.entrySet()) {
String worldName = entry.getKey(); worldName = entry.getKey();
for (Entry<String,Integer> entry2 : entry.getValue().entrySet()) { for (Entry<String,Integer> entry2 : entry.getValue().entrySet()) {
String[] coords = entry2.getKey().trim().split("[,\\s]+"); coords = entry2.getKey().trim().split("[,\\s]+");
int x = Integer.parseInt(coords[0]); x = Integer.parseInt(coords[0]);
int z = Integer.parseInt(coords[1]); z = Integer.parseInt(coords[1]);
int factionId = entry2.getValue(); factionId = entry2.getValue();
flocationIds.put(new FLocation(worldName, x, z), factionId); flocationIds.put(new FLocation(worldName, x, z), factionId);
} }
} }

View File

@ -96,6 +96,15 @@ public class Conf {
public static boolean territoryBlockTNT = false; public static boolean territoryBlockTNT = false;
public static boolean territoryBlockTNTWhenOffline = false; public static boolean territoryBlockTNTWhenOffline = false;
// for claimed areas where further faction-member ownership can be defined
public static boolean ownedAreasEnabled = true;
public static int ownedAreasLimitPerFaction = 0;
public static boolean ownedAreasModeratorsCanSet = false;
public static boolean ownedAreaModeratorsBypass = true;
public static boolean ownedAreaDenyBuild = true;
public static boolean ownedAreaProtectMaterials = true;
public static boolean ownedAreaDenyUseage = true;
public static boolean safeZoneDenyBuild = true; public static boolean safeZoneDenyBuild = true;
public static boolean safeZoneDenyUseage = true; public static boolean safeZoneDenyUseage = true;
public static boolean safeZoneBlockTNT = true; public static boolean safeZoneBlockTNT = true;

View File

@ -14,7 +14,7 @@ public class FLocation {
private int x = 0; private int x = 0;
private int z = 0; private int z = 0;
private final static transient double cellSize = 16; // private final static transient double cellSize = 16;
//----------------------------------------------// //----------------------------------------------//
// Constructors // Constructors
@ -31,7 +31,9 @@ public class FLocation {
} }
public FLocation(Location location) { public FLocation(Location location) {
this(location.getWorld().getName(), (int) Math.floor(location.getX() / cellSize) , (int) Math.floor(location.getZ() / cellSize)); // this(location.getWorld().getName(), (int) Math.floor(location.getX() / cellSize) , (int) Math.floor(location.getZ() / cellSize));
// handy dandy rapid bitshifting instead of division
this(location.getWorld().getName(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
} }
public FLocation(Player player) { public FLocation(Player player) {
@ -107,6 +109,7 @@ public class FLocation {
// Comparison // Comparison
//----------------------------------------------// //----------------------------------------------//
@Override
public int hashCode() { public int hashCode() {
int hash = 3; int hash = 3;
hash = 19 * hash + (this.worldName != null ? this.worldName.hashCode() : 0); hash = 19 * hash + (this.worldName != null ? this.worldName.hashCode() : 0);

View File

@ -69,6 +69,11 @@ public class FPlayer {
} }
public void resetFactionData() { public void resetFactionData() {
// clean up any territory ownership in old faction, if there is one
if (this.factionId > 0 && Faction.exists(this.factionId)) {
Faction.get(factionId).clearClaimOwnership(playerName);
}
this.factionId = 0; // The default neutral faction this.factionId = 0; // The default neutral faction
this.factionChatting = false; this.factionChatting = false;
this.role = Role.NORMAL; this.role = Role.NORMAL;
@ -103,7 +108,7 @@ public class FPlayer {
return Faction.get(factionId); return Faction.get(factionId);
} }
private int getFactionId() { public int getFactionId() {
return factionId; return factionId;
} }

View File

@ -28,6 +28,7 @@ public class Faction {
private transient int id; private transient int id;
private Map<Integer, Relation> relationWish; private Map<Integer, Relation> relationWish;
private Map<FLocation, Set<String>> claimOwnership;
private Set<String> invites; // Where string is a lowercase player name private Set<String> invites; // Where string is a lowercase player name
private boolean open; private boolean open;
private String tag; private String tag;
@ -397,6 +398,152 @@ public class Faction {
return this.getRelation(fplayer).getColor(); return this.getRelation(fplayer).getColor();
} }
//----------------------------------------------//
// Ownership of specific claims
//----------------------------------------------//
private boolean isClaimOwnershipEmpty() {
if (claimOwnership == null) {
claimOwnership = new HashMap<FLocation, Set<String>>();
return true;
}
return claimOwnership.isEmpty();
}
public void clearAllClaimOwnership() {
claimOwnership.clear();
}
public void clearClaimOwnership(FLocation loc) {
claimOwnership.remove(loc);
}
public void clearClaimOwnership(String playerName) {
if (playerName == null || playerName.isEmpty()) {
return;
}
isClaimOwnershipEmpty();
Set<String> ownerData;
String player = playerName.toLowerCase();
for (Entry<FLocation, Set<String>> entry : claimOwnership.entrySet()) {
ownerData = entry.getValue();
if (ownerData == null) {
continue;
}
Iterator<String> iter = ownerData.iterator();
while (iter.hasNext()) {
if (iter.next().equals(player)) {
iter.remove();
}
}
if (ownerData.isEmpty()) {
claimOwnership.remove(entry.getKey());
}
}
}
public int getCountOfClaimsWithOwners() {
return isClaimOwnershipEmpty() ? 0 : claimOwnership.size();
}
public boolean doesLocationHaveOwnersSet(FLocation loc) {
if (isClaimOwnershipEmpty() || !claimOwnership.containsKey(loc)) {
return false;
}
Set<String> ownerData = claimOwnership.get(loc);
return ownerData != null && !ownerData.isEmpty();
}
public boolean isPlayerInOwnerList(String playerName, FLocation loc) {
if (isClaimOwnershipEmpty()) {
return false;
}
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return false;
}
if (ownerData.contains(playerName.toLowerCase())) {
return true;
}
return false;
}
public void setPlayerAsOwner(String playerName, FLocation loc) {
isClaimOwnershipEmpty();
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
ownerData = new HashSet<String>();
}
ownerData.add(playerName.toLowerCase());
claimOwnership.put(loc, ownerData);
}
public void removePlayerAsOwner(String playerName, FLocation loc) {
isClaimOwnershipEmpty();
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null) {
return;
}
ownerData.remove(playerName.toLowerCase());
claimOwnership.put(loc, ownerData);
}
public Set<String> getOwnerList(FLocation loc) {
isClaimOwnershipEmpty();
return claimOwnership.get(loc);
}
public String getOwnerListString(FLocation loc) {
isClaimOwnershipEmpty();
Set<String> ownerData = claimOwnership.get(loc);
if (ownerData == null || ownerData.isEmpty()) {
return "";
}
String ownerList = "";
Iterator<String> iter = ownerData.iterator();
while (iter.hasNext()) {
if (!ownerList.isEmpty()) {
ownerList += ", ";
}
ownerList += iter.next();
}
return ownerList;
}
public boolean playerHasOwnershipRights(FPlayer fplayer, FLocation loc) {
// different faction?
if (fplayer.getFactionId() != id) {
return false;
}
// sufficient role to bypass ownership?
if (fplayer.getRole() == (Conf.ownedAreaModeratorsBypass ? Role.MODERATOR : Role.ADMIN)) {
return true;
}
// make sure claimOwnership is initialized
if (isClaimOwnershipEmpty()) {
return true;
}
// need to check the ownership list, then
Set<String> ownerData = claimOwnership.get(loc);
// if no owner list, owner list is empty, or player is in owner list, they're allowed
if (ownerData == null || ownerData.isEmpty() || ownerData.contains(fplayer.getName().toLowerCase())) {
return true;
}
return false;
}
//----------------------------------------------// //----------------------------------------------//

View File

@ -2,10 +2,12 @@ package com.massivecraft.factions;
import java.io.File; import java.io.File;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -25,6 +27,8 @@ import com.massivecraft.factions.listeners.FactionsChatEarlyListener;
import com.massivecraft.factions.listeners.FactionsEntityListener; import com.massivecraft.factions.listeners.FactionsEntityListener;
import com.massivecraft.factions.listeners.FactionsPlayerListener; import com.massivecraft.factions.listeners.FactionsPlayerListener;
import com.massivecraft.factions.util.JarLoader; import com.massivecraft.factions.util.JarLoader;
import com.massivecraft.factions.util.MapFLocToStringSetTypeAdapter;
import com.massivecraft.factions.util.MyLocationTypeAdapter;
import com.nijiko.permissions.PermissionHandler; import com.nijiko.permissions.PermissionHandler;
import com.nijikokun.bukkit.Permissions.Permissions; import com.nijikokun.bukkit.Permissions.Permissions;
@ -32,6 +36,7 @@ import com.earth2me.essentials.chat.EssentialsChat;
import com.earth2me.essentials.chat.IEssentialsChatListener; import com.earth2me.essentials.chat.IEssentialsChatListener;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
/** /**
* The data is saved to disk every 30min and on plugin disable. * The data is saved to disk every 30min and on plugin disable.
@ -71,15 +76,18 @@ public class Factions extends JavaPlugin {
// Load the gson library we require // Load the gson library we require
File gsonfile = new File("./lib/gson.jar"); File gsonfile = new File("./lib/gson.jar");
if ( ! JarLoader.load(gsonfile)) { if ( ! JarLoader.load(gsonfile)) {
log(Level.SEVERE, "Disabling myself as "+gsonfile+" is missing."); log(Level.SEVERE, "Disabling myself as "+gsonfile.getPath()+" is missing from the root Minecraft server folder.");
this.getServer().getPluginManager().disablePlugin(this); this.getServer().getPluginManager().disablePlugin(this);
return; return;
} }
Type mapFLocToStringSetType = new TypeToken<Map<FLocation, Set<String>>>(){}.getType();
gson = new GsonBuilder() gson = new GsonBuilder()
.setPrettyPrinting() .setPrettyPrinting()
.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE) .excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE)
.registerTypeAdapter(Location.class, new MyLocationTypeAdapter()) .registerTypeAdapter(Location.class, new MyLocationTypeAdapter())
.registerTypeAdapter(mapFLocToStringSetType, new MapFLocToStringSetTypeAdapter())
.create(); .create();
// Add the commands // Add the commands
@ -106,6 +114,8 @@ public class Factions extends JavaPlugin {
commands.add(new FCommandMap()); commands.add(new FCommandMap());
commands.add(new FCommandMod()); commands.add(new FCommandMod());
commands.add(new FCommandOpen()); commands.add(new FCommandOpen());
commands.add(new FCommandOwner());
commands.add(new FCommandOwnerList());
commands.add(new FCommandPower()); commands.add(new FCommandPower());
commands.add(new FCommandRelationAlly()); commands.add(new FCommandRelationAlly());
commands.add(new FCommandRelationEnemy()); commands.add(new FCommandRelationEnemy());
@ -137,8 +147,6 @@ public class Factions extends JavaPlugin {
setupPermissions(); setupPermissions();
integrateEssentialsChat(); integrateEssentialsChat();
// preload could apparently cause issues; removed since "softdepend" is now available
// Register events // Register events
PluginManager pm = this.getServer().getPluginManager(); PluginManager pm = this.getServer().getPluginManager();
pm.registerEvent(Event.Type.PLAYER_CHAT, this.playerListener, Event.Priority.Highest, this); pm.registerEvent(Event.Type.PLAYER_CHAT, this.playerListener, Event.Priority.Highest, this);
@ -177,7 +185,9 @@ public class Factions extends JavaPlugin {
this.getServer().getScheduler().cancelTask(saveTask); this.getServer().getScheduler().cancelTask(saveTask);
saveTask = null; saveTask = null;
} }
saveAll(); if (gson != null) {
saveAll();
}
unhookEssentialsChat(); unhookEssentialsChat();
} }
@ -369,6 +379,10 @@ public class Factions extends JavaPlugin {
return hasPerm(sender, "factions.viewAnyPower"); return hasPerm(sender, "factions.viewAnyPower");
} }
public static boolean hasPermOwnershipBypass(CommandSender sender) {
return hasPerm(sender, "factions.ownershipBypass");
}
public static boolean isCommandDisabled(CommandSender sender, String command) { public static boolean isCommandDisabled(CommandSender sender, String command) {
return (hasPerm(sender, "factions.commandDisable."+command) && !hasPerm(sender, "factions.commandDisable.none")); return (hasPerm(sender, "factions.commandDisable."+command) && !hasPerm(sender, "factions.commandDisable.none"));
} }

View File

@ -2,6 +2,7 @@ package com.massivecraft.factions.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -89,9 +90,12 @@ public class FBaseCommand {
} }
// make sure player doesn't have their access to the command revoked // make sure player doesn't have their access to the command revoked
if (Factions.isCommandDisabled(sender, aliases.get(0))) { Iterator<String> iter = aliases.iterator();
sendMessage("You lack the permissions to "+this.helpDescription.toLowerCase()+"."); while (iter.hasNext()) {
return false; if (Factions.isCommandDisabled(sender, iter.next())) {
sendMessage("You lack the permissions to "+this.helpDescription.toLowerCase()+".");
return false;
}
} }
if (parameters.size() < requiredParameters.size()) { if (parameters.size() < requiredParameters.size()) {

View File

@ -92,10 +92,22 @@ public class FCommandHelp extends FBaseCommand {
pageLines = new ArrayList<String>(); pageLines = new ArrayList<String>();
pageLines.add( new FCommandMap().getUseageTemplate() ); pageLines.add( new FCommandMap().getUseageTemplate() );
pageLines.add("");
pageLines.add("");
pageLines.add( new FCommandOwner().getUseageTemplate() );
pageLines.add( new FCommandOwnerList().getUseageTemplate() );
pageLines.add("");
pageLines.add("Claimed land with ownership set is further protected so");
pageLines.add("that only the owner(s), faction admin, and possibly the");
pageLines.add("faction moderators have full access.");
helpPages.add(pageLines);
pageLines = new ArrayList<String>();
pageLines.add( new FCommandRelationAlly().getUseageTemplate() ); pageLines.add( new FCommandRelationAlly().getUseageTemplate() );
pageLines.add( new FCommandRelationNeutral().getUseageTemplate() ); pageLines.add( new FCommandRelationNeutral().getUseageTemplate() );
pageLines.add( new FCommandRelationEnemy().getUseageTemplate() ); pageLines.add( new FCommandRelationEnemy().getUseageTemplate() );
pageLines.add(""); pageLines.add("");
pageLines.add("");
pageLines.add("Set the relation you WISH to have with another faction."); pageLines.add("Set the relation you WISH to have with another faction.");
pageLines.add("Your default relation with other factions will be neutral."); pageLines.add("Your default relation with other factions will be neutral.");
pageLines.add("If BOTH factions choose \"ally\" you will be allies."); pageLines.add("If BOTH factions choose \"ally\" you will be allies.");

View File

@ -0,0 +1,100 @@
package com.massivecraft.factions.commands;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.struct.Role;
public class FCommandOwner extends FBaseCommand {
public FCommandOwner() {
aliases.add("owner");
optionalParameters.add("player name");
helpDescription = "set ownership of claimed land";
}
@Override
public void perform() {
boolean hasBypass = Factions.hasPermAdminBypass(player);
if ( ! hasBypass && ! assertHasFaction()) {
return;
}
if( isLocked() ) {
sendLockMessage();
return;
}
if ( ! Conf.ownedAreasEnabled) {
me.sendMessage("Sorry, but owned areas are disabled on this server.");
return;
}
Faction myFaction = me.getFaction();
if (!hasBypass && Conf.ownedAreasLimitPerFaction > 0 && myFaction.getCountOfClaimsWithOwners() >= Conf.ownedAreasLimitPerFaction) {
me.sendMessage("Sorry, but you have reached the server's limit of "+Conf.ownedAreasLimitPerFaction+" owned areas per faction.");
return;
}
if (!hasBypass && !assertMinRole(Conf.ownedAreasModeratorsCanSet ? Role.MODERATOR : Role.ADMIN)) {
return;
}
FLocation flocation = new FLocation(me);
if (Board.getIdAt(flocation) != myFaction.getId()) {
if (!hasBypass) {
me.sendMessage("This land is not claimed by your faction, so you can't set ownership of it.");
return;
}
myFaction = Board.getFactionAt(flocation);
if (!myFaction.isNormal()) {
me.sendMessage("This land is not claimed by a faction. Ownership is not possible.");
return;
}
}
FPlayer target;
if (parameters.size() > 0) {
target = findFPlayer(parameters.get(0), false);
} else {
target = me;
}
if (target == null) {
return;
}
String playerName = target.getName();
if (target.getFaction().getId() != myFaction.getId()) {
me.sendMessage(playerName + " is not a member of this faction.");
return;
}
// if no player name was passed, and this claim does already have owners set, clear them
if (parameters.isEmpty() && myFaction.doesLocationHaveOwnersSet(flocation)) {
myFaction.clearClaimOwnership(flocation);
me.sendMessage("You have cleared ownership for this claimed area.");
return;
}
if (myFaction.isPlayerInOwnerList(playerName, flocation)) {
myFaction.removePlayerAsOwner(playerName, flocation);
me.sendMessage("You have removed ownership of this claimed land from "+playerName+".");
return;
}
myFaction.setPlayerAsOwner(playerName, flocation);
me.sendMessage("You have added "+playerName+" to the owner list for this claimed land.");
}
}

View File

@ -0,0 +1,59 @@
package com.massivecraft.factions.commands;
import java.util.Set;
import java.util.Iterator;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.Factions;
public class FCommandOwnerList extends FBaseCommand {
public FCommandOwnerList() {
aliases.add("ownerlist");
helpDescription = "list owner(s) of this claimed land";
}
@Override
public void perform() {
boolean hasBypass = Factions.hasPermAdminBypass(player);
if ( ! hasBypass && ! assertHasFaction()) {
return;
}
if ( ! Conf.ownedAreasEnabled) {
me.sendMessage("Owned areas are disabled on this server.");
return;
}
Faction myFaction = me.getFaction();
FLocation flocation = new FLocation(me);
if (Board.getIdAt(flocation) != myFaction.getId()) {
if (!hasBypass) {
me.sendMessage("This land is not claimed by your faction.");
return;
}
myFaction = Board.getFactionAt(flocation);
if (!myFaction.isNormal()) {
me.sendMessage("This land is not claimed by any faction, thus no owners.");
return;
}
}
String owners = myFaction.getOwnerListString(flocation);
if (owners == null || owners.isEmpty()) {
me.sendMessage("No owners are set here; everyone in the faction has access.");
return;
}
me.sendMessage("Current owner(s) of this land: "+owners);
}
}

View File

@ -153,10 +153,10 @@ public class FactionsBlockListener extends BlockListener {
return true; return true;
} }
Faction otherFaction = Board.getFactionAt(new FLocation(block)); FLocation loc = new FLocation(block);
Faction otherFaction = Board.getFactionAt(loc);
FPlayer me = FPlayer.get(player); FPlayer me = FPlayer.get(player);
if (otherFaction.isNone()) { if (otherFaction.isNone()) {
if (!Conf.wildernessDenyBuild || Factions.hasPermAdminBypass(player)) { if (!Conf.wildernessDenyBuild || Factions.hasPermAdminBypass(player)) {
return true; // This is not faction territory. Use whatever you like here. return true; // This is not faction territory. Use whatever you like here.
@ -193,6 +193,16 @@ public class FactionsBlockListener extends BlockListener {
return false; return false;
} }
} }
// Also cancel if player doesn't have ownership rights for this claim
else if (
Conf.ownedAreasEnabled
&& Conf.ownedAreaDenyBuild
&& !myFaction.playerHasOwnershipRights(me, loc)
&& !Factions.hasPermOwnershipBypass(player)
) {
me.sendMessage("You can't "+action+" in this territory, it is owned by: "+myFaction.getOwnerListString(loc));
return false;
}
return true; return true;
} }

View File

@ -311,7 +311,6 @@ public class FactionsEntityListener extends EntityListener {
} }
Faction otherFaction = Board.getFactionAt(loc); Faction otherFaction = Board.getFactionAt(loc);
FPlayer me = FPlayer.get(player); FPlayer me = FPlayer.get(player);
if (otherFaction.isNone()) { if (otherFaction.isNone()) {
@ -351,6 +350,16 @@ public class FactionsEntityListener extends EntityListener {
return false; return false;
} }
} }
// Also cancel if player doesn't have ownership rights for this claim
else if (
Conf.ownedAreasEnabled
&& Conf.ownedAreaDenyBuild
&& !myFaction.playerHasOwnershipRights(me, loc)
&& !Factions.hasPermOwnershipBypass(player)
) {
me.sendMessage("You can't "+action+" paintings in this territory, it is owned by: "+myFaction.getOwnerListString(loc));
return false;
}
return true; return true;
} }

View File

@ -123,16 +123,20 @@ public class FactionsPlayerListener extends PlayerListener{
// Make sure player's power is up to date when they log off. // Make sure player's power is up to date when they log off.
FPlayer me = FPlayer.get(event.getPlayer()); FPlayer me = FPlayer.get(event.getPlayer());
me.getPower(); me.getPower();
me.getFaction().memberLoggedOff(); Faction myFaction = me.getFaction();
if (myFaction != null) {
myFaction.memberLoggedOff();
}
} }
@Override @Override
public void onPlayerMove(PlayerMoveEvent event) { public void onPlayerMove(PlayerMoveEvent event) {
FPlayer me = FPlayer.get(event.getPlayer()); Player player = event.getPlayer();
FPlayer me = FPlayer.get(player);
// Did we change coord? // Did we change coord?
FLocation from = me.getLastStoodAt(); FLocation from = me.getLastStoodAt();
FLocation to = new FLocation(event.getPlayer().getLocation()); FLocation to = new FLocation(player.getLocation());
if (from.equals(to)) { if (from.equals(to)) {
return; return;
@ -143,7 +147,7 @@ public class FactionsPlayerListener extends PlayerListener{
me.setLastStoodAt(to); me.setLastStoodAt(to);
if (me.isMapAutoUpdating()) { if (me.isMapAutoUpdating()) {
me.sendMessage(Board.getMap(me.getFaction(), to, me.getPlayer().getLocation().getYaw())); me.sendMessage(Board.getMap(me.getFaction(), to, player.getLocation().getYaw()));
} else { } else {
// Did we change "host"(faction)? // Did we change "host"(faction)?
Faction factionFrom = Board.getFactionAt(from); Faction factionFrom = Board.getFactionAt(from);
@ -173,7 +177,7 @@ public class FactionsPlayerListener extends PlayerListener{
me.attemptClaim(false); me.attemptClaim(false);
} }
else if (me.autoSafeZoneEnabled()) { else if (me.autoSafeZoneEnabled()) {
if (!Factions.hasPermManageSafeZone((CommandSender)event.getPlayer())) { if (!Factions.hasPermManageSafeZone((CommandSender)player)) {
me.enableAutoSafeZone(false); me.enableAutoSafeZone(false);
} else { } else {
FLocation playerFlocation = new FLocation(me); FLocation playerFlocation = new FLocation(me);
@ -185,7 +189,7 @@ public class FactionsPlayerListener extends PlayerListener{
} }
} }
else if (me.autoWarZoneEnabled()) { else if (me.autoWarZoneEnabled()) {
if (!Factions.hasPermManageWarZone((CommandSender)event.getPlayer())) { if (!Factions.hasPermManageWarZone((CommandSender)player)) {
me.enableAutoWarZone(false); me.enableAutoWarZone(false);
} else { } else {
FLocation playerFlocation = new FLocation(me); FLocation playerFlocation = new FLocation(me);
@ -232,7 +236,8 @@ public class FactionsPlayerListener extends PlayerListener{
return true; return true;
} }
Faction otherFaction = Board.getFactionAt(new FLocation(block)); FLocation loc = new FLocation(block);
Faction otherFaction = Board.getFactionAt(loc);
if (otherFaction.hasPlayersOnline()){ if (otherFaction.hasPlayersOnline()){
if ( ! Conf.territoryDenyUseageMaterials.contains(material)) { if ( ! Conf.territoryDenyUseageMaterials.contains(material)) {
@ -272,8 +277,20 @@ public class FactionsPlayerListener extends PlayerListener{
boolean areEnemies = myFaction.getRelation(otherFaction).isEnemy(); boolean areEnemies = myFaction.getRelation(otherFaction).isEnemy();
// Cancel if we are not in our own territory // Cancel if we are not in our own territory
if (myFaction != otherFaction && (areEnemies ? Conf.territoryEnemyDenyUseage : Conf.territoryDenyUseage)) { if (myFaction != otherFaction) {
me.sendMessage("You can't use "+TextUtil.getMaterialName(material)+" in the territory of "+otherFaction.getTag(myFaction)); if (areEnemies ? Conf.territoryEnemyDenyUseage : Conf.territoryDenyUseage) {
me.sendMessage("You can't use "+TextUtil.getMaterialName(material)+" in the territory of "+otherFaction.getTag(myFaction));
return false;
}
}
// Also cancel if player doesn't have ownership rights for this claim
else if (
Conf.ownedAreasEnabled
&& Conf.ownedAreaDenyUseage
&& !myFaction.playerHasOwnershipRights(me, loc)
&& !Factions.hasPermOwnershipBypass(player)
) {
me.sendMessage("You can't use "+TextUtil.getMaterialName(material)+" in this territory, it is owned by: "+myFaction.getOwnerListString(loc));
return false; return false;
} }
@ -287,8 +304,8 @@ public class FactionsPlayerListener extends PlayerListener{
} }
Material material = block.getType(); Material material = block.getType();
FLocation loc = new FLocation(block);
Faction otherFaction = Board.getFactionAt(new FLocation(block)); Faction otherFaction = Board.getFactionAt(loc);
// We only care about some material types. // We only care about some material types.
if (otherFaction.hasPlayersOnline()){ if (otherFaction.hasPlayersOnline()){
@ -313,6 +330,17 @@ public class FactionsPlayerListener extends PlayerListener{
me.sendMessage("You can't use "+TextUtil.getMaterialName(material)+" in the territory of "+otherFaction.getTag(myFaction)); me.sendMessage("You can't use "+TextUtil.getMaterialName(material)+" in the territory of "+otherFaction.getTag(myFaction));
return false; return false;
} }
// Also cancel if player doesn't have ownership rights for this claim
else if (
myFaction == otherFaction
&& Conf.ownedAreasEnabled
&& Conf.ownedAreaProtectMaterials
&& !myFaction.playerHasOwnershipRights(me, loc)
&& !Factions.hasPermOwnershipBypass(player)
) {
me.sendMessage("You can't use "+TextUtil.getMaterialName(material)+" in this territory, it is owned by: "+myFaction.getOwnerListString(loc));
return false;
}
return true; return true;
} }

View File

@ -0,0 +1,112 @@
package com.massivecraft.factions.util;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.Map.Entry;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.Factions;
public class MapFLocToStringSetTypeAdapter implements JsonDeserializer<Map<FLocation, Set<String>>>, JsonSerializer<Map<FLocation, Set<String>>> {
@Override
public Map<FLocation, Set<String>> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
JsonObject obj = json.getAsJsonObject();
if (obj == null) {
return null;
}
Map<FLocation, Set<String>> locationMap = new HashMap<FLocation, Set<String>>();
Set<String> nameSet;
Iterator<JsonElement> iter;
String worldName;
String[] coords;
int x, z;
for (Entry<String, JsonElement> entry : obj.entrySet()) {
worldName = entry.getKey();
for (Entry<String, JsonElement> entry2 : entry.getValue().getAsJsonObject().entrySet()) {
coords = entry2.getKey().trim().split("[,\\s]+");
x = Integer.parseInt(coords[0]);
z = Integer.parseInt(coords[1]);
nameSet = new HashSet<String>();
iter = entry2.getValue().getAsJsonArray().iterator();
while (iter.hasNext()) {
nameSet.add(iter.next().getAsString());
}
locationMap.put(new FLocation(worldName, x, z), nameSet);
}
}
return locationMap;
} catch (Exception ex) {
ex.printStackTrace();
Factions.log(Level.WARNING, "Error encountered while deserializing a Map of FLocations to String Sets.");
return null;
}
}
@Override
public JsonElement serialize(Map<FLocation, Set<String>> src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
try {
if (src != null) {
FLocation loc;
String locWorld;
Set<String> nameSet;
Iterator<String> iter;
JsonArray nameArray;
JsonPrimitive nameElement;
for (Entry<FLocation, Set<String>> entry : src.entrySet()) {
loc = entry.getKey();
locWorld = loc.getWorldName();
nameSet = entry.getValue();
if (nameSet == null || nameSet.isEmpty()) {
continue;
}
nameArray = new JsonArray();
iter = nameSet.iterator();
while (iter.hasNext()) {
nameElement = new JsonPrimitive(iter.next());
nameArray.add(nameElement);
}
if ( ! obj.has(locWorld)) {
obj.add(locWorld, new JsonObject());
}
obj.get(locWorld).getAsJsonObject().add(loc.getCoordString(), nameArray);
}
}
return obj;
} catch (Exception ex) {
ex.printStackTrace();
Factions.log(Level.WARNING, "Error encountered while serializing a Map of FLocations to String Sets.");
return obj;
}
}
}

View File

@ -1,4 +1,4 @@
package com.massivecraft.factions; package com.massivecraft.factions.util;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.logging.Level; import java.util.logging.Level;
@ -13,6 +13,7 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer; import com.google.gson.JsonSerializer;
import com.massivecraft.factions.Factions;
public class MyLocationTypeAdapter implements JsonDeserializer<Location>, JsonSerializer<Location> { public class MyLocationTypeAdapter implements JsonDeserializer<Location>, JsonSerializer<Location> {

View File

@ -19,16 +19,17 @@ permissions:
factions.participate: true factions.participate: true
factions.create: true factions.create: true
factions.viewAnyPower: true factions.viewAnyPower: true
factions.adminBypass: true
factions.config: true
factions.disband: true
factions.lock: true
factions.manageSafeZone: true factions.manageSafeZone: true
factions.manageWarZone: true factions.manageWarZone: true
factions.adminBypass: true factions.ownershipBypass: true
factions.reload: true factions.reload: true
factions.saveall: true factions.saveall: true
factions.lock: true
factions.disband: true
factions.worldOptions: true factions.worldOptions: true
factions.commandDisable.none: true factions.commandDisable.none: true
factions.config: true
factions.participate: factions.participate:
description: Allows the player to participate in a faction description: Allows the player to participate in a faction
default: true default: true
@ -38,14 +39,26 @@ permissions:
factions.viewAnyPower: factions.viewAnyPower:
description: Allows the player to view the power level of anyone else description: Allows the player to view the power level of anyone else
default: true default: true
factions.adminBypass:
description: Allows the player to bypass many normal restrictions, and use the bypass command
default: op
factions.config:
description: Can use /f config command to change conf.json options
default: op
factions.disband:
description: Can use the /f disband <faction> command to disband any faction
default: op
factions.lock:
description: Can use the /f lock [on/off] command to temporarily lock the data files from being overwritten
default: op
factions.manageSafeZone: factions.manageSafeZone:
description: Allows the player to claim land as a safe zone, and to build/destroy within safe zones description: Allows the player to claim land as a safe zone, and to build/destroy within safe zones
default: op default: op
factions.manageWarZone: factions.manageWarZone:
description: Allows the player to claim land as a war zone, and to build/destroy within war zones description: Allows the player to claim land as a war zone, and to build/destroy within war zones
default: op default: op
factions.adminBypass: factions.ownershipBypass:
description: Allows the player to bypass many normal restrictions, and use the bypass command description: Allows the player to bypass ownership restrictions within own faction's territory
default: op default: op
factions.reload: factions.reload:
description: Can use the /f reload command to reload data file(s) from disk description: Can use the /f reload command to reload data file(s) from disk
@ -53,18 +66,9 @@ permissions:
factions.saveall: factions.saveall:
description: Can use the /f saveall command to save all data to disk description: Can use the /f saveall command to save all data to disk
default: op default: op
factions.lock:
description: Can use the /f lock [on/off] command to temporarily lock the data files from being overwritten
default: op
factions.disband:
description: Can use the /f disband <faction> command to disband any faction
default: op
factions.worldOptions: factions.worldOptions:
description: Can use the /f worldnoclaim and /f worldnopowerloss commands description: Can use the /f worldnoclaim and /f worldnopowerloss commands
default: op default: op
factions.config:
description: Can use /f config command to change conf.json options
default: op
factions.commandDisable.none: factions.commandDisable.none:
description: no commands disabled (ignore all other commandDisable permissions) description: no commands disabled (ignore all other commandDisable permissions)
default: op default: op
@ -86,6 +90,9 @@ permissions:
factions.commandDisable.chat: factions.commandDisable.chat:
description: chat command disabled description: chat command disabled
default: false default: false
factions.commandDisable.c:
description: chat command disabled
default: false
factions.commandDisable.claim: factions.commandDisable.claim:
description: claim command disabled description: claim command disabled
default: false default: false
@ -95,6 +102,9 @@ permissions:
factions.commandDisable.deinvite: factions.commandDisable.deinvite:
description: deinvite command disabled description: deinvite command disabled
default: false default: false
factions.commandDisable.deinv:
description: deinvite command disabled
default: false
factions.commandDisable.desc: factions.commandDisable.desc:
description: desc command disabled description: desc command disabled
default: false default: false
@ -104,12 +114,21 @@ permissions:
factions.commandDisable.help: factions.commandDisable.help:
description: help command disabled description: help command disabled
default: false default: false
factions.commandDisable.h:
description: help command disabled
default: false
factions.commandDisable.?:
description: help command disabled
default: false
factions.commandDisable.home: factions.commandDisable.home:
description: home command disabled description: home command disabled
default: false default: false
factions.commandDisable.invite: factions.commandDisable.invite:
description: invite command disabled description: invite command disabled
default: false default: false
factions.commandDisable.inv:
description: invite command disabled
default: false
factions.commandDisable.join: factions.commandDisable.join:
description: join command disabled description: join command disabled
default: false default: false
@ -122,6 +141,9 @@ permissions:
factions.commandDisable.list: factions.commandDisable.list:
description: list command disabled description: list command disabled
default: false default: false
factions.commandDisable.ls:
description: list command disabled
default: false
factions.commandDisable.lock: factions.commandDisable.lock:
description: lock command disabled description: lock command disabled
default: false default: false
@ -134,9 +156,21 @@ permissions:
factions.commandDisable.open: factions.commandDisable.open:
description: open command disabled description: open command disabled
default: false default: false
factions.commandDisable.close:
description: open command disabled
default: false
factions.commandDisable.owner:
description: owner command disabled
default: false
factions.commandDisable.ownerlist:
description: ownerlist command disabled
default: false
factions.commandDisable.power: factions.commandDisable.power:
description: power command disabled description: power command disabled
default: false default: false
factions.commandDisable.pow:
description: power command disabled
default: false
factions.commandDisable.ally: factions.commandDisable.ally:
description: ally command disabled description: ally command disabled
default: false default: false
@ -152,18 +186,30 @@ permissions:
factions.commandDisable.safeclaim: factions.commandDisable.safeclaim:
description: safeclaim command disabled description: safeclaim command disabled
default: false default: false
factions.commandDisable.safe:
description: safeclaim command disabled
default: false
factions.commandDisable.safeunclaimall: factions.commandDisable.safeunclaimall:
description: safeunclaimall command disabled description: safeunclaimall command disabled
default: false default: false
factions.commandDisable.safedeclaimall:
description: safeunclaimall command disabled
default: false
factions.commandDisable.saveall: factions.commandDisable.saveall:
description: saveall command disabled description: saveall command disabled
default: false default: false
factions.commandDisable.save:
description: saveall command disabled
default: false
factions.commandDisable.sethome: factions.commandDisable.sethome:
description: sethome command disabled description: sethome command disabled
default: false default: false
factions.commandDisable.show: factions.commandDisable.show:
description: show command disabled description: show command disabled
default: false default: false
factions.commandDisable.who:
description: show command disabled
default: false
factions.commandDisable.tag: factions.commandDisable.tag:
description: tag command disabled description: tag command disabled
default: false default: false
@ -173,18 +219,30 @@ permissions:
factions.commandDisable.unclaim: factions.commandDisable.unclaim:
description: unclaim command disabled description: unclaim command disabled
default: false default: false
factions.commandDisable.declaim:
description: unclaim command disabled
default: false
factions.commandDisable.unclaimall: factions.commandDisable.unclaimall:
description: unclaimall command disabled description: unclaimall command disabled
default: false default: false
factions.commandDisable.declaimall:
description: unclaimall command disabled
default: false
factions.commandDisable.version: factions.commandDisable.version:
description: version command disabled description: version command disabled
default: false default: false
factions.commandDisable.warclaim: factions.commandDisable.warclaim:
description: warclaim command disabled description: warclaim command disabled
default: false default: false
factions.commandDisable.war:
description: warclaim command disabled
default: false
factions.commandDisable.warunclaimall: factions.commandDisable.warunclaimall:
description: warunclaimall command disabled description: warunclaimall command disabled
default: false default: false
factions.commandDisable.wardeclaimall:
description: warunclaimall command disabled
default: false
factions.commandDisable.worldnoclaim: factions.commandDisable.worldnoclaim:
description: worldnoclaim command disabled description: worldnoclaim command disabled
default: false default: false