diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimPreTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimPreTask.java index 93eace3..e828633 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimPreTask.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimPreTask.java @@ -21,31 +21,33 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import java.util.UUID; + //asynchronously loads player data without caching it in the datastore, then //passes those data to a claim cleanup task which might decide to delete a claim for inactivity class CleanupUnusedClaimPreTask implements Runnable { - private Claim claim = null; + private UUID ownerID = null; - CleanupUnusedClaimPreTask(Claim claim) + CleanupUnusedClaimPreTask(UUID uuid) { - this.claim = claim; + this.ownerID = uuid; } @Override public void run() { //get the data - PlayerData ownerData = GriefPrevention.instance.dataStore.getPlayerDataFromStorage(claim.ownerID); - OfflinePlayer ownerInfo = Bukkit.getServer().getOfflinePlayer(claim.ownerID); + PlayerData ownerData = GriefPrevention.instance.dataStore.getPlayerDataFromStorage(ownerID); + OfflinePlayer ownerInfo = Bukkit.getServer().getOfflinePlayer(ownerID); //expiration code uses last logout timestamp to decide whether to expire claims //don't expire claims for online players if(ownerInfo.isOnline()) return; if(ownerInfo.getLastPlayed() <= 0) return; - GriefPrevention.AddLogEntry("Looking for expired claims. Checking data for " + claim.ownerID.toString(), CustomLogEntryTypes.Debug, true); + GriefPrevention.AddLogEntry("Looking for expired claims. Checking data for " + ownerID.toString(), CustomLogEntryTypes.Debug, true); //skip claims belonging to exempted players based on block totals in config int bonusBlocks = ownerData.getBonusClaimBlocks(); @@ -54,8 +56,25 @@ class CleanupUnusedClaimPreTask implements Runnable GriefPrevention.AddLogEntry("Player exempt from claim expiration based on claim block counts vs. config file settings.", CustomLogEntryTypes.Debug, true); return; } - + + Claim claimToExpire = null; + + for (Claim claim : GriefPrevention.instance.dataStore.getClaims()) + { + if (claim.ownerID.equals(ownerID)) + { + claimToExpire = claim; + break; + } + } + + if (claimToExpire == null) + { + GriefPrevention.AddLogEntry("Unable to find a claim to expire for " + ownerID.toString(), CustomLogEntryTypes.Debug, false); + return; + } + //pass it back to the main server thread, where it's safe to delete a claim if needed - Bukkit.getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, new CleanupUnusedClaimTask(claim, ownerData, ownerInfo), 1L); + Bukkit.getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, new CleanupUnusedClaimTask(claimToExpire, ownerData, ownerInfo), 1L); } } \ No newline at end of file diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/FindUnusedClaimsTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/FindUnusedClaimsTask.java index c1135b0..c1fbfc8 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/FindUnusedClaimsTask.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/FindUnusedClaimsTask.java @@ -18,7 +18,10 @@ package me.ryanhamshire.GriefPrevention; -import java.util.Random; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.UUID; import org.bukkit.Bukkit; @@ -29,38 +32,36 @@ import org.bukkit.Bukkit; //runs every 1 minute in the main thread class FindUnusedClaimsTask implements Runnable -{ - int nextClaimIndex; +{ + private Set claimOwnerUUIDs = new HashSet<>(); + private Iterator claimOwnerIterator; FindUnusedClaimsTask() { - //start scanning in a random spot - if(GriefPrevention.instance.dataStore.claims.size() == 0) - { - this.nextClaimIndex = 0; - } - else - { - Random randomNumberGenerator = new Random(); - this.nextClaimIndex = randomNumberGenerator.nextInt(GriefPrevention.instance.dataStore.claims.size()); - } + refreshUUIDs(); } @Override public void run() { //don't do anything when there are no claims - if(GriefPrevention.instance.dataStore.claims.size() == 0) return; + if(claimOwnerUUIDs.isEmpty()) return; //wrap search around to beginning - if(this.nextClaimIndex >= GriefPrevention.instance.dataStore.claims.size()) this.nextClaimIndex = 0; + if(!claimOwnerIterator.hasNext()) + { + refreshUUIDs(); + return; + } - //decide which claim to check next - Claim claim = GriefPrevention.instance.dataStore.claims.get(this.nextClaimIndex++); - - //skip administrative claims - if(claim.isAdminClaim()) return; - - Bukkit.getScheduler().runTaskAsynchronously(GriefPrevention.instance, new CleanupUnusedClaimPreTask(claim)); + Bukkit.getScheduler().runTaskAsynchronously(GriefPrevention.instance, new CleanupUnusedClaimPreTask(claimOwnerIterator.next())); + } + + public void refreshUUIDs() + { + claimOwnerUUIDs.clear(); + for (Claim claim : GriefPrevention.instance.dataStore.claims) + claimOwnerUUIDs.add(claim.ownerID); + claimOwnerIterator = claimOwnerUUIDs.iterator(); } } diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java b/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java index 7fab738..b94ecbe 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java @@ -198,6 +198,7 @@ public class GriefPrevention extends JavaPlugin public boolean config_pistonsInClaimsOnly; //whether pistons are limited to only move blocks located within the piston's land claim public boolean config_advanced_fixNegativeClaimblockAmounts; //whether to attempt to fix negative claim block amounts (some addons cause/assume players can go into negative amounts) + public int config_advanced_claim_expiration_check_rate; //How often GP should check for expired claims, amount in seconds //custom log settings public int config_logs_daysToKeep; @@ -327,7 +328,7 @@ public class GriefPrevention extends JavaPlugin //start recurring cleanup scan for unused claims belonging to inactive players FindUnusedClaimsTask task2 = new FindUnusedClaimsTask(); - this.getServer().getScheduler().scheduleSyncRepeatingTask(this, task2, 20L * 60, 20L * 60); + this.getServer().getScheduler().scheduleSyncRepeatingTask(this, task2, 20L * 60, 20L * config_advanced_claim_expiration_check_rate); //register for events PluginManager pluginManager = this.getServer().getPluginManager(); @@ -767,6 +768,7 @@ public class GriefPrevention extends JavaPlugin this.databasePassword = config.getString("GriefPrevention.Database.Password", ""); this.config_advanced_fixNegativeClaimblockAmounts = config.getBoolean("GriefPrevention.Advanced.fixNegativeClaimblockAmounts", true); + this.config_advanced_claim_expiration_check_rate = config.getInt("GriefPrevention.Advanced.ClaimExpirationCheckRate", 60); //custom logger settings this.config_logs_daysToKeep = config.getInt("GriefPrevention.Abridged Logs.Days To Keep", 7); @@ -893,6 +895,7 @@ public class GriefPrevention extends JavaPlugin outConfig.set("GriefPrevention.BanCommandPattern", this.config_ban_commandFormat); outConfig.set("GriefPrevention.Advanced.fixNegativeClaimblockAmounts", this.config_advanced_fixNegativeClaimblockAmounts); + outConfig.set("GriefPrevention.Advanced.ClaimExpirationCheckRate", this.config_advanced_claim_expiration_check_rate); //custom logger settings outConfig.set("GriefPrevention.Abridged Logs.Days To Keep", this.config_logs_daysToKeep);