Perf: Interactions, Fluid Flow, Block Deliveries
Improved performance for player interact handler, fluid flow handler, and scheduled claim block deliveries.
This commit is contained in:
parent
936463bf02
commit
02fba83551
|
|
@ -624,51 +624,27 @@ public class BlockEventHandler implements Listener
|
|||
}
|
||||
}
|
||||
|
||||
//ensures fluids don't flow out of claims, unless into another claim where the owner is trusted to build
|
||||
//ensures fluids don't flow into land claims from outside
|
||||
private Claim lastSpreadClaim = null;
|
||||
private Location lastSpreadSourceLocation = null;
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onBlockFromTo (BlockFromToEvent spreadEvent)
|
||||
{
|
||||
//don't track in worlds where claims are not enabled
|
||||
if(!GriefPrevention.instance.claimsEnabledForWorld(spreadEvent.getBlock().getWorld())) return;
|
||||
|
||||
//always allow fluids to flow straight down
|
||||
if(spreadEvent.getFace() == BlockFace.DOWN) return;
|
||||
|
||||
//from where?
|
||||
Block fromBlock = spreadEvent.getBlock();
|
||||
Claim fromClaim = null;
|
||||
if(fromBlock.getLocation().equals(lastSpreadSourceLocation))
|
||||
{
|
||||
fromClaim = lastSpreadClaim;
|
||||
}
|
||||
else
|
||||
{
|
||||
fromClaim = this.dataStore.getClaimAt(fromBlock.getLocation(), false, this.lastSpreadClaim);
|
||||
lastSpreadClaim = fromClaim;
|
||||
lastSpreadSourceLocation = fromBlock.getLocation();
|
||||
}
|
||||
//don't track in worlds where claims are not enabled
|
||||
if(!GriefPrevention.instance.claimsEnabledForWorld(spreadEvent.getBlock().getWorld())) return;
|
||||
|
||||
//where to?
|
||||
Block toBlock = spreadEvent.getToBlock();
|
||||
Location toLocation = toBlock.getLocation();
|
||||
Claim toClaim = this.dataStore.getClaimAt(toLocation, false, lastSpreadClaim);
|
||||
|
||||
//if from a land claim, this is easy and cheap - just don't allow for flowing out of that claim
|
||||
if(fromClaim != null)
|
||||
{
|
||||
if(!fromClaim.contains(toBlock.getLocation(), false, false))
|
||||
{
|
||||
spreadEvent.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, just prevent spreading into a claim from outside
|
||||
else
|
||||
{
|
||||
Claim toClaim = this.dataStore.getClaimAt(toBlock.getLocation(), false, fromClaim);
|
||||
|
||||
//if spreading into a claim
|
||||
//if into a land claim, it must be from the same land claim
|
||||
if(toClaim != null)
|
||||
{
|
||||
this.lastSpreadClaim = toClaim;
|
||||
if(!toClaim.contains(spreadEvent.getBlock().getLocation(), false, false))
|
||||
{
|
||||
spreadEvent.setCancelled(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,19 +26,35 @@ import org.bukkit.entity.Player;
|
|||
//runs every 5 minutes in the main thread, grants blocks per hour / 12 to each online player who appears to be actively playing
|
||||
class DeliverClaimBlocksTask implements Runnable
|
||||
{
|
||||
private Player player;
|
||||
|
||||
public DeliverClaimBlocksTask(Player player)
|
||||
{
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
//if no player specified, this task will create a player-specific task for each online player, scheduled one tick apart
|
||||
if(this.player == null)
|
||||
{
|
||||
Player [] players = GriefPrevention.instance.getServer().getOnlinePlayers();
|
||||
|
||||
//ensure players get at least 1 block (if accrual is totally disabled, this task won't even be scheduled)
|
||||
long i = 0;
|
||||
for(Player onlinePlayer : players)
|
||||
{
|
||||
DeliverClaimBlocksTask newTask = new DeliverClaimBlocksTask(onlinePlayer);
|
||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, newTask, i++);
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, deliver claim blocks to the specified player
|
||||
else
|
||||
{
|
||||
int accruedBlocks = GriefPrevention.instance.config_claims_blocksAccruedPerHour / 12;
|
||||
if(accruedBlocks < 0) accruedBlocks = 1;
|
||||
|
||||
//for each online player
|
||||
for(int i = 0; i < players.length; i++)
|
||||
{
|
||||
Player player = players[i];
|
||||
DataStore dataStore = GriefPrevention.instance.dataStore;
|
||||
PlayerData playerData = dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
|
|
@ -53,7 +69,7 @@ class DeliverClaimBlocksTask implements Runnable
|
|||
{
|
||||
//if player is over accrued limit, accrued limit was probably reduced in config file AFTER he accrued
|
||||
//in that case, leave his blocks where they are
|
||||
if(playerData.getAccruedClaimBlocks() > GriefPrevention.instance.config_claims_maxAccruedBlocks) continue;
|
||||
if(playerData.getAccruedClaimBlocks() > GriefPrevention.instance.config_claims_maxAccruedBlocks) return;
|
||||
|
||||
//add blocks
|
||||
playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() + accruedBlocks);
|
||||
|
|
@ -69,7 +85,15 @@ class DeliverClaimBlocksTask implements Runnable
|
|||
//dataStore.savePlayerData(player.getName(), playerData);
|
||||
}
|
||||
}
|
||||
catch(Exception e) { }
|
||||
catch(IllegalArgumentException e) //can't measure distance when to/from are different worlds
|
||||
{
|
||||
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Problem delivering claim blocks to player " + player.getName() + ":");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//remember current location for next time
|
||||
playerData.lastAfkCheckLocation = player.getLocation();
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//20L ~ 1 second
|
||||
if(this.config_claims_blocksAccruedPerHour > 0)
|
||||
{
|
||||
DeliverClaimBlocksTask task = new DeliverClaimBlocksTask();
|
||||
DeliverClaimBlocksTask task = new DeliverClaimBlocksTask(null);
|
||||
this.getServer().getScheduler().scheduleSyncRepeatingTask(this, task, 20L * 60 * 5, 20L * 60 * 5);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1115,15 +1115,16 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//don't care about left-clicking on most blocks, this is probably a break action
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
PlayerData playerData = null;
|
||||
if(action == Action.LEFT_CLICK_BLOCK && clickedBlock != null)
|
||||
{
|
||||
//exception for blocks on a specific watch list
|
||||
if(!this.onLeftClickWatchList(clickedBlockType) && !GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null)))
|
||||
{
|
||||
//and an exception for putting our fires
|
||||
if(event.getClickedBlock() != null && event.getClickedBlock().getRelative(event.getBlockFace()).getType() == Material.FIRE)
|
||||
if(clickedBlockType == Material.NETHERRACK && event.getClickedBlock() != null && event.getClickedBlock().getRelative(event.getBlockFace()).getType() == Material.FIRE)
|
||||
{
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
|
|
@ -1146,10 +1147,12 @@ class PlayerEventHandler implements Listener
|
|||
//apply rules for containers and crafting blocks
|
||||
if( clickedBlock != null && GriefPrevention.instance.config_claims_preventTheft && (
|
||||
event.getAction() == Action.RIGHT_CLICK_BLOCK && (
|
||||
clickedBlock.getState() instanceof InventoryHolder ||
|
||||
this.isInventoryHolder(clickedBlock) ||
|
||||
clickedBlockType == Material.ANVIL ||
|
||||
GriefPrevention.instance.config_mods_containerTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null)))))
|
||||
{
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//block container use while under siege, so players can't hide items from attackers
|
||||
if(playerData.siegeData != null)
|
||||
{
|
||||
|
|
@ -1196,6 +1199,7 @@ class PlayerEventHandler implements Listener
|
|||
(GriefPrevention.instance.config_claims_lockTrapDoors && clickedBlockType == Material.TRAP_DOOR) ||
|
||||
(GriefPrevention.instance.config_claims_lockFenceGates && clickedBlockType == Material.FENCE_GATE))
|
||||
{
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
|
|
@ -1214,9 +1218,11 @@ class PlayerEventHandler implements Listener
|
|||
//otherwise apply rules for buttons and switches
|
||||
else if(clickedBlock != null && GriefPrevention.instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.WOOD_BUTTON || clickedBlockType == Material.LEVER || GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null))))
|
||||
{
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.lastClaim = claim;
|
||||
|
||||
String noAccessReason = claim.allowAccess(player);
|
||||
|
|
@ -1232,6 +1238,7 @@ class PlayerEventHandler implements Listener
|
|||
//apply rule for note blocks and repeaters
|
||||
else if(clickedBlock != null && clickedBlockType == Material.NOTE_BLOCK || clickedBlockType == Material.DIODE_BLOCK_ON || clickedBlockType == Material.DIODE_BLOCK_OFF)
|
||||
{
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
|
|
@ -1269,6 +1276,7 @@ class PlayerEventHandler implements Listener
|
|||
|
||||
else if(clickedBlock != null && materialInHand == Material.BOAT)
|
||||
{
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
|
|
@ -1296,6 +1304,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//enforce limit on total number of entities in this claim
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim == null) return;
|
||||
|
||||
|
|
@ -1335,6 +1344,7 @@ class PlayerEventHandler implements Listener
|
|||
return;
|
||||
}
|
||||
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false /*ignore height*/, playerData.lastClaim);
|
||||
|
||||
//no claim case
|
||||
|
|
@ -1387,6 +1397,7 @@ class PlayerEventHandler implements Listener
|
|||
else if(materialInHand != GriefPrevention.instance.config_claims_modificationTool) return;
|
||||
|
||||
//disable golden shovel while under siege
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
if(playerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoShovel);
|
||||
|
|
@ -1588,6 +1599,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//if he's resizing a claim and that claim hasn't been deleted since he started resizing it
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
if(playerData.claimResizing != null && playerData.claimResizing.inDataStore)
|
||||
{
|
||||
if(clickedBlock.getLocation().equals(playerData.lastShovelLocation)) return;
|
||||
|
|
@ -1724,6 +1736,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//otherwise, since not currently resizing a claim, must be starting a resize, creating a new claim, or creating a subdivision
|
||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), true /*ignore height*/, playerData.lastClaim);
|
||||
|
||||
//if within an existing claim, he's not creating a new one
|
||||
|
|
@ -1919,6 +1932,24 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
}
|
||||
|
||||
//determines whether a block type is an inventory holder. uses a caching strategy to save cpu time
|
||||
private ConcurrentHashMap<Integer, Boolean> inventoryHolderCache = new ConcurrentHashMap<Integer, Boolean>();
|
||||
private boolean isInventoryHolder(Block clickedBlock)
|
||||
{
|
||||
Integer cacheKey = clickedBlock.getTypeId();
|
||||
Boolean cachedValue = this.inventoryHolderCache.get(cacheKey);
|
||||
if(cachedValue != null)
|
||||
{
|
||||
return cachedValue.booleanValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean isHolder = clickedBlock.getState() instanceof InventoryHolder;
|
||||
this.inventoryHolderCache.put(cacheKey, isHolder);
|
||||
return isHolder;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onLeftClickWatchList(Material material)
|
||||
{
|
||||
switch(material)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user