diff --git a/plugin.yml b/plugin.yml index 859bf2a..51b9626 100644 --- a/plugin.yml +++ b/plugin.yml @@ -48,6 +48,11 @@ commands: usage: /SubdivideClaims aliases: [sc, subdivideclaim] permission: griefprevention.claims + restrictsubclaim: + description: Restricts a subclaim, so that it inherits no permissions from the parent claim + usage: /restrictsubclaim + aliases: rsc + permission: griefprevention.claims adjustbonusclaimblocks: description: Adds or subtracts bonus claim blocks for a player. usage: /AdjustBonusClaimBlocks diff --git a/src/me/ryanhamshire/GriefPrevention/Claim.java b/src/me/ryanhamshire/GriefPrevention/Claim.java index 2884932..3ce4381 100644 --- a/src/me/ryanhamshire/GriefPrevention/Claim.java +++ b/src/me/ryanhamshire/GriefPrevention/Claim.java @@ -65,6 +65,9 @@ public class Claim //only used for claim subdivisions. top level claims have null here public Claim parent = null; + // intended for subclaims - they inherit no permissions + private boolean inheritNothing = false; + //children (subdivisions) //note subdivisions themselves never have children public ArrayList children = new ArrayList(); @@ -187,7 +190,7 @@ public class Claim } //main constructor. note that only creating a claim instance does nothing - a claim must be added to the data store to be effective - Claim(Location lesserBoundaryCorner, Location greaterBoundaryCorner, UUID ownerID, List builderIDs, List containerIDs, List accessorIDs, List managerIDs, Long id) + Claim(Location lesserBoundaryCorner, Location greaterBoundaryCorner, UUID ownerID, List builderIDs, List containerIDs, List accessorIDs, List managerIDs, boolean inheritNothing, Long id) { //modification date this.modifiedDate = Calendar.getInstance().getTime(); @@ -234,6 +237,13 @@ public class Claim this.managers.add(managerID); } } + + this.inheritNothing = inheritNothing; + } + + Claim(Location lesserBoundaryCorner, Location greaterBoundaryCorner, UUID ownerID, List builderIDs, List containerIDs, List accessorIDs, List managerIDs, Long id) + { + this(lesserBoundaryCorner, greaterBoundaryCorner, ownerID, builderIDs, containerIDs, accessorIDs, managerIDs, false, id); } //measurements. all measurements are in blocks @@ -254,7 +264,17 @@ public class Claim { return this.greaterBoundaryCorner.getBlockZ() - this.lesserBoundaryCorner.getBlockZ() + 1; } - + + public boolean getSubclaimRestrictions() + { + return inheritNothing; + } + + public void setSubclaimRestrictions(boolean inheritNothing) + { + this.inheritNothing = inheritNothing; + } + //distance check for claims, distance in this case is a band around the outside of the claim rather then euclidean distance public boolean isNear(Location location, int howNear) { @@ -301,7 +321,12 @@ public class Claim //permission inheritance for subdivisions if(this.parent != null) - return this.parent.allowEdit(player); + { + if (player.getUniqueId().equals(this.parent.ownerID)) + return null; + if (!inheritNothing) + return this.parent.allowEdit(player); + } //error message if all else fails return GriefPrevention.instance.dataStore.getMessage(Messages.OnlyOwnersModifyClaims, this.getOwnerName()); @@ -371,7 +396,12 @@ public class Claim //subdivision permission inheritance if(this.parent != null) - return this.parent.allowBuild(player, material); + { + if (player.getUniqueId().equals(this.parent.ownerID)) + return null; + if (!inheritNothing) + return this.parent.allowBuild(player, material); + } //failure message for all other cases String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPermission, this.getOwnerName()); @@ -471,7 +501,12 @@ public class Claim //permission inheritance for subdivisions if(this.parent != null) - return this.parent.allowAccess(player); + { + if (player.getUniqueId().equals(this.parent.ownerID)) + return null; + if (!inheritNothing) + return this.parent.allowAccess(player); + } //catch-all error message for all other cases String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoAccessPermission, this.getOwnerName()); @@ -514,7 +549,12 @@ public class Claim //permission inheritance for subdivisions if(this.parent != null) - return this.parent.allowContainers(player); + { + if (player.getUniqueId().equals(this.parent.ownerID)) + return null; + if (!inheritNothing) + return this.parent.allowContainers(player); + } //error message for all other cases String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersPermission, this.getOwnerName()); @@ -548,7 +588,12 @@ public class Claim //permission inheritance for subdivisions if(this.parent != null) - return this.parent.allowGrantPermission(player); + { + if (player.getUniqueId().equals(this.parent.ownerID)) + return null; + if (!inheritNothing) + return this.parent.allowGrantPermission(player); + } //generic error message String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoPermissionTrust, this.getOwnerName()); diff --git a/src/me/ryanhamshire/GriefPrevention/DataStore.java b/src/me/ryanhamshire/GriefPrevention/DataStore.java index a850151..56352ba 100644 --- a/src/me/ryanhamshire/GriefPrevention/DataStore.java +++ b/src/me/ryanhamshire/GriefPrevention/DataStore.java @@ -90,7 +90,7 @@ public abstract class DataStore final static String bannedWordsFilePath = dataLayerFolderPath + File.separator + "bannedWords.txt"; //the latest version of the data schema implemented here - protected static final int latestSchemaVersion = 2; + protected static final int latestSchemaVersion = 3; //reading and writing the schema version to the data store abstract int getSchemaVersionFromStorage(); @@ -1607,6 +1607,7 @@ public abstract class DataStore this.addDefault(defaults, Messages.Build, "Build", null); this.addDefault(defaults, Messages.Containers, "Containers", null); this.addDefault(defaults, Messages.Access, "Access", null); + this.addDefault(defaults, Messages.HasSubclaimRestriction, "This subclaim does not inherit permissions from the parent", null); this.addDefault(defaults, Messages.StartBlockMath, "{0} blocks from play + {1} bonus = {2} total.", null); this.addDefault(defaults, Messages.ClaimsListHeader, "Claims:", null); this.addDefault(defaults, Messages.ContinueBlockMath, " (-{0} blocks)", null); @@ -1637,7 +1638,11 @@ public abstract class DataStore this.addDefault(defaults, Messages.ConsoleOnlyCommand, "That command may only be executed from the server console.", null); this.addDefault(defaults, Messages.WorldNotFound, "World not found.", null); this.addDefault(defaults, Messages.TooMuchIpOverlap, "Sorry, there are too many players logged in with your IP address.", null); - + + this.addDefault(defaults, Messages.StandInSubclaim, "You need to be standing in a subclaim to restrict it", null); + this.addDefault(defaults, Messages.SubclaimRestricted, "This subclaim's permissions will no longer inherit from the parent claim", null); + this.addDefault(defaults, Messages.SubclaimUnrestricted, "This subclaim's permissions will now inherit from the parent claim", null); + //load the config file FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath)); diff --git a/src/me/ryanhamshire/GriefPrevention/DatabaseDataStore.java b/src/me/ryanhamshire/GriefPrevention/DatabaseDataStore.java index 6dbe6b6..78ab34d 100644 --- a/src/me/ryanhamshire/GriefPrevention/DatabaseDataStore.java +++ b/src/me/ryanhamshire/GriefPrevention/DatabaseDataStore.java @@ -79,7 +79,7 @@ public class DatabaseDataStore extends DataStore statement.execute("CREATE TABLE IF NOT EXISTS griefprevention_nextclaimid (nextid INT(15));"); - statement.execute("CREATE TABLE IF NOT EXISTS griefprevention_claimdata (id INT(15), owner VARCHAR(50), lessercorner VARCHAR(100), greatercorner VARCHAR(100), builders TEXT, containers TEXT, accessors TEXT, managers TEXT, parentid INT(15));"); + statement.execute("CREATE TABLE IF NOT EXISTS griefprevention_claimdata (id INT(15), owner VARCHAR(50), lessercorner VARCHAR(100), greatercorner VARCHAR(100), builders TEXT, containers TEXT, accessors TEXT, managers TEXT, inheritnothing BOOLEAN, parentid INT(15));"); statement.execute("CREATE TABLE IF NOT EXISTS griefprevention_playerdata (name VARCHAR(50), lastlogin DATETIME, accruedblocks INT(15), bonusblocks INT(15));"); @@ -224,6 +224,13 @@ public class DatabaseDataStore extends DataStore e.printStackTrace(); } } + + if(this.getSchemaVersion() <= 2) + { + statement = this.databaseConnection.createStatement(); + statement.execute("ALTER TABLE griefprevention_claimdata ADD inheritNothing BOOLEAN DEFAULT 0 AFTER managers;"); + } + //load claims data into memory results = statement.executeQuery("SELECT * FROM griefprevention_claimdata;"); @@ -237,22 +244,23 @@ public class DatabaseDataStore extends DataStore { try { - //problematic claims will be removed from secondary storage, and never added to in-memory data store - boolean removeClaim = false; + //problematic claims will be removed from secondary storage, and never added to in-memory data store + boolean removeClaim = false; - long parentId = results.getLong("parentid"); + long parentId = results.getLong("parentid"); claimID = results.getLong("id"); + boolean inheritNothing = results.getBoolean("inheritNothing"); Location lesserBoundaryCorner = null; Location greaterBoundaryCorner = null; String lesserCornerString = "(location not available)"; try { - lesserCornerString = results.getString("lessercorner"); - lesserBoundaryCorner = this.locationFromString(lesserCornerString, validWorlds); - - String greaterCornerString = results.getString("greatercorner"); - greaterBoundaryCorner = this.locationFromString(greaterCornerString, validWorlds); + lesserCornerString = results.getString("lessercorner"); + lesserBoundaryCorner = this.locationFromString(lesserCornerString, validWorlds); + + String greaterCornerString = results.getString("greatercorner"); + greaterBoundaryCorner = this.locationFromString(greaterCornerString, validWorlds); } catch(Exception e) { @@ -314,7 +322,7 @@ public class DatabaseDataStore extends DataStore List managerNames = Arrays.asList(managersString.split(";")); managerNames = this.convertNameListToUUIDList(managerNames); - Claim claim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerID, builderNames, containerNames, accessorNames, managerNames, claimID); + Claim claim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerID, builderNames, containerNames, accessorNames, managerNames, inheritNothing, claimID); if(removeClaim) { @@ -431,6 +439,8 @@ public class DatabaseDataStore extends DataStore managersString += managers.get(i) + ";"; } + boolean inheritNothing = claim.getSubclaimRestrictions(); + long parentId; if(claim.parent == null) { @@ -446,7 +456,7 @@ public class DatabaseDataStore extends DataStore this.refreshDataConnection(); Statement statement = databaseConnection.createStatement(); - statement.execute("INSERT INTO griefprevention_claimdata (id, owner, lessercorner, greatercorner, builders, containers, accessors, managers, parentid) VALUES(" + + statement.execute("INSERT INTO griefprevention_claimdata (id, owner, lessercorner, greatercorner, builders, containers, accessors, managers, inheritnothing, parentid) VALUES(" + claim.id + ", '" + owner + "', '" + lesserCornerString + "', '" + @@ -455,7 +465,8 @@ public class DatabaseDataStore extends DataStore containersString + "', '" + accessorsString + "', '" + managersString + "', " + - parentId + + inheritNothing + ", "+ + parentId + ");"); } catch(SQLException e) diff --git a/src/me/ryanhamshire/GriefPrevention/FlatFileDataStore.java b/src/me/ryanhamshire/GriefPrevention/FlatFileDataStore.java index a764dbf..8a46b4f 100644 --- a/src/me/ryanhamshire/GriefPrevention/FlatFileDataStore.java +++ b/src/me/ryanhamshire/GriefPrevention/FlatFileDataStore.java @@ -506,10 +506,12 @@ public class FlatFileDataStore extends DataStore List managers = yaml.getStringList("Managers"); + boolean inheritNothing = yaml.getBoolean("inheritNothing"); + out_parentID.add(yaml.getLong("Parent Claim ID", -1L)); //instantiate - claim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerID, builders, containers, accessors, managers, claimID); + claim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerID, builders, containers, accessors, managers, inheritNothing, claimID); claim.modifiedDate = new Date(lastModifiedDate); claim.id = claimID; @@ -548,6 +550,8 @@ public class FlatFileDataStore extends DataStore yaml.set("Parent Claim ID", parentID); + yaml.set("inheritNothing", claim.getSubclaimRestrictions()); + return yaml.saveToString(); } diff --git a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java index 0339130..f974d62 100644 --- a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java +++ b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java @@ -1502,6 +1502,11 @@ public class GriefPrevention extends JavaPlugin ChatColor.GREEN + this.dataStore.getMessage(Messages.Containers) + " " + ChatColor.BLUE + this.dataStore.getMessage(Messages.Access)); + if(claim.getSubclaimRestrictions()) + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.HasSubclaimRestriction); + } + return true; } @@ -1692,6 +1697,37 @@ public class GriefPrevention extends JavaPlugin return true; } + //restrictsubclaim + else if (cmd.getName().equalsIgnoreCase("restrictsubclaim") && player != null) + { + PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); + Claim claim = this.dataStore.getClaimAt(player.getLocation(), true, playerData.lastClaim); + if(claim == null || claim.parent == null) + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.StandInSubclaim); + return true; + } + + if(!player.getUniqueId().equals(claim.parent.ownerID)) + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.OnlyOwnersModifyClaims, claim.getOwnerName()); + return true; + } + + if(claim.getSubclaimRestrictions()) + { + claim.setSubclaimRestrictions(false); + GriefPrevention.sendMessage(player, TextMode.Success, Messages.SubclaimUnrestricted); + } + else + { + claim.setSubclaimRestrictions(true); + GriefPrevention.sendMessage(player, TextMode.Success, Messages.SubclaimRestricted); + } + this.dataStore.saveClaim(claim); + return true; + } + //buyclaimblocks else if(cmd.getName().equalsIgnoreCase("buyclaimblocks") && player != null) { diff --git a/src/me/ryanhamshire/GriefPrevention/Messages.java b/src/me/ryanhamshire/GriefPrevention/Messages.java index dcc02a7..c5422a7 100644 --- a/src/me/ryanhamshire/GriefPrevention/Messages.java +++ b/src/me/ryanhamshire/GriefPrevention/Messages.java @@ -216,6 +216,7 @@ public enum Messages Build, Containers, Access, + HasSubclaimRestriction, StartBlockMath, ClaimsListHeader, ContinueBlockMath, @@ -247,5 +248,8 @@ public enum Messages ConsoleOnlyCommand, WorldNotFound, AdjustBlocksAllSuccess, - TooMuchIpOverlap + TooMuchIpOverlap, + StandInSubclaim, + SubclaimRestricted, + SubclaimUnrestricted }