6.4
This commit is contained in:
parent
008f313d09
commit
1f6223526b
|
|
@ -2,7 +2,7 @@ name: GriefPrevention
|
|||
main: me.ryanhamshire.GriefPrevention.GriefPrevention
|
||||
softdepend: [Vault, Multiverse-Core, My Worlds]
|
||||
dev-url: http://dev.bukkit.org/server-mods/grief-prevention
|
||||
version: 6.3
|
||||
version: 6.4
|
||||
commands:
|
||||
abandonclaim:
|
||||
description: Deletes a claim.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ public class Claim
|
|||
{
|
||||
//two locations, which together define the boundaries of the claim
|
||||
//note that the upper Y value is always ignored, because claims ALWAYS extend up to the sky
|
||||
//IF MODIFIED, THE CLAIM DATA FILE'S NAME WILL CHANGE. ANY MODIFICATIONS MUST BE HANDLED VERY CAREFULLY
|
||||
Location lesserBoundaryCorner;
|
||||
Location greaterBoundaryCorner;
|
||||
|
||||
|
|
@ -436,6 +435,12 @@ public class Claim
|
|||
//following a siege where the defender lost, the claim will allow everyone access for a time
|
||||
if(this.doorsOpen) return null;
|
||||
|
||||
//admin claims need adminclaims permission only.
|
||||
if(this.isAdminClaim())
|
||||
{
|
||||
if(player.hasPermission("griefprevention.adminclaims")) return null;
|
||||
}
|
||||
|
||||
//claim owner and admins in ignoreclaims mode have access
|
||||
if(this.ownerName.equals(player.getName()) || GriefPrevention.instance.dataStore.getPlayerData(player.getName()).ignoreClaims) return null;
|
||||
|
||||
|
|
@ -474,6 +479,12 @@ public class Claim
|
|||
//owner and administrators in ignoreclaims mode have access
|
||||
if(this.ownerName.equals(player.getName()) || GriefPrevention.instance.dataStore.getPlayerData(player.getName()).ignoreClaims) return null;
|
||||
|
||||
//admin claims need adminclaims permission only.
|
||||
if(this.isAdminClaim())
|
||||
{
|
||||
if(player.hasPermission("griefprevention.adminclaims")) return null;
|
||||
}
|
||||
|
||||
//check for explicit individual container or build permission
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Inventory)) return null;
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null;
|
||||
|
|
@ -750,4 +761,61 @@ public class Claim
|
|||
|
||||
return thisCorner.getWorld().getName().compareTo(otherCorner.getWorld().getName()) < 0;
|
||||
}
|
||||
|
||||
long getPlayerInvestmentScore()
|
||||
{
|
||||
//decide which blocks will be considered player placed
|
||||
Location lesserBoundaryCorner = this.getLesserBoundaryCorner();
|
||||
ArrayList<Integer> playerBlocks = RestoreNatureProcessingTask.getPlayerBlocks(lesserBoundaryCorner.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome());
|
||||
|
||||
//scan the claim for player placed blocks
|
||||
double score = 0;
|
||||
|
||||
boolean creativeMode = GriefPrevention.instance.creativeRulesApply(lesserBoundaryCorner);
|
||||
|
||||
for(int x = this.lesserBoundaryCorner.getBlockX(); x <= this.greaterBoundaryCorner.getBlockX(); x++)
|
||||
{
|
||||
for(int z = this.lesserBoundaryCorner.getBlockZ(); z <= this.greaterBoundaryCorner.getBlockZ(); z++)
|
||||
{
|
||||
int y = this.lesserBoundaryCorner.getBlockY();
|
||||
for(; y < this.lesserBoundaryCorner.getWorld().getSeaLevel(); y++)
|
||||
{
|
||||
Block block = this.lesserBoundaryCorner.getWorld().getBlockAt(x, y, z);
|
||||
if(playerBlocks.contains(block.getTypeId()))
|
||||
{
|
||||
if(block.getType() == Material.CHEST && !creativeMode)
|
||||
{
|
||||
score += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
score += .2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(; y < this.lesserBoundaryCorner.getWorld().getMaxHeight(); y++)
|
||||
{
|
||||
Block block = this.lesserBoundaryCorner.getWorld().getBlockAt(x, y, z);
|
||||
if(playerBlocks.contains(block.getTypeId()))
|
||||
{
|
||||
if(block.getType() == Material.CHEST && !creativeMode)
|
||||
{
|
||||
score += 10;
|
||||
}
|
||||
else if(creativeMode && (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA))
|
||||
{
|
||||
score -= 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
score += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (long)score;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
186
src/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimsTask.java
Normal file
186
src/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimsTask.java
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
GriefPrevention Server Plugin for Minecraft
|
||||
Copyright (C) 2011 Ryan Hamshire
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.ryanhamshire.GriefPrevention;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
||||
//FEATURE: automatically remove claims owned by inactive players which:
|
||||
//...aren't protecting much OR
|
||||
//...are a free new player claim (and the player has no other claims) OR
|
||||
//...because the player has been gone a REALLY long time, and that expiration has been configured in config.yml
|
||||
|
||||
//runs every 1 minute in the main thread
|
||||
class CleanupUnusedClaimsTask implements Runnable
|
||||
{
|
||||
int nextClaimIndex;
|
||||
|
||||
CleanupUnusedClaimsTask()
|
||||
{
|
||||
//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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
//don't do anything when there are no claims
|
||||
if(GriefPrevention.instance.dataStore.claims.size() == 0) return;
|
||||
|
||||
//wrap search around to beginning
|
||||
if(this.nextClaimIndex >= GriefPrevention.instance.dataStore.claims.size()) this.nextClaimIndex = 0;
|
||||
|
||||
//decide which claim to check next
|
||||
Claim claim = GriefPrevention.instance.dataStore.claims.get(this.nextClaimIndex++);
|
||||
|
||||
//skip administrative claims
|
||||
if(claim.isAdminClaim()) return;
|
||||
|
||||
//get data for the player, especially last login timestamp
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(claim.ownerName);
|
||||
|
||||
//determine area of the default chest claim
|
||||
int areaOfDefaultClaim = 0;
|
||||
if(GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius >= 0)
|
||||
{
|
||||
areaOfDefaultClaim = (int)Math.pow(GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius * 2 + 1, 2);
|
||||
}
|
||||
|
||||
//if he's been gone at least a week, if he has ONLY the new player claim, it will be removed
|
||||
Calendar sevenDaysAgo = Calendar.getInstance();
|
||||
sevenDaysAgo.add(Calendar.DATE, -7);
|
||||
boolean newPlayerClaimsExpired = sevenDaysAgo.getTime().after(playerData.lastLogin);
|
||||
|
||||
//if only one claim, and the player hasn't played in a week
|
||||
if(newPlayerClaimsExpired && playerData.claims.size() == 1)
|
||||
{
|
||||
//if that's a chest claim, delete it
|
||||
if(claim.getArea() <= areaOfDefaultClaim)
|
||||
{
|
||||
claim.removeSurfaceFluids(null);
|
||||
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
||||
|
||||
//if in a creative mode world, delete the claim
|
||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
||||
{
|
||||
GriefPrevention.instance.restoreClaim(claim, 0);
|
||||
}
|
||||
|
||||
GriefPrevention.AddLogEntry(" " + claim.getOwnerName() + "'s new player claim expired.");
|
||||
}
|
||||
}
|
||||
|
||||
//if configured to always remove claims after some inactivity period without exceptions...
|
||||
else if(GriefPrevention.instance.config_claims_expirationDays > 0)
|
||||
{
|
||||
Calendar earliestPermissibleLastLogin = Calendar.getInstance();
|
||||
earliestPermissibleLastLogin.add(Calendar.DATE, -GriefPrevention.instance.config_claims_expirationDays);
|
||||
|
||||
if(earliestPermissibleLastLogin.getTime().after(playerData.lastLogin))
|
||||
{
|
||||
GriefPrevention.instance.dataStore.deleteClaimsForPlayer(claim.getOwnerName(), true);
|
||||
GriefPrevention.AddLogEntry(" All of " + claim.getOwnerName() + "'s claims have expired.");
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
//if the player has been gone two weeks, scan claim content to assess player investment
|
||||
Calendar fourteenDaysAgo = Calendar.getInstance();
|
||||
fourteenDaysAgo.add(Calendar.DATE, -14);
|
||||
boolean needsInvestmentScan = fourteenDaysAgo.getTime().after(playerData.lastLogin);
|
||||
|
||||
//avoid scanning large claims and administrative claims
|
||||
if(claim.isAdminClaim() || claim.getWidth() > 25 || claim.getHeight() > 25) return;
|
||||
|
||||
//if creative mode or the claim owner has been away a long enough time, scan the claim content
|
||||
if(needsInvestmentScan || GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
||||
{
|
||||
int minInvestment;
|
||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
||||
{
|
||||
minInvestment = 400;
|
||||
}
|
||||
else
|
||||
{
|
||||
minInvestment = 200;
|
||||
}
|
||||
|
||||
long investmentScore = claim.getPlayerInvestmentScore();
|
||||
boolean removeClaim = false;
|
||||
|
||||
//in creative mode, a build which is almost entirely lava above sea level will be automatically removed, even if the owner is an active player
|
||||
//lava above the surface deducts 10 points per block from the investment score
|
||||
//so 500 blocks of lava without anything built to offset all that potential mess would be cleaned up automatically
|
||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()) && investmentScore < -5000)
|
||||
{
|
||||
removeClaim = true;
|
||||
}
|
||||
|
||||
//otherwise, the only way to get a claim automatically removed based on build investment is to be away for two weeks AND not build much of anything
|
||||
else if(needsInvestmentScan && investmentScore < minInvestment)
|
||||
{
|
||||
removeClaim = true;
|
||||
}
|
||||
|
||||
if(removeClaim)
|
||||
{
|
||||
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
||||
GriefPrevention.AddLogEntry("Removed " + claim.getOwnerName() + "'s unused claim @ " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()));
|
||||
|
||||
//if in a creative mode world, restore the claim area
|
||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
||||
{
|
||||
GriefPrevention.instance.restoreClaim(claim, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//toss that player data out of the cache, it's probably not needed in memory right now
|
||||
GriefPrevention.instance.dataStore.clearCachedPlayerData(claim.ownerName);
|
||||
|
||||
//since we're potentially loading a lot of chunks to scan parts of the world where there are no players currently playing, be mindful of memory usage
|
||||
//unfortunately, java/minecraft don't do a good job of clearing unused memory, leading to out of memory errors from this type of world scanning
|
||||
if(this.nextClaimIndex % 20 == 0)
|
||||
{
|
||||
World world = claim.getLesserBoundaryCorner().getWorld();
|
||||
Chunk [] chunks = world.getLoadedChunks();
|
||||
for(int i = 0; i < chunks.length; i++)
|
||||
{
|
||||
Chunk chunk = chunks[i];
|
||||
chunk.unload(true, true);
|
||||
}
|
||||
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -70,63 +70,6 @@ public abstract class DataStore
|
|||
|
||||
GriefPrevention.AddLogEntry(playerNames.size() + " players have staked claims.");
|
||||
|
||||
//load each of these players and determine whether his claims should be cleaned up
|
||||
for(int i = 0; i < playerNames.size(); i++)
|
||||
{
|
||||
String playerName = playerNames.get(i);
|
||||
|
||||
PlayerData playerData = this.getPlayerData(playerName);
|
||||
|
||||
int areaOfDefaultClaim = 0;
|
||||
|
||||
//determine area of the default chest claim
|
||||
if(GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius >= 0)
|
||||
{
|
||||
areaOfDefaultClaim = (int)Math.pow(GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius * 2 + 1, 2);
|
||||
}
|
||||
|
||||
//figure out how long the player has been away
|
||||
Calendar sevenDaysAgo = Calendar.getInstance();
|
||||
sevenDaysAgo.add(Calendar.DATE, -7);
|
||||
boolean claimsExpired = sevenDaysAgo.getTime().after(playerData.lastLogin);
|
||||
|
||||
//if only one claim, and the player hasn't played in a week
|
||||
if(claimsExpired && playerData.claims.size() == 1)
|
||||
{
|
||||
Claim claim = playerData.claims.get(0);
|
||||
|
||||
//if that's a chest claim, delete it
|
||||
if(claim.getArea() <= areaOfDefaultClaim)
|
||||
{
|
||||
claim.removeSurfaceFluids(null);
|
||||
this.deleteClaim(claim);
|
||||
|
||||
//if in a creative mode world, delete the claim
|
||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
||||
{
|
||||
GriefPrevention.instance.restoreClaim(claim, 0);
|
||||
}
|
||||
|
||||
GriefPrevention.AddLogEntry(" " + playerName + "'s new player claim expired.");
|
||||
}
|
||||
}
|
||||
|
||||
if(GriefPrevention.instance.config_claims_expirationDays > 0)
|
||||
{
|
||||
Calendar earliestPermissibleLastLogin = Calendar.getInstance();
|
||||
earliestPermissibleLastLogin.add(Calendar.DATE, -GriefPrevention.instance.config_claims_expirationDays);
|
||||
|
||||
if(earliestPermissibleLastLogin.getTime().after(playerData.lastLogin))
|
||||
{
|
||||
this.deleteClaimsForPlayer(playerName, true);
|
||||
GriefPrevention.AddLogEntry(" All of " + playerName + "'s claims have expired.");
|
||||
}
|
||||
}
|
||||
|
||||
//toss that player data out of the cache, it's not needed in memory right now
|
||||
this.clearCachedPlayerData(playerName);
|
||||
}
|
||||
|
||||
//load up all the messages from messages.yml
|
||||
this.loadMessages();
|
||||
|
||||
|
|
@ -1013,6 +956,7 @@ public abstract class DataStore
|
|||
this.addDefault(defaults, Messages.TrappedWontWorkHere, "Sorry, unable to find a safe location to teleport you to. Contact an admin, or consider /kill if you don't want to wait.", null);
|
||||
this.addDefault(defaults, Messages.CommandBannedInPvP, "You can't use that command while in PvP combat.", null);
|
||||
this.addDefault(defaults, Messages.UnclaimCleanupWarning, "The land you've unclaimed may be changed by other players or cleaned up by administrators. If you've built something there you want to keep, you should reclaim it.", null);
|
||||
this.addDefault(defaults, Messages.BuySellNotConfigured, "Sorry, buying anhd selling claim blocks is disabled.", null);
|
||||
|
||||
//load the config file
|
||||
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));
|
||||
|
|
|
|||
|
|
@ -44,30 +44,23 @@ class EquipShovelProcessingTask implements Runnable
|
|||
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
|
||||
//reset any work he might have been doing
|
||||
playerData.lastShovelLocation = null;
|
||||
playerData.claimResizing = null;
|
||||
|
||||
//always reset to basic claims mode
|
||||
if(playerData.shovelMode != ShovelMode.Basic)
|
||||
{
|
||||
playerData.shovelMode = ShovelMode.Basic;
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.ShovelBasicClaimMode);
|
||||
}
|
||||
|
||||
int remainingBlocks = playerData.getRemainingClaimBlocks();
|
||||
|
||||
//instruct him in the steps to create a claim
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RemainingBlocks, String.valueOf(remainingBlocks));
|
||||
|
||||
//demo link changes based on game mode
|
||||
if(GriefPrevention.instance.creativeRulesApply(player.getLocation()))
|
||||
//if in basic claims mode...
|
||||
if(playerData.shovelMode == ShovelMode.Basic)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsDemoAdvertisement);
|
||||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsDemoAdvertisement);
|
||||
//tell him how many claim blocks he has available
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RemainingBlocks, String.valueOf(remainingBlocks));
|
||||
|
||||
//link to a video demo of land claiming, based on world type
|
||||
if(GriefPrevention.instance.creativeRulesApply(player.getLocation()))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsDemoAdvertisement);
|
||||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsDemoAdvertisement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -565,6 +565,10 @@ public class GriefPrevention extends JavaPlugin
|
|||
EntityCleanupTask task = new EntityCleanupTask(0);
|
||||
this.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L);
|
||||
|
||||
//start recurring cleanup scan for unused claims belonging to inactive players
|
||||
CleanupUnusedClaimsTask task2 = new CleanupUnusedClaimsTask();
|
||||
this.getServer().getScheduler().scheduleSyncRepeatingTask(this, task2, 20L * 60 * 2, 20L * 60 * 5);
|
||||
|
||||
//register for events
|
||||
PluginManager pluginManager = this.getServer().getPluginManager();
|
||||
|
||||
|
|
@ -614,7 +618,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
{
|
||||
GriefPrevention.AddLogEntry("ERROR: Vault was unable to find a supported economy plugin. Either install a Vault-compatible economy plugin, or set both of the economy config variables to zero.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//handles slash commands
|
||||
|
|
@ -1041,7 +1045,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
else if(cmd.getName().equalsIgnoreCase("buyclaimblocks") && player != null)
|
||||
{
|
||||
//if economy is disabled, don't do anything
|
||||
if(GriefPrevention.economy == null) return true;
|
||||
if(GriefPrevention.economy == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.BuySellNotConfigured);
|
||||
return true;
|
||||
}
|
||||
|
||||
//if purchase disabled, send error message
|
||||
if(GriefPrevention.instance.config_economy_claimBlocksPurchaseCost == 0)
|
||||
|
|
@ -1122,7 +1130,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
else if(cmd.getName().equalsIgnoreCase("sellclaimblocks") && player != null)
|
||||
{
|
||||
//if economy is disabled, don't do anything
|
||||
if(GriefPrevention.economy == null) return true;
|
||||
if(GriefPrevention.economy == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.BuySellNotConfigured);
|
||||
return true;
|
||||
}
|
||||
|
||||
//if disabled, error message
|
||||
if(GriefPrevention.instance.config_economy_claimBlocksSellValue == 0)
|
||||
|
|
@ -2337,7 +2349,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
//create task
|
||||
//when done processing, this task will create a main thread task to actually update the world with processing results
|
||||
RestoreNatureProcessingTask task = new RestoreNatureProcessingTask(snapshots, miny, chunk.getWorld().getEnvironment(), chunk.getWorld().getBiome(lesserBoundaryCorner.getBlockX(), lesserBoundaryCorner.getBlockZ()), lesserBoundaryCorner, greaterBoundaryCorner, chunk.getWorld().getSeaLevel() + 1, aggressiveMode, GriefPrevention.instance.creativeRulesApply(lesserBoundaryCorner), playerReceivingVisualization);
|
||||
RestoreNatureProcessingTask task = new RestoreNatureProcessingTask(snapshots, miny, chunk.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome(), lesserBoundaryCorner, greaterBoundaryCorner, chunk.getWorld().getSeaLevel() + 1, aggressiveMode, GriefPrevention.instance.creativeRulesApply(lesserBoundaryCorner), playerReceivingVisualization);
|
||||
GriefPrevention.instance.getServer().getScheduler().scheduleAsyncDelayedTask(GriefPrevention.instance, task, delayInTicks);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,5 +2,5 @@ package me.ryanhamshire.GriefPrevention;
|
|||
|
||||
public enum Messages
|
||||
{
|
||||
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionDemo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, TrappedOnCooldown, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, TrustCommandAdvertisement, GoldenShovelAdvertisement, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsDemoAdvertisement, SurvivalBasicsDemoAdvertisement, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning
|
||||
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionDemo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, TrappedOnCooldown, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, TrustCommandAdvertisement, GoldenShovelAdvertisement, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsDemoAdvertisement, SurvivalBasicsDemoAdvertisement, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
player.kickPlayer("");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//cancel any messages while at or above the third spam level and issue warnings
|
||||
|
|
@ -521,7 +523,7 @@ class PlayerEventHandler implements Listener
|
|||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
|
||||
//if banned, add IP to the temporary IP ban list
|
||||
if(player.isBanned())
|
||||
if(player.isBanned() && playerData.ipAddress != null)
|
||||
{
|
||||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
this.tempBannedIps.add(new IpBanInfo(playerData.ipAddress, now + this.MILLISECONDS_IN_DAY, player.getName()));
|
||||
|
|
@ -534,7 +536,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//make sure his data is all saved - he might have accrued some claim blocks while playing that were not saved immediately
|
||||
this.dataStore.savePlayerData(player.getName(), playerData);
|
||||
this.dataStore.savePlayerData(player.getName(), playerData);
|
||||
|
||||
this.onPlayerDisconnect(event.getPlayer(), event.getQuitMessage());
|
||||
}
|
||||
|
|
@ -762,6 +764,20 @@ class PlayerEventHandler implements Listener
|
|||
ItemStack newItemStack = player.getInventory().getItem(event.getNewSlot());
|
||||
if(newItemStack != null && newItemStack.getType() == GriefPrevention.instance.config_claims_modificationTool)
|
||||
{
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
|
||||
//always reset to basic claims mode
|
||||
if(playerData.shovelMode != ShovelMode.Basic)
|
||||
{
|
||||
playerData.shovelMode = ShovelMode.Basic;
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.ShovelBasicClaimMode);
|
||||
}
|
||||
|
||||
//reset any work he might have been doing
|
||||
playerData.lastShovelLocation = null;
|
||||
playerData.claimResizing = null;
|
||||
|
||||
//give the player his available claim blocks count and claiming instructions, but only if he keeps the shovel equipped for a minimum time, to avoid mouse wheel spam
|
||||
EquipShovelProcessingTask task = new EquipShovelProcessingTask(player);
|
||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 15L); //15L is approx. 3/4 of a second
|
||||
}
|
||||
|
|
@ -878,7 +894,7 @@ class PlayerEventHandler implements Listener
|
|||
try
|
||||
{
|
||||
clickedBlock = event.getClickedBlock(); //null returned here means interacting with air
|
||||
if(clickedBlock == null)
|
||||
if(clickedBlock == null || clickedBlock.getType() == Material.SNOW)
|
||||
{
|
||||
//try to find a far away non-air block along line of sight
|
||||
HashSet<Byte> transparentMaterials = new HashSet<Byte>();
|
||||
|
|
@ -1570,7 +1586,7 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapOtherPlayer, claim.getOwnerName());
|
||||
Visualization visualization = Visualization.FromClaim(claim, clickedBlock.getY(), VisualizationType.ErrorClaim, player.getLocation());
|
||||
Visualization.Apply(player, visualization);
|
||||
Visualization.Apply(player, visualization);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -1592,6 +1608,10 @@ class PlayerEventHandler implements Listener
|
|||
//remember it, and start him on the new claim
|
||||
playerData.lastShovelLocation = clickedBlock.getLocation();
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ClaimStart);
|
||||
|
||||
//show him where he's working
|
||||
Visualization visualization = Visualization.FromClaim(new Claim(clickedBlock.getLocation(), clickedBlock.getLocation(), "", new String[]{}, new String[]{}, new String[]{}, new String[]{}, null), clickedBlock.getY(), VisualizationType.RestoreNature, player.getLocation());
|
||||
Visualization.Apply(player, visualization);
|
||||
}
|
||||
|
||||
//otherwise, he's trying to finish creating a claim by setting the other boundary corner
|
||||
|
|
|
|||
|
|
@ -75,110 +75,8 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
this.notAllowedToHang.add(Material.STONE.getId());
|
||||
}
|
||||
|
||||
//NOTE on this list. why not make a list of natural blocks?
|
||||
//answer: better to leave a few player blocks than to remove too many natural blocks. remember we're "restoring nature"
|
||||
//a few extra player blocks can be manually removed, but it will be impossible to guess exactly which natural materials to use in manual repair of an overzealous block removal
|
||||
this.playerBlocks = new ArrayList<Integer>();
|
||||
this.playerBlocks.add(Material.FIRE.getId());
|
||||
this.playerBlocks.add(Material.BED_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.WOOD.getId());
|
||||
this.playerBlocks.add(Material.BOOKSHELF.getId());
|
||||
this.playerBlocks.add(Material.BREWING_STAND.getId());
|
||||
this.playerBlocks.add(Material.BRICK.getId());
|
||||
this.playerBlocks.add(Material.COBBLESTONE.getId());
|
||||
this.playerBlocks.add(Material.GLASS.getId());
|
||||
this.playerBlocks.add(Material.LAPIS_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.DISPENSER.getId());
|
||||
this.playerBlocks.add(Material.NOTE_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.POWERED_RAIL.getId());
|
||||
this.playerBlocks.add(Material.DETECTOR_RAIL.getId());
|
||||
this.playerBlocks.add(Material.PISTON_STICKY_BASE.getId());
|
||||
this.playerBlocks.add(Material.PISTON_BASE.getId());
|
||||
this.playerBlocks.add(Material.PISTON_EXTENSION.getId());
|
||||
this.playerBlocks.add(Material.WOOL.getId());
|
||||
this.playerBlocks.add(Material.PISTON_MOVING_PIECE.getId());
|
||||
this.playerBlocks.add(Material.GOLD_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.IRON_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.DOUBLE_STEP.getId());
|
||||
this.playerBlocks.add(Material.STEP.getId());
|
||||
this.playerBlocks.add(Material.CROPS.getId());
|
||||
this.playerBlocks.add(Material.TNT.getId());
|
||||
this.playerBlocks.add(Material.MOSSY_COBBLESTONE.getId());
|
||||
this.playerBlocks.add(Material.TORCH.getId());
|
||||
this.playerBlocks.add(Material.FIRE.getId());
|
||||
this.playerBlocks.add(Material.WOOD_STAIRS.getId());
|
||||
this.playerBlocks.add(Material.CHEST.getId());
|
||||
this.playerBlocks.add(Material.REDSTONE_WIRE.getId());
|
||||
this.playerBlocks.add(Material.DIAMOND_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.WORKBENCH.getId());
|
||||
this.playerBlocks.add(Material.SOIL.getId());
|
||||
this.playerBlocks.add(Material.FURNACE.getId());
|
||||
this.playerBlocks.add(Material.BURNING_FURNACE.getId());
|
||||
this.playerBlocks.add(Material.WOODEN_DOOR.getId());
|
||||
this.playerBlocks.add(Material.SIGN_POST.getId());
|
||||
this.playerBlocks.add(Material.LADDER.getId());
|
||||
this.playerBlocks.add(Material.RAILS.getId());
|
||||
this.playerBlocks.add(Material.COBBLESTONE_STAIRS.getId());
|
||||
this.playerBlocks.add(Material.WALL_SIGN.getId());
|
||||
this.playerBlocks.add(Material.STONE_PLATE.getId());
|
||||
this.playerBlocks.add(Material.LEVER.getId());
|
||||
this.playerBlocks.add(Material.IRON_DOOR_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.WOOD_PLATE.getId());
|
||||
this.playerBlocks.add(Material.REDSTONE_TORCH_ON.getId());
|
||||
this.playerBlocks.add(Material.REDSTONE_TORCH_OFF.getId());
|
||||
this.playerBlocks.add(Material.STONE_BUTTON.getId());
|
||||
this.playerBlocks.add(Material.SNOW_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.JUKEBOX.getId());
|
||||
this.playerBlocks.add(Material.FENCE.getId());
|
||||
this.playerBlocks.add(Material.PORTAL.getId());
|
||||
this.playerBlocks.add(Material.JACK_O_LANTERN.getId());
|
||||
this.playerBlocks.add(Material.CAKE_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
this.playerBlocks.add(Material.DIODE_BLOCK_OFF.getId());
|
||||
this.playerBlocks.add(Material.TRAP_DOOR.getId());
|
||||
this.playerBlocks.add(Material.SMOOTH_BRICK.getId());
|
||||
this.playerBlocks.add(Material.HUGE_MUSHROOM_1.getId());
|
||||
this.playerBlocks.add(Material.HUGE_MUSHROOM_2.getId());
|
||||
this.playerBlocks.add(Material.IRON_FENCE.getId());
|
||||
this.playerBlocks.add(Material.THIN_GLASS.getId());
|
||||
this.playerBlocks.add(Material.MELON_STEM.getId());
|
||||
this.playerBlocks.add(Material.FENCE_GATE.getId());
|
||||
this.playerBlocks.add(Material.BRICK_STAIRS.getId());
|
||||
this.playerBlocks.add(Material.SMOOTH_STAIRS.getId());
|
||||
this.playerBlocks.add(Material.ENCHANTMENT_TABLE.getId());
|
||||
this.playerBlocks.add(Material.BREWING_STAND.getId());
|
||||
this.playerBlocks.add(Material.CAULDRON.getId());
|
||||
this.playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
this.playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
this.playerBlocks.add(Material.WEB.getId());
|
||||
this.playerBlocks.add(Material.SPONGE.getId());
|
||||
this.playerBlocks.add(Material.GRAVEL.getId());
|
||||
this.playerBlocks.add(Material.EMERALD_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.SANDSTONE.getId());
|
||||
|
||||
//these are unnatural in the standard world, but not in the nether
|
||||
if(this.environment != Environment.NETHER)
|
||||
{
|
||||
this.playerBlocks.add(Material.NETHERRACK.getId());
|
||||
this.playerBlocks.add(Material.SOUL_SAND.getId());
|
||||
this.playerBlocks.add(Material.GLOWSTONE.getId());
|
||||
this.playerBlocks.add(Material.NETHER_BRICK.getId());
|
||||
this.playerBlocks.add(Material.NETHER_FENCE.getId());
|
||||
this.playerBlocks.add(Material.NETHER_BRICK_STAIRS.getId());
|
||||
}
|
||||
|
||||
//these are unnatural in the standard and nether worlds, but not in the end
|
||||
if(this.environment != Environment.THE_END)
|
||||
{
|
||||
this.playerBlocks.add(Material.OBSIDIAN.getId());
|
||||
}
|
||||
|
||||
//these are unnatural in sandy biomes, but not elsewhere
|
||||
if(this.biome == Biome.DESERT || this.biome == Biome.DESERT_HILLS || this.biome == Biome.BEACH || this.environment != Environment.NORMAL || this.aggressiveMode)
|
||||
{
|
||||
this.playerBlocks.add(Material.LEAVES.getId());
|
||||
this.playerBlocks.add(Material.LOG.getId());
|
||||
}
|
||||
this.playerBlocks.addAll(RestoreNatureProcessingTask.getPlayerBlocks(this.environment, this.biome));
|
||||
|
||||
//in aggressive or creative world mode, also treat these blocks as user placed, to be removed
|
||||
//this is helpful in the few cases where griefers intentionally use natural blocks to grief,
|
||||
|
|
@ -199,6 +97,8 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
|
||||
if(this.aggressiveMode)
|
||||
{
|
||||
this.playerBlocks.add(Material.LEAVES.getId());
|
||||
this.playerBlocks.add(Material.LOG.getId());
|
||||
this.playerBlocks.add(Material.LEAVES.getId());
|
||||
this.playerBlocks.add(Material.VINE.getId());
|
||||
}
|
||||
|
|
@ -215,15 +115,15 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
//remove any blocks which are definitely player placed
|
||||
this.removePlayerBlocks();
|
||||
|
||||
//remove natural blocks which are unnaturally hanging in the air
|
||||
this.removeHanging();
|
||||
|
||||
//reduce large outcroppings of stone, sandstone
|
||||
this.reduceStone();
|
||||
|
||||
//reduce logs, except in jungle biomes
|
||||
this.reduceLogs();
|
||||
|
||||
//remove natural blocks which are unnaturally hanging in the air
|
||||
this.removeHanging();
|
||||
|
||||
//remove natural blocks which are unnaturally stacked high
|
||||
this.removeWallsAndTowers();
|
||||
|
||||
|
|
@ -257,13 +157,13 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
for(int z = 1; z < snapshots[0][0].length - 1; z++)
|
||||
{
|
||||
//replace air, lava, or running water at sea level with stone
|
||||
if(this.snapshots[x][this.seaLevel - 3][z].typeId == Material.AIR.getId() || this.snapshots[x][this.seaLevel][z].typeId == Material.LAVA.getId() || (this.snapshots[x][this.seaLevel][z].typeId == Material.WATER.getId() || this.snapshots[x][this.seaLevel][z].data != 0))
|
||||
if(this.snapshots[x][this.seaLevel - 3][z].typeId == Material.AIR.getId() || this.snapshots[x][this.seaLevel - 3][z].typeId == Material.LAVA.getId() || (this.snapshots[x][this.seaLevel - 3][z].typeId == Material.WATER.getId() || this.snapshots[x][this.seaLevel - 3][z].data != 0))
|
||||
{
|
||||
this.snapshots[x][this.seaLevel - 3][z].typeId = Material.STONE.getId();
|
||||
}
|
||||
|
||||
//do the same for one layer beneath that (because a future restoration step may convert surface stone to sand, which falls down)
|
||||
if(this.snapshots[x][this.seaLevel - 4][z].typeId == Material.AIR.getId() || this.snapshots[x][this.seaLevel][z].typeId == Material.LAVA.getId() || (this.snapshots[x][this.seaLevel][z].typeId == Material.WATER.getId() || this.snapshots[x][this.seaLevel][z].data != 0))
|
||||
if(this.snapshots[x][this.seaLevel - 4][z].typeId == Material.AIR.getId() || this.snapshots[x][this.seaLevel - 4][z].typeId == Material.LAVA.getId() || (this.snapshots[x][this.seaLevel - 4][z].typeId == Material.WATER.getId() || this.snapshots[x][this.seaLevel - 4][z].data != 0))
|
||||
{
|
||||
this.snapshots[x][this.seaLevel - 4][z].typeId = Material.STONE.getId();
|
||||
}
|
||||
|
|
@ -696,4 +596,119 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
|
||||
return y;
|
||||
}
|
||||
|
||||
static ArrayList<Integer> getPlayerBlocks(Environment environment, Biome biome)
|
||||
{
|
||||
//NOTE on this list. why not make a list of natural blocks?
|
||||
//answer: better to leave a few player blocks than to remove too many natural blocks. remember we're "restoring nature"
|
||||
//a few extra player blocks can be manually removed, but it will be impossible to guess exactly which natural materials to use in manual repair of an overzealous block removal
|
||||
ArrayList<Integer> playerBlocks = new ArrayList<Integer>();
|
||||
playerBlocks.add(Material.FIRE.getId());
|
||||
playerBlocks.add(Material.BED_BLOCK.getId());
|
||||
playerBlocks.add(Material.WOOD.getId());
|
||||
playerBlocks.add(Material.BOOKSHELF.getId());
|
||||
playerBlocks.add(Material.BREWING_STAND.getId());
|
||||
playerBlocks.add(Material.BRICK.getId());
|
||||
playerBlocks.add(Material.COBBLESTONE.getId());
|
||||
playerBlocks.add(Material.GLASS.getId());
|
||||
playerBlocks.add(Material.LAPIS_BLOCK.getId());
|
||||
playerBlocks.add(Material.DISPENSER.getId());
|
||||
playerBlocks.add(Material.NOTE_BLOCK.getId());
|
||||
playerBlocks.add(Material.POWERED_RAIL.getId());
|
||||
playerBlocks.add(Material.DETECTOR_RAIL.getId());
|
||||
playerBlocks.add(Material.PISTON_STICKY_BASE.getId());
|
||||
playerBlocks.add(Material.PISTON_BASE.getId());
|
||||
playerBlocks.add(Material.PISTON_EXTENSION.getId());
|
||||
playerBlocks.add(Material.WOOL.getId());
|
||||
playerBlocks.add(Material.PISTON_MOVING_PIECE.getId());
|
||||
playerBlocks.add(Material.GOLD_BLOCK.getId());
|
||||
playerBlocks.add(Material.IRON_BLOCK.getId());
|
||||
playerBlocks.add(Material.DOUBLE_STEP.getId());
|
||||
playerBlocks.add(Material.STEP.getId());
|
||||
playerBlocks.add(Material.CROPS.getId());
|
||||
playerBlocks.add(Material.TNT.getId());
|
||||
playerBlocks.add(Material.MOSSY_COBBLESTONE.getId());
|
||||
playerBlocks.add(Material.TORCH.getId());
|
||||
playerBlocks.add(Material.FIRE.getId());
|
||||
playerBlocks.add(Material.WOOD_STAIRS.getId());
|
||||
playerBlocks.add(Material.CHEST.getId());
|
||||
playerBlocks.add(Material.REDSTONE_WIRE.getId());
|
||||
playerBlocks.add(Material.DIAMOND_BLOCK.getId());
|
||||
playerBlocks.add(Material.WORKBENCH.getId());
|
||||
playerBlocks.add(Material.SOIL.getId());
|
||||
playerBlocks.add(Material.FURNACE.getId());
|
||||
playerBlocks.add(Material.BURNING_FURNACE.getId());
|
||||
playerBlocks.add(Material.WOODEN_DOOR.getId());
|
||||
playerBlocks.add(Material.SIGN_POST.getId());
|
||||
playerBlocks.add(Material.LADDER.getId());
|
||||
playerBlocks.add(Material.RAILS.getId());
|
||||
playerBlocks.add(Material.COBBLESTONE_STAIRS.getId());
|
||||
playerBlocks.add(Material.WALL_SIGN.getId());
|
||||
playerBlocks.add(Material.STONE_PLATE.getId());
|
||||
playerBlocks.add(Material.LEVER.getId());
|
||||
playerBlocks.add(Material.IRON_DOOR_BLOCK.getId());
|
||||
playerBlocks.add(Material.WOOD_PLATE.getId());
|
||||
playerBlocks.add(Material.REDSTONE_TORCH_ON.getId());
|
||||
playerBlocks.add(Material.REDSTONE_TORCH_OFF.getId());
|
||||
playerBlocks.add(Material.STONE_BUTTON.getId());
|
||||
playerBlocks.add(Material.SNOW_BLOCK.getId());
|
||||
playerBlocks.add(Material.JUKEBOX.getId());
|
||||
playerBlocks.add(Material.FENCE.getId());
|
||||
playerBlocks.add(Material.PORTAL.getId());
|
||||
playerBlocks.add(Material.JACK_O_LANTERN.getId());
|
||||
playerBlocks.add(Material.CAKE_BLOCK.getId());
|
||||
playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
playerBlocks.add(Material.DIODE_BLOCK_OFF.getId());
|
||||
playerBlocks.add(Material.TRAP_DOOR.getId());
|
||||
playerBlocks.add(Material.SMOOTH_BRICK.getId());
|
||||
playerBlocks.add(Material.HUGE_MUSHROOM_1.getId());
|
||||
playerBlocks.add(Material.HUGE_MUSHROOM_2.getId());
|
||||
playerBlocks.add(Material.IRON_FENCE.getId());
|
||||
playerBlocks.add(Material.THIN_GLASS.getId());
|
||||
playerBlocks.add(Material.MELON_STEM.getId());
|
||||
playerBlocks.add(Material.FENCE_GATE.getId());
|
||||
playerBlocks.add(Material.BRICK_STAIRS.getId());
|
||||
playerBlocks.add(Material.SMOOTH_STAIRS.getId());
|
||||
playerBlocks.add(Material.ENCHANTMENT_TABLE.getId());
|
||||
playerBlocks.add(Material.BREWING_STAND.getId());
|
||||
playerBlocks.add(Material.CAULDRON.getId());
|
||||
playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
playerBlocks.add(Material.WEB.getId());
|
||||
playerBlocks.add(Material.SPONGE.getId());
|
||||
playerBlocks.add(Material.GRAVEL.getId());
|
||||
playerBlocks.add(Material.EMERALD_BLOCK.getId());
|
||||
playerBlocks.add(Material.SANDSTONE.getId());
|
||||
playerBlocks.add(Material.WOOD_STEP.getId());
|
||||
playerBlocks.add(Material.WOOD_DOUBLE_STEP.getId());
|
||||
playerBlocks.add(Material.ENDER_CHEST.getId());
|
||||
|
||||
//these are unnatural in the standard world, but not in the nether
|
||||
if(environment != Environment.NETHER)
|
||||
{
|
||||
playerBlocks.add(Material.NETHERRACK.getId());
|
||||
playerBlocks.add(Material.SOUL_SAND.getId());
|
||||
playerBlocks.add(Material.GLOWSTONE.getId());
|
||||
playerBlocks.add(Material.NETHER_BRICK.getId());
|
||||
playerBlocks.add(Material.NETHER_FENCE.getId());
|
||||
playerBlocks.add(Material.NETHER_BRICK_STAIRS.getId());
|
||||
}
|
||||
|
||||
//these are unnatural in the standard and nether worlds, but not in the end
|
||||
if(environment != Environment.THE_END)
|
||||
{
|
||||
playerBlocks.add(Material.OBSIDIAN.getId());
|
||||
playerBlocks.add(Material.ENDER_STONE.getId());
|
||||
playerBlocks.add(Material.ENDER_PORTAL_FRAME.getId());
|
||||
}
|
||||
|
||||
//these are unnatural in sandy biomes, but not elsewhere
|
||||
if(biome == Biome.DESERT || biome == Biome.DESERT_HILLS || biome == Biome.BEACH || environment != Environment.NORMAL)
|
||||
{
|
||||
playerBlocks.add(Material.LEAVES.getId());
|
||||
playerBlocks.add(Material.LOG.getId());
|
||||
}
|
||||
|
||||
return playerBlocks;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user