PageRenderTime 129ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java

https://gitlab.com/Slind/GriefPrevention
Java | 812 lines | 601 code | 125 blank | 86 comment | 75 complexity | 2cfef57ae14d2cd226f5ecf73b2293a3 MD5 | raw file
  1. /*
  2. GriefPrevention Server Plugin for Minecraft
  3. Copyright (C) 2012 Ryan Hamshire
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package me.ryanhamshire.GriefPrevention;
  16. import java.io.File;
  17. import java.io.IOException;
  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map.Entry;
  23. import java.util.UUID;
  24. import java.util.Vector;
  25. import java.util.concurrent.ConcurrentHashMap;
  26. import java.util.logging.Logger;
  27. import java.util.regex.Matcher;
  28. import java.util.regex.Pattern;
  29. import me.ryanhamshire.GriefPrevention.DataStore.NoTransferException;
  30. import net.milkbowl.vault.economy.Economy;
  31. import org.bukkit.Achievement;
  32. import org.bukkit.BanList;
  33. import org.bukkit.Bukkit;
  34. import org.bukkit.ChatColor;
  35. import org.bukkit.Chunk;
  36. import org.bukkit.ChunkSnapshot;
  37. import org.bukkit.GameMode;
  38. import org.bukkit.Location;
  39. import org.bukkit.Material;
  40. import org.bukkit.OfflinePlayer;
  41. import org.bukkit.World;
  42. import org.bukkit.BanList.Type;
  43. import org.bukkit.World.Environment;
  44. import org.bukkit.block.Block;
  45. import org.bukkit.block.BlockFace;
  46. import org.bukkit.command.*;
  47. import org.bukkit.configuration.file.FileConfiguration;
  48. import org.bukkit.configuration.file.YamlConfiguration;
  49. import org.bukkit.entity.Player;
  50. import org.bukkit.inventory.ItemStack;
  51. import org.bukkit.inventory.PlayerInventory;
  52. import org.bukkit.plugin.PluginManager;
  53. import org.bukkit.plugin.RegisteredServiceProvider;
  54. import org.bukkit.plugin.java.JavaPlugin;
  55. import org.bukkit.util.BlockIterator;
  56. public class GriefPrevention extends JavaPlugin
  57. {
  58. //for convenience, a reference to the instance of this plugin
  59. public static GriefPrevention instance;
  60. //for logging to the console and log file
  61. private static Logger log = Logger.getLogger("Minecraft");
  62. //this handles data storage, like player and region data
  63. public DataStore dataStore;
  64. //this tracks item stacks expected to drop which will need protection
  65. ArrayList<PendingItemProtection> pendingItemWatchList = new ArrayList<PendingItemProtection>();
  66. //log entry manager for GP's custom log files
  67. CustomLogger customLogger;
  68. //configuration variables, loaded/saved from a config.yml
  69. //claim mode for each world
  70. public ConcurrentHashMap<World, ClaimsMode> config_claims_worldModes;
  71. public boolean config_claims_preventTheft; //whether containers and crafting blocks are protectable
  72. public boolean config_claims_protectCreatures; //whether claimed animals may be injured by players without permission
  73. public boolean config_claims_protectFires; //whether open flint+steel flames should be protected - optional because it's expensive
  74. public boolean config_claims_protectHorses; //whether horses on a claim should be protected by that claim's rules
  75. public boolean config_claims_preventButtonsSwitches; //whether buttons and switches are protectable
  76. public boolean config_claims_lockWoodenDoors; //whether wooden doors should be locked by default (require /accesstrust)
  77. public boolean config_claims_lockTrapDoors; //whether trap doors should be locked by default (require /accesstrust)
  78. public boolean config_claims_lockFenceGates; //whether fence gates should be locked by default (require /accesstrust)
  79. public boolean config_claims_enderPearlsRequireAccessTrust; //whether teleporting into a claim with a pearl requires access trust
  80. public int config_claims_maxClaimsPerPlayer; //maximum number of claims per player
  81. public boolean config_claims_respectWorldGuard; //whether claim creations requires WG build permission in creation area
  82. public boolean config_claims_portalsRequirePermission; //whether nether portals require permission to generate. defaults to off for performance reasons
  83. public boolean config_claims_villagerTradingRequiresTrust; //whether trading with a claimed villager requires permission
  84. public int config_claims_initialBlocks; //the number of claim blocks a new player starts with
  85. public double config_claims_abandonReturnRatio; //the portion of claim blocks returned to a player when a claim is abandoned
  86. public int config_claims_blocksAccruedPerHour; //how many additional blocks players get each hour of play (can be zero)
  87. public int config_claims_maxAccruedBlocks; //the limit on accrued blocks (over time). doesn't limit purchased or admin-gifted blocks
  88. public int config_claims_maxDepth; //limit on how deep claims can go
  89. public int config_claims_expirationDays; //how many days of inactivity before a player loses his claims
  90. public int config_claims_expirationExemptionTotalBlocks; //total claim blocks amount which will exempt a player from claim expiration
  91. public int config_claims_expirationExemptionBonusBlocks; //bonus claim blocks amount which will exempt a player from claim expiration
  92. public int config_claims_automaticClaimsForNewPlayersRadius; //how big automatic new player claims (when they place a chest) should be. 0 to disable
  93. public int config_claims_claimsExtendIntoGroundDistance; //how far below the shoveled block a new claim will reach
  94. public int config_claims_minWidth; //minimum width for non-admin claims
  95. public int config_claims_minArea; //minimum area for non-admin claims
  96. public int config_claims_chestClaimExpirationDays; //number of days of inactivity before an automatic chest claim will be deleted
  97. public int config_claims_unusedClaimExpirationDays; //number of days of inactivity before an unused (nothing build) claim will be deleted
  98. public boolean config_claims_survivalAutoNatureRestoration; //whether survival claims will be automatically restored to nature when auto-deleted
  99. public Material config_claims_investigationTool; //which material will be used to investigate claims with a right click
  100. public Material config_claims_modificationTool; //which material will be used to create/resize claims with a right click
  101. public ArrayList<String> config_claims_commandsRequiringAccessTrust; //the list of slash commands requiring access trust when in a claim
  102. public boolean config_claims_supplyPlayerManual; //whether to give new players a book with land claim help in it
  103. public int config_claims_manualDeliveryDelaySeconds; //how long to wait before giving a book to a new player
  104. public ArrayList<World> config_siege_enabledWorlds; //whether or not /siege is enabled on this server
  105. public ArrayList<Material> config_siege_blocks; //which blocks will be breakable in siege mode
  106. public boolean config_spam_enabled; //whether or not to monitor for spam
  107. public int config_spam_loginCooldownSeconds; //how long players must wait between logins. combats login spam.
  108. public ArrayList<String> config_spam_monitorSlashCommands; //the list of slash commands monitored for spam
  109. public boolean config_spam_banOffenders; //whether or not to ban spammers automatically
  110. public String config_spam_banMessage; //message to show an automatically banned player
  111. public String config_spam_warningMessage; //message to show a player who is close to spam level
  112. public String config_spam_allowedIpAddresses; //IP addresses which will not be censored
  113. public int config_spam_deathMessageCooldownSeconds; //cooldown period for death messages (per player) in seconds
  114. HashMap<World, Boolean> config_pvp_specifiedWorlds; //list of worlds where pvp anti-grief rules apply, according to the config file
  115. public boolean config_pvp_protectFreshSpawns; //whether to make newly spawned players immune until they pick up an item
  116. public boolean config_pvp_punishLogout; //whether to kill players who log out during PvP combat
  117. public int config_pvp_combatTimeoutSeconds; //how long combat is considered to continue after the most recent damage
  118. public boolean config_pvp_allowCombatItemDrop; //whether a player can drop items during combat to hide them
  119. public ArrayList<String> config_pvp_blockedCommands; //list of commands which may not be used during pvp combat
  120. public boolean config_pvp_noCombatInPlayerLandClaims; //whether players may fight in player-owned land claims
  121. public boolean config_pvp_noCombatInAdminLandClaims; //whether players may fight in admin-owned land claims
  122. public boolean config_pvp_noCombatInAdminSubdivisions; //whether players may fight in subdivisions of admin-owned land claims
  123. public boolean config_pvp_allowLavaNearPlayers; //whether players may dump lava near other players in pvp worlds
  124. public boolean config_pvp_allowFireNearPlayers; //whether players may start flint/steel fires near other players in pvp worlds
  125. public boolean config_pvp_protectPets; //whether players may damage pets outside of land claims in pvp worlds
  126. public boolean config_lockDeathDropsInPvpWorlds; //whether players' dropped on death items are protected in pvp worlds
  127. public boolean config_lockDeathDropsInNonPvpWorlds; //whether players' dropped on death items are protected in non-pvp worlds
  128. public double config_economy_claimBlocksPurchaseCost; //cost to purchase a claim block. set to zero to disable purchase.
  129. public double config_economy_claimBlocksSellValue; //return on a sold claim block. set to zero to disable sale.
  130. public boolean config_blockClaimExplosions; //whether explosions may destroy claimed blocks
  131. public boolean config_blockSurfaceCreeperExplosions; //whether creeper explosions near or above the surface destroy blocks
  132. public boolean config_blockSurfaceOtherExplosions; //whether non-creeper explosions near or above the surface destroy blocks
  133. public boolean config_blockSkyTrees; //whether players can build trees on platforms in the sky
  134. public boolean config_fireSpreads; //whether fire spreads outside of claims
  135. public boolean config_fireDestroys; //whether fire destroys blocks outside of claims
  136. public boolean config_whisperNotifications; //whether whispered messages will broadcast to administrators in game
  137. public boolean config_signNotifications; //whether sign content will broadcast to administrators in game
  138. public ArrayList<String> config_eavesdrop_whisperCommands; //list of whisper commands to eavesdrop on
  139. public boolean config_smartBan; //whether to ban accounts which very likely owned by a banned player
  140. public boolean config_endermenMoveBlocks; //whether or not endermen may move blocks around
  141. public boolean config_silverfishBreakBlocks; //whether silverfish may break blocks
  142. public boolean config_creaturesTrampleCrops; //whether or not non-player entities may trample crops
  143. public boolean config_rabbitsEatCrops; //whether or not rabbits may eat crops
  144. public boolean config_zombiesBreakDoors; //whether or not hard-mode zombies may break down wooden doors
  145. public int config_ipLimit; //how many players can share an IP address
  146. public MaterialCollection config_mods_accessTrustIds; //list of block IDs which should require /accesstrust for player interaction
  147. public MaterialCollection config_mods_containerTrustIds; //list of block IDs which should require /containertrust for player interaction
  148. public List<String> config_mods_ignoreClaimsAccounts; //list of player names which ALWAYS ignore claims
  149. public MaterialCollection config_mods_explodableIds; //list of block IDs which can be destroyed by explosions, even in claimed areas
  150. public HashMap<String, Integer> config_seaLevelOverride; //override for sea level, because bukkit doesn't report the right value for all situations
  151. public boolean config_limitTreeGrowth; //whether trees should be prevented from growing into a claim from outside
  152. public boolean config_pistonsInClaimsOnly; //whether pistons are limited to only move blocks located within the piston's land claim
  153. //custom log settings
  154. public int config_logs_daysToKeep;
  155. public boolean config_logs_socialEnabled;
  156. public boolean config_logs_suspiciousEnabled;
  157. public boolean config_logs_adminEnabled;
  158. public boolean config_logs_debugEnabled;
  159. public boolean config_logs_mutedChatEnabled;
  160. //ban management plugin interop settings
  161. public boolean config_ban_useCommand;
  162. public String config_ban_commandFormat;
  163. private String databaseUrl;
  164. private String databaseUserName;
  165. private String databasePassword;
  166. //reference to the economy plugin, if economy integration is enabled
  167. public static Economy economy = null;
  168. //how far away to search from a tree trunk for its branch blocks
  169. public static final int TREE_RADIUS = 5;
  170. //how long to wait before deciding a player is staying online or staying offline, for notication messages
  171. public static final int NOTIFICATION_SECONDS = 20;
  172. //adds a server log entry
  173. public static synchronized void AddLogEntry(String entry, CustomLogEntryTypes customLogType, boolean excludeFromServerLogs)
  174. {
  175. if(customLogType != null && GriefPrevention.instance.customLogger != null)
  176. {
  177. GriefPrevention.instance.customLogger.AddEntry(entry, customLogType);
  178. }
  179. if(!excludeFromServerLogs) log.info("GriefPrevention: " + entry);
  180. }
  181. public static synchronized void AddLogEntry(String entry, CustomLogEntryTypes customLogType)
  182. {
  183. AddLogEntry(entry, customLogType, false);
  184. }
  185. public static synchronized void AddLogEntry(String entry)
  186. {
  187. AddLogEntry(entry, CustomLogEntryTypes.Debug);
  188. }
  189. //initializes well... everything
  190. public void onEnable()
  191. {
  192. instance = this;
  193. AddLogEntry("Grief Prevention boot start.");
  194. this.loadConfig();
  195. this.customLogger = new CustomLogger();
  196. AddLogEntry("Finished loading configuration.");
  197. //when datastore initializes, it loads player and claim data, and posts some stats to the log
  198. if(this.databaseUrl.length() > 0)
  199. {
  200. try
  201. {
  202. DatabaseDataStore databaseStore = new DatabaseDataStore(this.databaseUrl, this.databaseUserName, this.databasePassword);
  203. if(FlatFileDataStore.hasData())
  204. {
  205. GriefPrevention.AddLogEntry("There appears to be some data on the hard drive. Migrating those data to the database...");
  206. FlatFileDataStore flatFileStore = new FlatFileDataStore();
  207. this.dataStore = flatFileStore;
  208. flatFileStore.migrateData(databaseStore);
  209. GriefPrevention.AddLogEntry("Data migration process complete. Reloading data from the database...");
  210. databaseStore.close();
  211. databaseStore = new DatabaseDataStore(this.databaseUrl, this.databaseUserName, this.databasePassword);
  212. }
  213. this.dataStore = databaseStore;
  214. }
  215. catch(Exception e)
  216. {
  217. GriefPrevention.AddLogEntry("Because there was a problem with the database, GriefPrevention will not function properly. Either update the database config settings resolve the issue, or delete those lines from your config.yml so that GriefPrevention can use the file system to store data.");
  218. e.printStackTrace();
  219. return;
  220. }
  221. }
  222. //if not using the database because it's not configured or because there was a problem, use the file system to store data
  223. //this is the preferred method, as it's simpler than the database scenario
  224. if(this.dataStore == null)
  225. {
  226. File oldclaimdata = new File(getDataFolder(), "ClaimData");
  227. if(oldclaimdata.exists()) {
  228. if(!FlatFileDataStore.hasData()) {
  229. File claimdata = new File("plugins" + File.separator + "GriefPreventionData" + File.separator + "ClaimData");
  230. oldclaimdata.renameTo(claimdata);
  231. File oldplayerdata = new File(getDataFolder(), "PlayerData");
  232. File playerdata = new File("plugins" + File.separator + "GriefPreventionData" + File.separator + "PlayerData");
  233. oldplayerdata.renameTo(playerdata);
  234. }
  235. }
  236. try
  237. {
  238. this.dataStore = new FlatFileDataStore();
  239. }
  240. catch(Exception e)
  241. {
  242. GriefPrevention.AddLogEntry("Unable to initialize the file system data store. Details:");
  243. GriefPrevention.AddLogEntry(e.getMessage());
  244. e.printStackTrace();
  245. }
  246. }
  247. String dataMode = (this.dataStore instanceof FlatFileDataStore)?"(File Mode)":"(Database Mode)";
  248. AddLogEntry("Finished loading data " + dataMode + ".");
  249. //unless claim block accrual is disabled, start the recurring per 10 minute event to give claim blocks to online players
  250. //20L ~ 1 second
  251. if(this.config_claims_blocksAccruedPerHour > 0)
  252. {
  253. DeliverClaimBlocksTask task = new DeliverClaimBlocksTask(null);
  254. this.getServer().getScheduler().scheduleSyncRepeatingTask(this, task, 20L * 60 * 10, 20L * 60 * 10);
  255. }
  256. //start the recurring cleanup event for entities in creative worlds
  257. EntityCleanupTask task = new EntityCleanupTask(0);
  258. this.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * 60 * 2);
  259. //start recurring cleanup scan for unused claims belonging to inactive players
  260. FindUnusedClaimsTask task2 = new FindUnusedClaimsTask();
  261. this.getServer().getScheduler().scheduleSyncRepeatingTask(this, task2, 20L * 60, 20L * 60);
  262. //register for events
  263. PluginManager pluginManager = this.getServer().getPluginManager();
  264. //player events
  265. PlayerEventHandler playerEventHandler = new PlayerEventHandler(this.dataStore, this);
  266. pluginManager.registerEvents(playerEventHandler, this);
  267. //block events
  268. BlockEventHandler blockEventHandler = new BlockEventHandler(this.dataStore);
  269. pluginManager.registerEvents(blockEventHandler, this);
  270. //entity events
  271. EntityEventHandler entityEventHandler = new EntityEventHandler(this.dataStore);
  272. pluginManager.registerEvents(entityEventHandler, this);
  273. //if economy is enabled
  274. if(this.config_economy_claimBlocksPurchaseCost > 0 || this.config_economy_claimBlocksSellValue > 0)
  275. {
  276. //try to load Vault
  277. GriefPrevention.AddLogEntry("GriefPrevention requires Vault for economy integration.");
  278. GriefPrevention.AddLogEntry("Attempting to load Vault...");
  279. RegisteredServiceProvider<Economy> economyProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
  280. GriefPrevention.AddLogEntry("Vault loaded successfully!");
  281. //ask Vault to hook into an economy plugin
  282. GriefPrevention.AddLogEntry("Looking for a Vault-compatible economy plugin...");
  283. if (economyProvider != null)
  284. {
  285. GriefPrevention.economy = economyProvider.getProvider();
  286. //on success, display success message
  287. if(GriefPrevention.economy != null)
  288. {
  289. GriefPrevention.AddLogEntry("Hooked into economy: " + GriefPrevention.economy.getName() + ".");
  290. GriefPrevention.AddLogEntry("Ready to buy/sell claim blocks!");
  291. }
  292. //otherwise error message
  293. else
  294. {
  295. 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.");
  296. }
  297. }
  298. //another error case
  299. else
  300. {
  301. 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.");
  302. }
  303. }
  304. //cache offline players
  305. OfflinePlayer [] offlinePlayers = this.getServer().getOfflinePlayers();
  306. CacheOfflinePlayerNamesThread namesThread = new CacheOfflinePlayerNamesThread(offlinePlayers, this.playerNameToIDMap);
  307. namesThread.setPriority(Thread.MIN_PRIORITY);
  308. namesThread.start();
  309. //load ignore lists for any already-online players
  310. @SuppressWarnings("unchecked")
  311. Collection<Player> players = (Collection<Player>)GriefPrevention.instance.getServer().getOnlinePlayers();
  312. for(Player player : players)
  313. {
  314. new IgnoreLoaderThread(player.getUniqueId(), this.dataStore.getPlayerData(player.getUniqueId()).ignoredPlayers).start();
  315. }
  316. AddLogEntry("Boot finished.");
  317. }
  318. private void loadConfig()
  319. {
  320. //load the config if it exists
  321. FileConfiguration config = YamlConfiguration.loadConfiguration(new File(DataStore.configFilePath));
  322. FileConfiguration outConfig = new YamlConfiguration();
  323. outConfig.options().header("Default values are perfect for most servers. If you want to customize and have a question, look for the answer here first: http://dev.bukkit.org/bukkit-plugins/grief-prevention/pages/setup-and-configuration/");
  324. //read configuration settings (note defaults)
  325. //get (deprecated node) claims world names from the config file
  326. List<World> worlds = this.getServer().getWorlds();
  327. List<String> deprecated_claimsEnabledWorldNames = config.getStringList("GriefPrevention.Claims.Worlds");
  328. //validate that list
  329. for(int i = 0; i < deprecated_claimsEnabledWorldNames.size(); i++)
  330. {
  331. String worldName = deprecated_claimsEnabledWorldNames.get(i);
  332. World world = this.getServer().getWorld(worldName);
  333. if(world == null)
  334. {
  335. deprecated_claimsEnabledWorldNames.remove(i--);
  336. }
  337. }
  338. //get (deprecated node) creative world names from the config file
  339. List<String> deprecated_creativeClaimsEnabledWorldNames = config.getStringList("GriefPrevention.Claims.CreativeRulesWorlds");
  340. //validate that list
  341. for(int i = 0; i < deprecated_creativeClaimsEnabledWorldNames.size(); i++)
  342. {
  343. String worldName = deprecated_creativeClaimsEnabledWorldNames.get(i);
  344. World world = this.getServer().getWorld(worldName);
  345. if(world == null)
  346. {
  347. deprecated_claimsEnabledWorldNames.remove(i--);
  348. }
  349. }
  350. //decide claim mode for each world
  351. this.config_claims_worldModes = new ConcurrentHashMap<World, ClaimsMode>();
  352. for(World world : worlds)
  353. {
  354. //is it specified in the config file?
  355. String configSetting = config.getString("GriefPrevention.Claims.Mode." + world.getName());
  356. if(configSetting != null)
  357. {
  358. ClaimsMode claimsMode = this.configStringToClaimsMode(configSetting);
  359. if(claimsMode != null)
  360. {
  361. this.config_claims_worldModes.put(world, claimsMode);
  362. continue;
  363. }
  364. else
  365. {
  366. GriefPrevention.AddLogEntry("Error: Invalid claim mode \"" + configSetting + "\". Options are Survival, Creative, and Disabled.");
  367. this.config_claims_worldModes.put(world, ClaimsMode.Creative);
  368. }
  369. }
  370. //was it specified in a deprecated config node?
  371. if(deprecated_creativeClaimsEnabledWorldNames.contains(world.getName()))
  372. {
  373. this.config_claims_worldModes.put(world, ClaimsMode.Creative);
  374. }
  375. else if(deprecated_claimsEnabledWorldNames.contains(world.getName()))
  376. {
  377. this.config_claims_worldModes.put(world, ClaimsMode.Survival);
  378. }
  379. //does the world's name indicate its purpose?
  380. else if(world.getName().toLowerCase().contains("survival"))
  381. {
  382. this.config_claims_worldModes.put(world, ClaimsMode.Survival);
  383. }
  384. else if(world.getName().toLowerCase().contains("creative"))
  385. {
  386. this.config_claims_worldModes.put(world, ClaimsMode.Creative);
  387. }
  388. //decide a default based on server type and world type
  389. else if(this.getServer().getDefaultGameMode() == GameMode.CREATIVE)
  390. {
  391. this.config_claims_worldModes.put(world, ClaimsMode.Creative);
  392. }
  393. else if(world.getEnvironment() == Environment.NORMAL)
  394. {
  395. this.config_claims_worldModes.put(world, ClaimsMode.Survival);
  396. }
  397. else
  398. {
  399. this.config_claims_worldModes.put(world, ClaimsMode.Disabled);
  400. }
  401. //if the setting WOULD be disabled but this is a server upgrading from the old config format,
  402. //then default to survival mode for safety's sake (to protect any admin claims which may
  403. //have been created there)
  404. if(this.config_claims_worldModes.get(world) == ClaimsMode.Disabled &&
  405. deprecated_claimsEnabledWorldNames.size() > 0)
  406. {
  407. this.config_claims_worldModes.put(world, ClaimsMode.Survival);
  408. }
  409. }
  410. //pvp worlds list
  411. this.config_pvp_specifiedWorlds = new HashMap<World, Boolean>();
  412. for(World world : worlds)
  413. {
  414. boolean pvpWorld = config.getBoolean("GriefPrevention.PvP.RulesEnabledInWorld." + world.getName(), world.getPVP());
  415. this.config_pvp_specifiedWorlds.put(world, pvpWorld);
  416. }
  417. //sea level
  418. this.config_seaLevelOverride = new HashMap<String, Integer>();
  419. for(int i = 0; i < worlds.size(); i++)
  420. {
  421. int seaLevelOverride = config.getInt("GriefPrevention.SeaLevelOverrides." + worlds.get(i).getName(), -1);
  422. outConfig.set("GriefPrevention.SeaLevelOverrides." + worlds.get(i).getName(), seaLevelOverride);
  423. this.config_seaLevelOverride.put(worlds.get(i).getName(), seaLevelOverride);
  424. }
  425. this.config_claims_preventTheft = config.getBoolean("GriefPrevention.Claims.PreventTheft", true);
  426. this.config_claims_protectCreatures = config.getBoolean("GriefPrevention.Claims.ProtectCreatures", true);
  427. this.config_claims_protectFires = config.getBoolean("GriefPrevention.Claims.ProtectFires", false);
  428. this.config_claims_protectHorses = config.getBoolean("GriefPrevention.Claims.ProtectHorses", true);
  429. this.config_claims_preventButtonsSwitches = config.getBoolean("GriefPrevention.Claims.PreventButtonsSwitches", true);
  430. this.config_claims_lockWoodenDoors = config.getBoolean("GriefPrevention.Claims.LockWoodenDoors", false);
  431. this.config_claims_lockTrapDoors = config.getBoolean("GriefPrevention.Claims.LockTrapDoors", false);
  432. this.config_claims_lockFenceGates = config.getBoolean("GriefPrevention.Claims.LockFenceGates", true);
  433. this.config_claims_enderPearlsRequireAccessTrust = config.getBoolean("GriefPrevention.Claims.EnderPearlsRequireAccessTrust", true);
  434. this.config_claims_initialBlocks = config.getInt("GriefPrevention.Claims.InitialBlocks", 100);
  435. this.config_claims_blocksAccruedPerHour = config.getInt("GriefPrevention.Claims.BlocksAccruedPerHour", 100);
  436. this.config_claims_maxAccruedBlocks = config.getInt("GriefPrevention.Claims.MaxAccruedBlocks", 80000);
  437. this.config_claims_abandonReturnRatio = config.getDouble("GriefPrevention.Claims.AbandonReturnRatio", 1);
  438. this.config_claims_automaticClaimsForNewPlayersRadius = config.getInt("GriefPrevention.Claims.AutomaticNewPlayerClaimsRadius", 4);
  439. this.config_claims_claimsExtendIntoGroundDistance = Math.abs(config.getInt("GriefPrevention.Claims.ExtendIntoGroundDistance", 5));
  440. this.config_claims_minWidth = config.getInt("GriefPrevention.Claims.MinimumWidth", 5);
  441. this.config_claims_minArea = config.getInt("GriefPrevention.Claims.MinimumArea", 100);
  442. this.config_claims_maxDepth = config.getInt("GriefPrevention.Claims.MaximumDepth", 0);
  443. this.config_claims_chestClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.ChestClaimDays", 7);
  444. this.config_claims_unusedClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.UnusedClaimDays", 14);
  445. this.config_claims_expirationDays = config.getInt("GriefPrevention.Claims.Expiration.AllClaims.DaysInactive", 60);
  446. this.config_claims_expirationExemptionTotalBlocks = config.getInt("GriefPrevention.Claims.Expiration.AllClaims.ExceptWhenOwnerHasTotalClaimBlocks", 10000);
  447. this.config_claims_expirationExemptionBonusBlocks = config.getInt("GriefPrevention.Claims.Expiration.AllClaims.ExceptWhenOwnerHasBonusClaimBlocks", 5000);
  448. this.config_claims_survivalAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", false);
  449. this.config_claims_maxClaimsPerPlayer = config.getInt("GriefPrevention.Claims.MaximumNumberOfClaimsPerPlayer", 0);
  450. this.config_claims_respectWorldGuard = config.getBoolean("GriefPrevention.Claims.CreationRequiresWorldGuardBuildPermission", true);
  451. this.config_claims_portalsRequirePermission = config.getBoolean("GriefPrevention.Claims.PortalGenerationRequiresPermission", false);
  452. this.config_claims_villagerTradingRequiresTrust = config.getBoolean("GriefPrevention.Claims.VillagerTradingRequiresPermission", true);
  453. String accessTrustSlashCommands = config.getString("GriefPrevention.Claims.CommandsRequiringAccessTrust", "/sethome");
  454. this.config_claims_supplyPlayerManual = config.getBoolean("GriefPrevention.Claims.DeliverManuals", true);
  455. this.config_claims_manualDeliveryDelaySeconds = config.getInt("GriefPrevention.Claims.ManualDeliveryDelaySeconds", 30);
  456. this.config_spam_enabled = config.getBoolean("GriefPrevention.Spam.Enabled", true);
  457. this.config_spam_loginCooldownSeconds = config.getInt("GriefPrevention.Spam.LoginCooldownSeconds", 60);
  458. this.config_spam_warningMessage = config.getString("GriefPrevention.Spam.WarningMessage", "Please reduce your noise level. Spammers will be banned.");
  459. this.config_spam_allowedIpAddresses = config.getString("GriefPrevention.Spam.AllowedIpAddresses", "1.2.3.4; 5.6.7.8");
  460. this.config_spam_banOffenders = config.getBoolean("GriefPrevention.Spam.BanOffenders", true);
  461. this.config_spam_banMessage = config.getString("GriefPrevention.Spam.BanMessage", "Banned for spam.");
  462. String slashCommandsToMonitor = config.getString("GriefPrevention.Spam.MonitorSlashCommands", "/me;/global;/local");
  463. slashCommandsToMonitor = config.getString("GriefPrevention.Spam.ChatSlashCommands", slashCommandsToMonitor);
  464. this.config_spam_deathMessageCooldownSeconds = config.getInt("GriefPrevention.Spam.DeathMessageCooldownSeconds", 60);
  465. this.config_pvp_protectFreshSpawns = config.getBoolean("GriefPrevention.PvP.ProtectFreshSpawns", true);
  466. this.config_pvp_punishLogout = config.getBoolean("GriefPrevention.PvP.PunishLogout", true);
  467. this.config_pvp_combatTimeoutSeconds = config.getInt("GriefPrevention.PvP.CombatTimeoutSeconds", 15);
  468. this.config_pvp_allowCombatItemDrop = config.getBoolean("GriefPrevention.PvP.AllowCombatItemDrop", false);
  469. String bannedPvPCommandsList = config.getString("GriefPrevention.PvP.BlockedSlashCommands", "/home;/vanish;/spawn;/tpa");
  470. this.config_economy_claimBlocksPurchaseCost = config.getDouble("GriefPrevention.Economy.ClaimBlocksPurchaseCost", 0);
  471. this.config_economy_claimBlocksSellValue = config.getDouble("GriefPrevention.Economy.ClaimBlocksSellValue", 0);
  472. this.config_lockDeathDropsInPvpWorlds = config.getBoolean("GriefPrevention.ProtectItemsDroppedOnDeath.PvPWorlds", false);
  473. this.config_lockDeathDropsInNonPvpWorlds = config.getBoolean("GriefPrevention.ProtectItemsDroppedOnDeath.NonPvPWorlds", true);
  474. this.config_blockClaimExplosions = config.getBoolean("GriefPrevention.BlockLandClaimExplosions", true);
  475. this.config_blockSurfaceCreeperExplosions = config.getBoolean("GriefPrevention.BlockSurfaceCreeperExplosions", true);
  476. this.config_blockSurfaceOtherExplosions = config.getBoolean("GriefPrevention.BlockSurfaceOtherExplosions", true);
  477. this.config_blockSkyTrees = config.getBoolean("GriefPrevention.LimitSkyTrees", true);
  478. this.config_limitTreeGrowth = config.getBoolean("GriefPrevention.LimitTreeGrowth", false);
  479. this.config_pistonsInClaimsOnly = config.getBoolean("GriefPrevention.LimitPistonsToLandClaims", true);
  480. this.config_fireSpreads = config.getBoolean("GriefPrevention.FireSpreads", false);
  481. this.config_fireDestroys = config.getBoolean("GriefPrevention.FireDestroys", false);
  482. this.config_whisperNotifications = config.getBoolean("GriefPrevention.AdminsGetWhispers", true);
  483. this.config_signNotifications = config.getBoolean("GriefPrevention.AdminsGetSignNotifications", true);
  484. String whisperCommandsToMonitor = config.getString("GriefPrevention.WhisperCommands", "/tell;/pm;/r;/whisper;/msg");
  485. whisperCommandsToMonitor = config.getString("GriefPrevention.Spam.WhisperSlashCommands", whisperCommandsToMonitor);
  486. this.config_smartBan = config.getBoolean("GriefPrevention.SmartBan", true);
  487. this.config_ipLimit = config.getInt("GriefPrevention.MaxPlayersPerIpAddress", 3);
  488. this.config_endermenMoveBlocks = config.getBoolean("GriefPrevention.EndermenMoveBlocks", false);
  489. this.config_silverfishBreakBlocks = config.getBoolean("GriefPrevention.SilverfishBreakBlocks", false);
  490. this.config_creaturesTrampleCrops = config.getBoolean("GriefPrevention.CreaturesTrampleCrops", false);
  491. this.config_rabbitsEatCrops = config.getBoolean("GriefPrevention.RabbitsEatCrops", true);
  492. this.config_zombiesBreakDoors = config.getBoolean("GriefPrevention.HardModeZombiesBreakDoors", false);
  493. this.config_ban_useCommand = config.getBoolean("GriefPrevention.UseBanCommand", false);
  494. this.config_ban_commandFormat = config.getString("GriefPrevention.BanCommandPattern", "ban %name% %reason%");
  495. this.config_mods_ignoreClaimsAccounts = config.getStringList("GriefPrevention.Mods.PlayersIgnoringAllClaims");
  496. if(this.config_mods_ignoreClaimsAccounts == null) this.config_mods_ignoreClaimsAccounts = new ArrayList<String>();
  497. this.config_mods_accessTrustIds = new MaterialCollection();
  498. List<String> accessTrustStrings = config.getStringList("GriefPrevention.Mods.BlockIdsRequiringAccessTrust");
  499. this.parseMaterialListFromConfig(accessTrustStrings, this.config_mods_accessTrustIds);
  500. this.config_mods_containerTrustIds = new MaterialCollection();
  501. List<String> containerTrustStrings = config.getStringList("GriefPrevention.Mods.BlockIdsRequiringContainerTrust");
  502. //default values for container trust mod blocks
  503. if(containerTrustStrings == null || containerTrustStrings.size() == 0)
  504. {
  505. containerTrustStrings.add(new MaterialInfo(99999, "Example - ID 99999, all data values.").toString());
  506. }
  507. //parse the strings from the config file
  508. this.parseMaterialListFromConfig(containerTrustStrings, this.config_mods_containerTrustIds);
  509. this.config_mods_explodableIds = new MaterialCollection();
  510. List<String> explodableStrings = config.getStringList("GriefPrevention.Mods.BlockIdsExplodable");
  511. //parse the strings from the config file
  512. this.parseMaterialListFromConfig(explodableStrings, this.config_mods_explodableIds);
  513. //default for claim investigation tool
  514. String investigationToolMaterialName = Material.STICK.name();
  515. //get investigation tool from config
  516. investigationToolMaterialName = config.getString("GriefPrevention.Claims.InvestigationTool", investigationToolMaterialName);
  517. //validate investigation tool
  518. this.config_claims_investigationTool = Material.getMaterial(investigationToolMaterialName);
  519. if(this.config_claims_investigationTool == null)
  520. {
  521. GriefPrevention.AddLogEntry("ERROR: Material " + investigationToolMaterialName + " not found. Defaulting to the stick. Please update your config.yml.");
  522. this.config_claims_investigationTool = Material.STICK;
  523. }
  524. //default for claim creation/modification tool
  525. String modificationToolMaterialName = Material.GOLD_SPADE.name();
  526. //get modification tool from config
  527. modificationToolMaterialName = config.getString("GriefPrevention.Claims.ModificationTool", modificationToolMaterialName);
  528. //validate modification tool
  529. this.config_claims_modificationTool = Material.getMaterial(modificationToolMaterialName);
  530. if(this.config_claims_modificationTool == null)
  531. {
  532. GriefPrevention.AddLogEntry("ERROR: Material " + modificationToolMaterialName + " not found. Defaulting to the golden shovel. Please update your config.yml.");
  533. this.config_claims_modificationTool = Material.GOLD_SPADE;
  534. }
  535. //default for siege worlds list
  536. ArrayList<String> defaultSiegeWorldNames = new ArrayList<String>();
  537. //get siege world names from the config file
  538. List<String> siegeEnabledWorldNames = config.getStringList("GriefPrevention.Siege.Worlds");
  539. if(siegeEnabledWorldNames == null)
  540. {
  541. siegeEnabledWorldNames = defaultSiegeWorldNames;
  542. }
  543. //validate that list
  544. this.config_siege_enabledWorlds = new ArrayList<World>();
  545. for(int i = 0; i < siegeEnabledWorldNames.size(); i++)
  546. {
  547. String worldName = siegeEnabledWorldNames.get(i);
  548. World world = this.getServer().getWorld(worldName);
  549. if(world == null)
  550. {
  551. AddLogEntry("Error: Siege Configuration: There's no world named \"" + worldName + "\". Please update your config.yml.");
  552. }
  553. else
  554. {
  555. this.config_siege_enabledWorlds.add(world);
  556. }
  557. }
  558. //default siege blocks
  559. this.config_siege_blocks = new ArrayList<Material>();
  560. this.config_siege_blocks.add(Material.DIRT);
  561. this.config_siege_blocks.add(Material.GRASS);
  562. this.config_siege_blocks.add(Material.LONG_GRASS);
  563. this.config_siege_blocks.add(Material.COBBLESTONE);
  564. this.config_siege_blocks.add(Material.GRAVEL);
  565. this.config_siege_blocks.add(Material.SAND);
  566. this.config_siege_blocks.add(Material.GLASS);
  567. this.config_siege_blocks.add(Material.THIN_GLASS);
  568. this.config_siege_blocks.add(Material.WOOD);
  569. this.config_siege_blocks.add(Material.WOOL);
  570. this.config_siege_blocks.add(Material.SNOW);
  571. //build a default config entry
  572. ArrayList<String> defaultBreakableBlocksList = new ArrayList<String>();
  573. for(int i = 0; i < this.config_siege_blocks.size(); i++)
  574. {
  575. defaultBreakableBlocksList.add(this.config_siege_blocks.get(i).name());
  576. }
  577. //try to load the list from the config file
  578. List<String> breakableBlocksList = config.getStringList("GriefPrevention.Siege.BreakableBlocks");
  579. //if it fails, use default list instead
  580. if(breakableBlocksList == null || breakableBlocksList.size() == 0)
  581. {
  582. breakableBlocksList = defaultBreakableBlocksList;
  583. }
  584. //parse the list of siege-breakable blocks
  585. this.config_siege_blocks = new ArrayList<Material>();
  586. for(int i = 0; i < breakableBlocksList.size(); i++)
  587. {
  588. String blockName = breakableBlocksList.get(i);
  589. Material material = Material.getMaterial(blockName);
  590. if(material == null)
  591. {
  592. GriefPrevention.AddLogEntry("Siege Configuration: Material not found: " + blockName + ".");
  593. }
  594. else
  595. {
  596. this.config_siege_blocks.add(material);
  597. }
  598. }
  599. this.config_pvp_noCombatInPlayerLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_siege_enabledWorlds.size() == 0);
  600. this.config_pvp_noCombatInAdminLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_siege_enabledWorlds.size() == 0);
  601. this.config_pvp_noCombatInAdminSubdivisions = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeSubdivisions", this.config_siege_enabledWorlds.size() == 0);
  602. this.config_pvp_allowLavaNearPlayers = config.getBoolean("GriefPrevention.PvP.AllowLavaDumpingNearOtherPlayers", true);
  603. this.config_pvp_allowFireNearPlayers = config.getBoolean("GriefPrevention.PvP.AllowFlintAndSteelNearOtherPlayers", true);
  604. this.config_pvp_protectPets = config.getBoolean("GriefPrevention.PvP.ProtectPetsOutsideLandClaims", false);
  605. //optional database settings
  606. this.databaseUrl = config.getString("GriefPrevention.Database.URL", "");
  607. this.databaseUserName = config.getString("GriefPrevention.Database.UserName", "");
  608. this.databasePassword = config.getString("GriefPrevention.Database.Password", "");
  609. //custom logger settings
  610. this.config_logs_daysToKeep = config.getInt("GriefPrevention.Abridged Logs.Days To Keep", 7);
  611. this.config_logs_socialEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Social Activity", true);
  612. this.config_logs_suspiciousEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Suspicious Activity", true);
  613. this.config_logs_adminEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Administrative Activity", false);
  614. this.config_logs_debugEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Debug", false);
  615. this.config_logs_mutedChatEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Muted Chat Messages", false);
  616. //claims mode by world
  617. for(World world : this.config_claims_worldModes.keySet())
  618. {
  619. outConfig.set(
  620. "GriefPrevention.Claims.Mode." + world.getName(),
  621. this.config_claims_worldModes.get(world).name());
  622. }
  623. outConfig.set("GriefPrevention.Claims.PreventTheft", this.config_claims_preventTheft);
  624. outConfig.set("GriefPrevention.Claims.ProtectCreatures", this.config_claims_protectCreatures);
  625. outConfig.set("GriefPrevention.Claims.PreventButtonsSwitches", this.config_claims_preventButtonsSwitches);
  626. outConfig.set("GriefPrevention.Claims.LockWoodenDoors", this.config_claims_lockWoodenDoors);
  627. outConfig.set("GriefPrevention.Claims.LockTrapDoors", this.config_claims_lockTrapDoors);
  628. outConfig.set("GriefPrevention.Claims.LockFenceGates", this.config_claims_lockFenceGates);
  629. outConfig.set("GriefPrevention.Claims.EnderPearlsRequireAccessTrust", this.config_claims_enderPearlsRequireAccessTrust);
  630. outConfig.set("GriefPrevention.Claims.ProtectFires", this.config_claims_protectFires);
  631. outConfig.set("GriefPrevention.Claims.ProtectHorses", this.config_claims_protectHorses);
  632. outConfig.set("GriefPrevention.Claims.InitialBlocks", this.config_claims_initialBlocks);
  633. outConfig.set("GriefPrevention.Claims.BlocksAccruedPerHour", this.config_claims_blocksAccruedPerHour);
  634. outConfig.set("GriefPrevention.Claims.MaxAccruedBlocks", this.config_claims_maxAccruedBlocks);
  635. outConfig.set("GriefPrevention.Claims.AbandonReturnRatio", this.config_claims_abandonReturnRatio);
  636. outConfig.set("GriefPrevention.Claims.AutomaticNewPlayerClaimsRadius", this.config_claims_automaticClaimsForNewPlayersRadius);
  637. outConfig.set("GriefPrevention.Claims.ExtendIntoGroundDistance", this.config_claims_claimsExtendIntoGroundDistance);
  638. outConfig.set("GriefPrevention.Claims.MinimumWidth", this.config_claims_minWidth);
  639. outConfig.set("GriefPrevention.Claims.MinimumArea", this.config_claims_minArea);
  640. outConfig.set("GriefPrevention.Claims.MaximumDepth", this.config_claims_maxDepth);
  641. outConfig.set("GriefPrevention.Claims.InvestigationTool", this.config_claims_investigationTool.name());
  642. outConfig.set("GriefPrevention.Claims.ModificationTool", this.config_claims_modificationTool.name());
  643. outConfig.set("GriefPrevention.Claims.Expiration.ChestClaimDays", this.config_claims_chestClaimExpirationDays);
  644. outConfig.set("GriefPrevention.Claims.Expiration.UnusedClaimDays", this.config_claims_unusedClaimExpirationDays);
  645. outConfig.set("GriefPrevention.Claims.Expiration.AllClaims.DaysInactive", this.config_claims_expirationDays);
  646. outConfig.set("GriefPrevention.Claims.Expiration.AllClaims.ExceptWhenOwnerHasTotalClaimBlocks", this.config_claims_expirationExemptionTotalBlocks);
  647. outConfig.set("GriefPrevention.Claims.Expiration.AllClaims.ExceptWhenOwnerHasBonusClaimBlocks", this.config_claims_expirationExemptionBonusBlocks);
  648. outConfig.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", this.config_claims_survivalAutoNatureRestoration);
  649. outConfig.set("GriefPrevention.Claims.MaximumNumberOfClaimsPerPlayer", this.config_claims_maxClaimsPerPlayer);
  650. outConfig.set("GriefPrevention.Claims.CreationRequiresWorldGuardBuildPermission", this.config_claims_respectWorldGuard);
  651. outConfig.set("GriefPrevention.Claims.PortalGenerationRequiresPermission", this.config_claims_portalsRequirePermission);
  652. outConfig.set("GriefPrevention.Claims.VillagerTradingRequiresPermission", this.config_claims_villagerTradingRequiresTrust);
  653. outConfig.set("GriefPrevention.Claims.CommandsRequiringAccessTrust", accessTrustSlashCommands);
  654. outConfig.set("GriefPrevention.Claims.DeliverManuals", config_claims_supplyPlayerManual);
  655. outConfig.set("GriefPrevention.Claims.ManualDeliveryDelaySeconds", config_claims_manualDeliveryDelaySeconds);
  656. outConfig.set("GriefPrevention.Spam.Enabled", this.config_spam_enabled);
  657. outConfig.set("GriefPrevention.Spam.LoginCooldownSeconds", this.config_spam_loginCooldownSeconds);
  658. outConfig.set("GriefPrevention.Spam.ChatSlashCommands", slashCommandsToMonitor);
  659. outConfig.set("GriefPrevention.Spam.WhisperSlashCommands", whisperCommandsToMonitor);
  660. outConfig.set("GriefPrevention.Spam.WarningMessage", this.config_spam_warningMessage);
  661. outConfig.set("GriefPrevention.Spam.BanOffenders", this.config_spam_banOffenders);
  662. outConfig.set("GriefPrevention.Spam.BanMessage", this.config_spam_banMessage);
  663. outConfig.set("GriefPrevention.Spam.AllowedIpAddresses", this.config_spam_allowedIpAddresses);
  664. outConfig.set("GriefPrevention.Spam.DeathMessageCooldownSeconds", this.config_spam_deathMessageCooldownSeconds);
  665. for(World world : worlds)
  666. {
  667. outConfig.set("GriefPrevention.PvP.RulesEnabledInWorld." + world.getName(), this.pvpRulesApply(world));
  668. }
  669. outConfig.set("GriefPrevention.PvP.ProtectFreshSpawns", this.config_pvp_protectFreshSpawns);
  670. outConfig.set("GriefPrevention.PvP.PunishLogout", this.config_pvp_punishLogout);
  671. outConfig.set("GriefPrevention.PvP.CombatTimeoutSeconds", this.config_pvp_combatTimeoutSeconds);
  672. outConfig.set("GriefPrevention.PvP.AllowCombatItemDrop", this.config_pvp_allowCombatItemDrop);
  673. outConfig.set("GriefPrevention.PvP.BlockedSlashCommands", bannedPvPCommandsList);
  674. outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_pvp_noCombatInPlayerLandClaims);
  675. outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_pvp_noCombatInAdminLandClaims);
  676. outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeSubdivisions", this.config_pvp_noCombatInAdminSubdivisions);
  677. outConfig.set("GriefPrevention.PvP.AllowLavaDumpingNearOtherPlayers", this.config_pvp_allowLavaNearPlayers);
  678. outConfig.set("GriefPrevention.PvP.AllowFlintAndSteelNearOtherPlayers", this.config_pvp_allowFireNearPlayers);
  679. outConfig.set("GriefPrevention.PvP.ProtectPetsOutsideLandClaims", this.config_pvp_protectPets);
  680. outConfig.set("GriefPrevention.Economy.ClaimBlocksPurchaseCost", this.config_economy_claimBlocksPurchaseCost);
  681. outConfig.set("GriefPrevention.Economy.ClaimBlocksSellValue", this.config_economy_claimBlocksSellValue);
  682. outConfig.set("GriefPrevention.ProtectItemsDroppedOnDeath.PvPWorlds", this.config_lockDeathDropsInPvpWorlds);
  683. outConfig.set("GriefPrevention.ProtectItemsDroppedOnDeath.NonPvPWorlds", this.config_lockDeathDropsInNonPvpWorlds);
  684. outConfig.set("GriefPrevention.BlockLandClaimExplo