7.2.2
This commit is contained in:
parent
6fa1b7340c
commit
2734ba1ae9
|
|
@ -2,7 +2,7 @@ name: GriefPrevention
|
||||||
main: me.ryanhamshire.GriefPrevention.GriefPrevention
|
main: me.ryanhamshire.GriefPrevention.GriefPrevention
|
||||||
softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter]
|
softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter]
|
||||||
dev-url: http://dev.bukkit.org/server-mods/grief-prevention
|
dev-url: http://dev.bukkit.org/server-mods/grief-prevention
|
||||||
version: 7.2
|
version: 7.2.2
|
||||||
commands:
|
commands:
|
||||||
abandonclaim:
|
abandonclaim:
|
||||||
description: Deletes a claim.
|
description: Deletes a claim.
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -20,6 +20,7 @@ package me.ryanhamshire.GriefPrevention;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
@ -31,10 +32,10 @@ import org.bukkit.inventory.ItemStack;
|
||||||
public abstract class DataStore
|
public abstract class DataStore
|
||||||
{
|
{
|
||||||
//in-memory cache for player data
|
//in-memory cache for player data
|
||||||
protected HashMap<String, PlayerData> playerNameToPlayerDataMap = new HashMap<String, PlayerData>();
|
protected ConcurrentHashMap<String, PlayerData> playerNameToPlayerDataMap = new ConcurrentHashMap<String, PlayerData>();
|
||||||
|
|
||||||
//in-memory cache for group (permission-based) data
|
//in-memory cache for group (permission-based) data
|
||||||
protected HashMap<String, Integer> permissionToBonusBlocksMap = new HashMap<String, Integer>();
|
protected ConcurrentHashMap<String, Integer> permissionToBonusBlocksMap = new ConcurrentHashMap<String, Integer>();
|
||||||
|
|
||||||
//in-memory cache for claim data
|
//in-memory cache for claim data
|
||||||
ArrayList<Claim> claims = new ArrayList<Claim>();
|
ArrayList<Claim> claims = new ArrayList<Claim>();
|
||||||
|
|
|
||||||
|
|
@ -62,13 +62,7 @@ public class DatabaseDataStore extends DataStore
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//set username/pass properties
|
this.refreshDataConnection();
|
||||||
Properties connectionProps = new Properties();
|
|
||||||
connectionProps.put("user", this.userName);
|
|
||||||
connectionProps.put("password", this.password);
|
|
||||||
|
|
||||||
//establish connection
|
|
||||||
this.databaseConnection = DriverManager.getConnection(this.databaseUrl, connectionProps);
|
|
||||||
}
|
}
|
||||||
catch(Exception e2)
|
catch(Exception e2)
|
||||||
{
|
{
|
||||||
|
|
@ -240,6 +234,8 @@ public class DatabaseDataStore extends DataStore
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.refreshDataConnection();
|
||||||
|
|
||||||
//wipe out any existing data about this claim
|
//wipe out any existing data about this claim
|
||||||
this.deleteClaimFromSecondaryStorage(claim);
|
this.deleteClaimFromSecondaryStorage(claim);
|
||||||
|
|
||||||
|
|
@ -320,6 +316,8 @@ public class DatabaseDataStore extends DataStore
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.refreshDataConnection();
|
||||||
|
|
||||||
Statement statement = databaseConnection.createStatement();
|
Statement statement = databaseConnection.createStatement();
|
||||||
statement.execute("INSERT INTO griefprevention_claimdata VALUES(" +
|
statement.execute("INSERT INTO griefprevention_claimdata VALUES(" +
|
||||||
id + ", '" +
|
id + ", '" +
|
||||||
|
|
@ -346,6 +344,8 @@ public class DatabaseDataStore extends DataStore
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.refreshDataConnection();
|
||||||
|
|
||||||
Statement statement = this.databaseConnection.createStatement();
|
Statement statement = this.databaseConnection.createStatement();
|
||||||
statement.execute("DELETE FROM griefprevention_claimdata WHERE id=" + claim.id + ";");
|
statement.execute("DELETE FROM griefprevention_claimdata WHERE id=" + claim.id + ";");
|
||||||
statement.execute("DELETE FROM griefprevention_claimdata WHERE parentid=" + claim.id + ";");
|
statement.execute("DELETE FROM griefprevention_claimdata WHERE parentid=" + claim.id + ";");
|
||||||
|
|
@ -365,6 +365,8 @@ public class DatabaseDataStore extends DataStore
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.refreshDataConnection();
|
||||||
|
|
||||||
Statement statement = this.databaseConnection.createStatement();
|
Statement statement = this.databaseConnection.createStatement();
|
||||||
ResultSet results = statement.executeQuery("SELECT * FROM griefprevention_playerdata WHERE name='" + playerName + "';");
|
ResultSet results = statement.executeQuery("SELECT * FROM griefprevention_playerdata WHERE name='" + playerName + "';");
|
||||||
|
|
||||||
|
|
@ -400,6 +402,8 @@ public class DatabaseDataStore extends DataStore
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.refreshDataConnection();
|
||||||
|
|
||||||
SimpleDateFormat sqlFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
SimpleDateFormat sqlFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
String dateString = sqlFormat.format(playerData.lastLogin);
|
String dateString = sqlFormat.format(playerData.lastLogin);
|
||||||
|
|
||||||
|
|
@ -427,6 +431,8 @@ public class DatabaseDataStore extends DataStore
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
this.refreshDataConnection();
|
||||||
|
|
||||||
Statement statement = databaseConnection.createStatement();
|
Statement statement = databaseConnection.createStatement();
|
||||||
statement.execute("DELETE FROM griefprevention_nextclaimid;");
|
statement.execute("DELETE FROM griefprevention_nextclaimid;");
|
||||||
statement.execute("INSERT INTO griefprevention_nextclaimid VALUES (" + nextID + ");");
|
statement.execute("INSERT INTO griefprevention_nextclaimid VALUES (" + nextID + ");");
|
||||||
|
|
@ -457,11 +463,28 @@ public class DatabaseDataStore extends DataStore
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.databaseConnection.close();
|
if(!this.databaseConnection.isClosed())
|
||||||
|
{
|
||||||
|
this.databaseConnection.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(SQLException e){};
|
catch(SQLException e){};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.databaseConnection = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshDataConnection() throws SQLException
|
||||||
|
{
|
||||||
|
if(this.databaseConnection == null || this.databaseConnection.isClosed())
|
||||||
|
{
|
||||||
|
//set username/pass properties
|
||||||
|
Properties connectionProps = new Properties();
|
||||||
|
connectionProps.put("user", this.userName);
|
||||||
|
connectionProps.put("password", this.password);
|
||||||
|
|
||||||
this.databaseConnection = null;
|
//establish connection
|
||||||
|
this.databaseConnection = DriverManager.getConnection(this.databaseUrl, connectionProps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2254,8 +2254,8 @@ public class GriefPrevention extends JavaPlugin
|
||||||
if(hasLeaves)
|
if(hasLeaves)
|
||||||
{
|
{
|
||||||
//schedule a cleanup task for later, in case the player leaves part of this tree hanging in the air
|
//schedule a cleanup task for later, in case the player leaves part of this tree hanging in the air
|
||||||
TreeCleanupTask cleanupTask = new TreeCleanupTask(block, rootBlock, treeBlocks);
|
TreeCleanupTask cleanupTask = new TreeCleanupTask(block, rootBlock, treeBlocks, rootBlock.getData());
|
||||||
|
|
||||||
//20L ~ 1 second, so 2 mins = 120 seconds ~ 2400L
|
//20L ~ 1 second, so 2 mins = 120 seconds ~ 2400L
|
||||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, cleanupTask, 2400L);
|
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, cleanupTask, 2400L);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -235,15 +235,18 @@ class PlayerEventHandler implements Listener
|
||||||
//log entry
|
//log entry
|
||||||
GriefPrevention.AddLogEntry("Banning " + player.getName() + " for spam.");
|
GriefPrevention.AddLogEntry("Banning " + player.getName() + " for spam.");
|
||||||
|
|
||||||
//ban
|
//kick and ban
|
||||||
GriefPrevention.instance.getServer().getOfflinePlayer(player.getName()).setBanned(true);
|
PlayerKickBanTask task = new PlayerKickBanTask(player, GriefPrevention.instance.config_spam_banMessage);
|
||||||
|
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 1L);
|
||||||
//kick
|
}
|
||||||
player.kickPlayer(GriefPrevention.instance.config_spam_banMessage);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player.kickPlayer("");
|
//log entry
|
||||||
|
GriefPrevention.AddLogEntry("Banning " + player.getName() + " for spam.");
|
||||||
|
|
||||||
|
//just kick
|
||||||
|
PlayerKickBanTask task = new PlayerKickBanTask(player, null);
|
||||||
|
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
59
src/me/ryanhamshire/GriefPrevention/PlayerKickBanTask.java
Normal file
59
src/me/ryanhamshire/GriefPrevention/PlayerKickBanTask.java
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
GriefPrevention Server Plugin for Minecraft
|
||||||
|
Copyright (C) 2012 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 org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
//kicks or bans a player
|
||||||
|
//need a task for this because async threads (like the chat event handlers) can't kick or ban.
|
||||||
|
//but they CAN schedule a task to run in the main thread to do that job
|
||||||
|
class PlayerKickBanTask implements Runnable
|
||||||
|
{
|
||||||
|
//player to kick or ban
|
||||||
|
private Player player;
|
||||||
|
|
||||||
|
//ban message. if null, don't ban
|
||||||
|
private String banReason;
|
||||||
|
|
||||||
|
public PlayerKickBanTask(Player player, String banReason)
|
||||||
|
{
|
||||||
|
this.player = player;
|
||||||
|
this.banReason = banReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
if(this.banReason != null)
|
||||||
|
{
|
||||||
|
//ban
|
||||||
|
GriefPrevention.instance.getServer().getOfflinePlayer(this.player.getName()).setBanned(true);
|
||||||
|
|
||||||
|
//kick
|
||||||
|
if(this.player.isOnline())
|
||||||
|
{
|
||||||
|
this.player.kickPlayer(this.banReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(this.player.isOnline())
|
||||||
|
{
|
||||||
|
this.player.kickPlayer("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,100 +1,102 @@
|
||||||
/*
|
/*
|
||||||
GriefPrevention Server Plugin for Minecraft
|
GriefPrevention Server Plugin for Minecraft
|
||||||
Copyright (C) 2012 Ryan Hamshire
|
Copyright (C) 2012 Ryan Hamshire
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.ryanhamshire.GriefPrevention;
|
package me.ryanhamshire.GriefPrevention;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
|
|
||||||
//FEATURE: treetops left unnaturally hanging will be automatically cleaned up
|
//FEATURE: treetops left unnaturally hanging will be automatically cleaned up
|
||||||
|
|
||||||
//this main thread task revisits the location of a partially chopped tree from several minutes ago
|
//this main thread task revisits the location of a partially chopped tree from several minutes ago
|
||||||
//if any part of the tree is still there and nothing else has been built in its place, remove the remaining parts
|
//if any part of the tree is still there and nothing else has been built in its place, remove the remaining parts
|
||||||
class TreeCleanupTask implements Runnable
|
class TreeCleanupTask implements Runnable
|
||||||
{
|
{
|
||||||
private Block originalChoppedBlock; //first block chopped in the tree
|
private Block originalChoppedBlock; //first block chopped in the tree
|
||||||
private Block originalRootBlock; //where the root of the tree used to be
|
private Block originalRootBlock; //where the root of the tree used to be
|
||||||
private ArrayList<Block> originalTreeBlocks; //a list of other log blocks determined to be part of this tree
|
private byte originalRootBlockData; //data value of that root block (TYPE of log)
|
||||||
|
private ArrayList<Block> originalTreeBlocks; //a list of other log blocks determined to be part of this tree
|
||||||
public TreeCleanupTask(Block originalChoppedBlock, Block originalRootBlock, ArrayList<Block> originalTreeBlocks)
|
|
||||||
{
|
public TreeCleanupTask(Block originalChoppedBlock, Block originalRootBlock, ArrayList<Block> originalTreeBlocks, byte originalRootBlockData)
|
||||||
this.originalChoppedBlock = originalChoppedBlock;
|
{
|
||||||
this.originalRootBlock = originalRootBlock;
|
this.originalChoppedBlock = originalChoppedBlock;
|
||||||
this.originalTreeBlocks = originalTreeBlocks;
|
this.originalRootBlock = originalRootBlock;
|
||||||
}
|
this.originalTreeBlocks = originalTreeBlocks;
|
||||||
|
this.originalRootBlockData = originalRootBlockData;
|
||||||
@Override
|
}
|
||||||
public void run()
|
|
||||||
{
|
@Override
|
||||||
//if this chunk is no longer loaded, load it and come back in a few seconds
|
public void run()
|
||||||
Chunk chunk = this.originalChoppedBlock.getWorld().getChunkAt(this.originalChoppedBlock);
|
{
|
||||||
if(!chunk.isLoaded())
|
//if this chunk is no longer loaded, load it and come back in a few seconds
|
||||||
{
|
Chunk chunk = this.originalChoppedBlock.getWorld().getChunkAt(this.originalChoppedBlock);
|
||||||
chunk.load();
|
if(!chunk.isLoaded())
|
||||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, this, 100L);
|
{
|
||||||
return;
|
chunk.load();
|
||||||
}
|
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, this, 100L);
|
||||||
|
return;
|
||||||
//if the block originally chopped has been replaced with anything but air, something has been built (or has grown here)
|
}
|
||||||
//in that case, don't do any cleanup
|
|
||||||
if(this.originalChoppedBlock.getWorld().getBlockAt(this.originalChoppedBlock.getLocation()).getType() != Material.AIR) return;
|
//if the block originally chopped has been replaced with anything but air, something has been built (or has grown here)
|
||||||
|
//in that case, don't do any cleanup
|
||||||
//scan the original tree block locations to see if any of them have been replaced
|
if(this.originalChoppedBlock.getWorld().getBlockAt(this.originalChoppedBlock.getLocation()).getType() != Material.AIR) return;
|
||||||
for(int i = 0; i < this.originalTreeBlocks.size(); i++)
|
|
||||||
{
|
//scan the original tree block locations to see if any of them have been replaced
|
||||||
Location location = this.originalTreeBlocks.get(i).getLocation();
|
for(int i = 0; i < this.originalTreeBlocks.size(); i++)
|
||||||
Block currentBlock = location.getBlock();
|
{
|
||||||
|
Location location = this.originalTreeBlocks.get(i).getLocation();
|
||||||
//if the block has been replaced, stop here, we won't do any cleanup
|
Block currentBlock = location.getBlock();
|
||||||
if(currentBlock.getType() != Material.LOG && currentBlock.getType() != Material.AIR)
|
|
||||||
{
|
//if the block has been replaced, stop here, we won't do any cleanup
|
||||||
return;
|
if(currentBlock.getType() != Material.LOG && currentBlock.getType() != Material.AIR)
|
||||||
}
|
{
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
//otherwise scan again, this time removing any remaining log blocks
|
}
|
||||||
boolean logsRemaining = false;
|
|
||||||
for(int i = 0; i < this.originalTreeBlocks.size(); i++)
|
//otherwise scan again, this time removing any remaining log blocks
|
||||||
{
|
boolean logsRemaining = false;
|
||||||
Location location = this.originalTreeBlocks.get(i).getLocation();
|
for(int i = 0; i < this.originalTreeBlocks.size(); i++)
|
||||||
Block currentBlock = location.getBlock();
|
{
|
||||||
if(currentBlock.getType() == Material.LOG)
|
Location location = this.originalTreeBlocks.get(i).getLocation();
|
||||||
{
|
Block currentBlock = location.getBlock();
|
||||||
logsRemaining = true;
|
if(currentBlock.getType() == Material.LOG)
|
||||||
currentBlock.setType(Material.AIR);
|
{
|
||||||
}
|
logsRemaining = true;
|
||||||
}
|
currentBlock.setType(Material.AIR);
|
||||||
|
}
|
||||||
//if any were actually removed and we're set to automatically replant griefed trees, place a sapling where the root block was previously
|
}
|
||||||
if(logsRemaining && GriefPrevention.instance.config_trees_regrowGriefedTrees)
|
|
||||||
{
|
//if any were actually removed and we're set to automatically replant griefed trees, place a sapling where the root block was previously
|
||||||
Block currentBlock = this.originalRootBlock.getLocation().getBlock();
|
if(logsRemaining && GriefPrevention.instance.config_trees_regrowGriefedTrees)
|
||||||
//make sure there's grass or dirt underneath
|
{
|
||||||
if(currentBlock.getType() == Material.AIR && (currentBlock.getRelative(BlockFace.DOWN).getType() == Material.DIRT || currentBlock.getRelative(BlockFace.DOWN).getType() == Material.GRASS))
|
Block currentBlock = this.originalRootBlock.getLocation().getBlock();
|
||||||
{
|
//make sure there's grass or dirt underneath
|
||||||
currentBlock.setType(Material.SAPLING);
|
if(currentBlock.getType() == Material.AIR && (currentBlock.getRelative(BlockFace.DOWN).getType() == Material.DIRT || currentBlock.getRelative(BlockFace.DOWN).getType() == Material.GRASS))
|
||||||
currentBlock.setData(this.originalRootBlock.getData()); //makes the sapling type match the original tree type
|
{
|
||||||
}
|
currentBlock.setType(Material.SAPLING);
|
||||||
}
|
currentBlock.setData(this.originalRootBlockData); //makes the sapling type match the original tree type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user