Claim expiration: improvements+config option. Closes #24
- Claim expiration collects all players (uuids) that own claims, and iterates this set instead of iterating through every single claim. - Individual claims had a "last modified" timestamp, so this method was valid before, but makes no sense now since expiration is based on player inactivity instead of claim inactivity. New config option under the advanced node allows controlling the frequency each player in the aforementioned set is checked for inactivity.
This commit is contained in:
parent
93a36dd9e1
commit
f6b35d71bf
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<UUID> claimOwnerUUIDs = new HashSet<>();
|
||||
private Iterator<UUID> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user