Added UUID support.
Rewrote and retested parts of the plugin to use UUIDs instead of player names to uniquely identify players. Added data migration code to convert old data to the new (UUID) format.
This commit is contained in:
parent
e855f10a75
commit
6da42a9077
|
|
@ -109,7 +109,7 @@ public class BlockEventHandler implements Listener
|
|||
if(claim == null || claim.allowContainers(player) == null) return;
|
||||
|
||||
//if the player is under siege, he can't give away items
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getUniqueId());
|
||||
if(playerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoDrop);
|
||||
|
|
@ -177,7 +177,7 @@ public class BlockEventHandler implements Listener
|
|||
return;
|
||||
}
|
||||
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(block.getLocation(), true, playerData.lastClaim);
|
||||
|
||||
//if there's a claim here
|
||||
|
|
@ -218,7 +218,7 @@ public class BlockEventHandler implements Listener
|
|||
String signMessage = lines.toString();
|
||||
|
||||
//if not empty and wasn't the same as the last sign, log it and remember it for later
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
if(notEmpty && playerData.lastMessage != null && !playerData.lastMessage.equals(signMessage))
|
||||
{
|
||||
GriefPrevention.AddLogEntry("[Sign Placement] <" + player.getName() + "> " + lines.toString() + " @ " + GriefPrevention.getfriendlyLocationString(event.getBlock().getLocation()));
|
||||
|
|
@ -275,7 +275,7 @@ public class BlockEventHandler implements Listener
|
|||
}
|
||||
|
||||
//if the block is being placed within or under an existing claim
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(block.getLocation(), true, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
|
|
@ -350,7 +350,7 @@ public class BlockEventHandler implements Listener
|
|||
//radius == 0 means protect ONLY the chest
|
||||
if(GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius == 0)
|
||||
{
|
||||
this.dataStore.createClaim(block.getWorld(), block.getX(), block.getX(), block.getY(), block.getY(), block.getZ(), block.getZ(), player.getName(), null, null);
|
||||
this.dataStore.createClaim(block.getWorld(), block.getX(), block.getX(), block.getY(), block.getY(), block.getZ(), block.getZ(), player.getUniqueId(), null, null);
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ChestClaimConfirmation);
|
||||
}
|
||||
|
||||
|
|
@ -363,7 +363,7 @@ public class BlockEventHandler implements Listener
|
|||
block.getX() - radius, block.getX() + radius,
|
||||
block.getY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance, block.getY(),
|
||||
block.getZ() - radius, block.getZ() + radius,
|
||||
player.getName(),
|
||||
player.getUniqueId(),
|
||||
null, null).succeeded)
|
||||
{
|
||||
radius--;
|
||||
|
|
@ -687,7 +687,7 @@ public class BlockEventHandler implements Listener
|
|||
OfflinePlayer fromOwner = null;
|
||||
if(fromClaim != null)
|
||||
{
|
||||
fromOwner = GriefPrevention.instance.getServer().getOfflinePlayer(fromClaim.ownerName);
|
||||
fromOwner = GriefPrevention.instance.getServer().getOfflinePlayer(fromClaim.ownerID);
|
||||
}
|
||||
|
||||
//cancel unless the owner of the spreading block is allowed to build in the receiving claim
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.World.Environment;
|
||||
|
|
@ -48,15 +49,15 @@ public class Claim
|
|||
//id number. unique to this claim, never changes.
|
||||
Long id = null;
|
||||
|
||||
//ownername. for admin claims, this is the empty string
|
||||
//ownerID. for admin claims, this is NULL
|
||||
//use getOwnerName() to get a friendly name (will be "an administrator" for admin claims)
|
||||
public String ownerName;
|
||||
public UUID ownerID;
|
||||
|
||||
//list of players who (beyond the claim owner) have permission to grant permissions in this claim
|
||||
public ArrayList<String> managers = new ArrayList<String>();
|
||||
|
||||
//permissions for this claim, see ClaimPermission class
|
||||
private HashMap<String, ClaimPermission> playerNameToClaimPermissionMap = new HashMap<String, ClaimPermission>();
|
||||
private HashMap<String, ClaimPermission> playerIDToClaimPermissionMap = new HashMap<String, ClaimPermission>();
|
||||
|
||||
//whether or not this claim is in the data store
|
||||
//if a claim instance isn't in the data store, it isn't "active" - players can't interract with it
|
||||
|
|
@ -84,7 +85,7 @@ public class Claim
|
|||
//administrative claims are created and maintained by players with the griefprevention.adminclaims permission.
|
||||
public boolean isAdminClaim()
|
||||
{
|
||||
return (this.ownerName == null || this.ownerName.isEmpty());
|
||||
return (this.ownerID == null);
|
||||
}
|
||||
|
||||
//accessor for ID
|
||||
|
|
@ -197,7 +198,7 @@ public class Claim
|
|||
}
|
||||
|
||||
//main constructor. note that only creating a claim instance does nothing - a claim must be added to the data store to be effective
|
||||
Claim(Location lesserBoundaryCorner, Location greaterBoundaryCorner, String ownerName, String [] builderNames, String [] containerNames, String [] accessorNames, String [] managerNames, Long id)
|
||||
Claim(Location lesserBoundaryCorner, Location greaterBoundaryCorner, UUID ownerID, String [] builderIDs, String [] containerIds, String [] accessorIDs, String [] managerIDs, Long id)
|
||||
{
|
||||
//modification date
|
||||
this.modifiedDate = Calendar.getInstance().getTime();
|
||||
|
|
@ -210,42 +211,42 @@ public class Claim
|
|||
this.greaterBoundaryCorner = greaterBoundaryCorner;
|
||||
|
||||
//owner
|
||||
this.ownerName = ownerName;
|
||||
this.ownerID = ownerID;
|
||||
|
||||
//other permissions
|
||||
for(int i = 0; i < builderNames.length; i++)
|
||||
for(int i = 0; i < builderIDs.length; i++)
|
||||
{
|
||||
String name = builderNames[i];
|
||||
if(name != null && !name.isEmpty())
|
||||
String builderID = builderIDs[i];
|
||||
if(builderID != null)
|
||||
{
|
||||
this.playerNameToClaimPermissionMap.put(name, ClaimPermission.Build);
|
||||
this.playerIDToClaimPermissionMap.put(builderID, ClaimPermission.Build);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < containerNames.length; i++)
|
||||
for(int i = 0; i < containerIds.length; i++)
|
||||
{
|
||||
String name = containerNames[i];
|
||||
if(name != null && !name.isEmpty())
|
||||
String containerID = containerIds[i];
|
||||
if(containerID != null)
|
||||
{
|
||||
this.playerNameToClaimPermissionMap.put(name, ClaimPermission.Inventory);
|
||||
this.playerIDToClaimPermissionMap.put(containerID, ClaimPermission.Inventory);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < accessorNames.length; i++)
|
||||
for(int i = 0; i < accessorIDs.length; i++)
|
||||
{
|
||||
String name = accessorNames[i];
|
||||
if(name != null && !name.isEmpty())
|
||||
String accessorID = accessorIDs[i];
|
||||
if(accessorID != null)
|
||||
{
|
||||
this.playerNameToClaimPermissionMap.put(name, ClaimPermission.Access);
|
||||
this.playerIDToClaimPermissionMap.put(accessorID, ClaimPermission.Access);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < managerNames.length; i++)
|
||||
for(int i = 0; i < managerIDs.length; i++)
|
||||
{
|
||||
String name = managerNames[i];
|
||||
if(name != null && !name.isEmpty())
|
||||
String managerID = managerIDs[i];
|
||||
if(managerID != null)
|
||||
{
|
||||
this.managers.add(name);
|
||||
this.managers.add(managerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -275,7 +276,7 @@ public class Claim
|
|||
Claim claim = new Claim
|
||||
(new Location(this.lesserBoundaryCorner.getWorld(), this.lesserBoundaryCorner.getBlockX() - howNear, this.lesserBoundaryCorner.getBlockY(), this.lesserBoundaryCorner.getBlockZ() - howNear),
|
||||
new Location(this.greaterBoundaryCorner.getWorld(), this.greaterBoundaryCorner.getBlockX() + howNear, this.greaterBoundaryCorner.getBlockY(), this.greaterBoundaryCorner.getBlockZ() + howNear),
|
||||
"", new String[] {}, new String[] {}, new String[] {}, new String[] {}, null);
|
||||
null, new String[] {}, new String[] {}, new String[] {}, new String[] {}, null);
|
||||
|
||||
return claim.contains(location, false, true);
|
||||
}
|
||||
|
|
@ -302,7 +303,7 @@ public class Claim
|
|||
}
|
||||
|
||||
//no resizing, deleting, and so forth while under siege
|
||||
if(this.ownerName.equals(player.getName()))
|
||||
if(player.getUniqueId().equals(this.ownerID))
|
||||
{
|
||||
if(this.siegeData != null)
|
||||
{
|
||||
|
|
@ -343,20 +344,20 @@ public class Claim
|
|||
}
|
||||
|
||||
//no building while in pvp combat
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
|
||||
if(playerData.inPvpCombat())
|
||||
{
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPvP);
|
||||
}
|
||||
|
||||
//owners can make changes, or admins with ignore claims mode enabled
|
||||
if(this.ownerName.equals(player.getName()) || GriefPrevention.instance.dataStore.getPlayerData(player.getName()).ignoreClaims) return null;
|
||||
if(player.getUniqueId().equals(this.ownerID) || GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()).ignoreClaims) return null;
|
||||
|
||||
//anyone with explicit build permission can make changes
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null;
|
||||
|
||||
//also everyone is a member of the "public", so check for public permission
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
//also everyone is a member of the "public", so check for public permission, indicated by a null key
|
||||
ClaimPermission permissionLevel = this.playerIDToClaimPermissionMap.get(null);
|
||||
if(ClaimPermission.Build == permissionLevel) return null;
|
||||
|
||||
//subdivision permission inheritance
|
||||
|
|
@ -372,13 +373,13 @@ public class Claim
|
|||
|
||||
private boolean hasExplicitPermission(Player player, ClaimPermission level)
|
||||
{
|
||||
String playerName = player.getName();
|
||||
Set<String> keys = this.playerNameToClaimPermissionMap.keySet();
|
||||
String playerID = player.getUniqueId().toString();
|
||||
Set<String> keys = this.playerIDToClaimPermissionMap.keySet();
|
||||
Iterator<String> iterator = keys.iterator();
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
String identifier = iterator.next();
|
||||
if(playerName.equalsIgnoreCase(identifier) && this.playerNameToClaimPermissionMap.get(identifier) == level) return true;
|
||||
if(playerID.equalsIgnoreCase(identifier) && this.playerIDToClaimPermissionMap.get(identifier) == level) return true;
|
||||
|
||||
else if(identifier.startsWith("[") && identifier.endsWith("]"))
|
||||
{
|
||||
|
|
@ -389,7 +390,7 @@ public class Claim
|
|||
if(permissionIdentifier == null || permissionIdentifier.isEmpty()) continue;
|
||||
|
||||
//check permission
|
||||
if(player.hasPermission(permissionIdentifier) && this.playerNameToClaimPermissionMap.get(identifier) == level) return true;
|
||||
if(player.hasPermission(permissionIdentifier) && this.playerIDToClaimPermissionMap.get(identifier) == level) return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -408,7 +409,7 @@ public class Claim
|
|||
for(int i = 0; i < GriefPrevention.instance.config_siege_blocks.size(); i++)
|
||||
{
|
||||
Material breakableMaterial = GriefPrevention.instance.config_siege_blocks.get(i);
|
||||
if(breakableMaterial.getId() == material.getId())
|
||||
if(breakableMaterial == material)
|
||||
{
|
||||
breakable = true;
|
||||
break;
|
||||
|
|
@ -420,7 +421,7 @@ public class Claim
|
|||
{
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NonSiegeMaterial);
|
||||
}
|
||||
else if(this.ownerName.equals(player.getName()))
|
||||
else if(player.getUniqueId().equals(this.ownerID))
|
||||
{
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoOwnerBuildUnderSiege);
|
||||
}
|
||||
|
|
@ -447,7 +448,7 @@ public class Claim
|
|||
}
|
||||
|
||||
//claim owner and admins in ignoreclaims mode have access
|
||||
if(this.ownerName.equals(player.getName()) || GriefPrevention.instance.dataStore.getPlayerData(player.getName()).ignoreClaims) return null;
|
||||
if(player.getUniqueId().equals(this.ownerID) || GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()).ignoreClaims) return null;
|
||||
|
||||
//look for explicit individual access, inventory, or build permission
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Access)) return null;
|
||||
|
|
@ -455,7 +456,7 @@ public class Claim
|
|||
if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null;
|
||||
|
||||
//also check for public permission
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
ClaimPermission permissionLevel = this.playerIDToClaimPermissionMap.get("public");
|
||||
if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel || ClaimPermission.Access == permissionLevel) return null;
|
||||
|
||||
//permission inheritance for subdivisions
|
||||
|
|
@ -485,7 +486,7 @@ 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;
|
||||
if(player.getUniqueId().equals(this.ownerID) || GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()).ignoreClaims) return null;
|
||||
|
||||
//admin claims need adminclaims permission only.
|
||||
if(this.isAdminClaim())
|
||||
|
|
@ -498,7 +499,7 @@ public class Claim
|
|||
if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null;
|
||||
|
||||
//check for public container or build permission
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
ClaimPermission permissionLevel = this.playerIDToClaimPermissionMap.get("public");
|
||||
if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel) return null;
|
||||
|
||||
//permission inheritance for subdivisions
|
||||
|
|
@ -525,7 +526,7 @@ public class Claim
|
|||
for(int i = 0; i < this.managers.size(); i++)
|
||||
{
|
||||
String managerID = this.managers.get(i);
|
||||
if(player.getName().equalsIgnoreCase(managerID)) return null;
|
||||
if(player.getUniqueId().toString().equals(managerID)) return null;
|
||||
|
||||
else if(managerID.startsWith("[") && managerID.endsWith("]"))
|
||||
{
|
||||
|
|
@ -547,21 +548,21 @@ public class Claim
|
|||
}
|
||||
|
||||
//grants a permission for a player or the public
|
||||
public void setPermission(String playerName, ClaimPermission permissionLevel)
|
||||
public void setPermission(String playerID, ClaimPermission permissionLevel)
|
||||
{
|
||||
this.playerNameToClaimPermissionMap.put(playerName.toLowerCase(), permissionLevel);
|
||||
this.playerIDToClaimPermissionMap.put(playerID.toLowerCase(), permissionLevel);
|
||||
}
|
||||
|
||||
//revokes a permission for a player or the public
|
||||
public void dropPermission(String playerName)
|
||||
public void dropPermission(String playerID)
|
||||
{
|
||||
this.playerNameToClaimPermissionMap.remove(playerName.toLowerCase());
|
||||
this.playerIDToClaimPermissionMap.remove(playerID.toLowerCase());
|
||||
}
|
||||
|
||||
//clears all permissions (except owner of course)
|
||||
public void clearPermissions()
|
||||
{
|
||||
this.playerNameToClaimPermissionMap.clear();
|
||||
this.playerIDToClaimPermissionMap.clear();
|
||||
}
|
||||
|
||||
//gets ALL permissions
|
||||
|
|
@ -569,7 +570,7 @@ public class Claim
|
|||
public void getPermissions(ArrayList<String> builders, ArrayList<String> containers, ArrayList<String> accessors, ArrayList<String> managers)
|
||||
{
|
||||
//loop through all the entries in the hash map
|
||||
Iterator<Map.Entry<String, ClaimPermission>> mappingsIterator = this.playerNameToClaimPermissionMap.entrySet().iterator();
|
||||
Iterator<Map.Entry<String, ClaimPermission>> mappingsIterator = this.playerIDToClaimPermissionMap.entrySet().iterator();
|
||||
while(mappingsIterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, ClaimPermission> entry = mappingsIterator.next();
|
||||
|
|
@ -615,10 +616,10 @@ public class Claim
|
|||
if(this.parent != null)
|
||||
return this.parent.getOwnerName();
|
||||
|
||||
if(this.ownerName.length() == 0)
|
||||
if(this.ownerID == null)
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.OwnerNameForAdminClaims);
|
||||
|
||||
return this.ownerName;
|
||||
return GriefPrevention.lookupPlayerName(this.ownerID);
|
||||
}
|
||||
|
||||
//whether or not a location is in a claim
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
boolean cleanupChunks = false;
|
||||
|
||||
//get data for the player, especially last login timestamp
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(claim.ownerName);
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(claim.ownerID);
|
||||
|
||||
//determine area of the default chest claim
|
||||
int areaOfDefaultClaim = 0;
|
||||
|
|
@ -118,7 +118,7 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
}
|
||||
|
||||
//delete them
|
||||
GriefPrevention.instance.dataStore.deleteClaimsForPlayer(claim.getOwnerName(), true);
|
||||
GriefPrevention.instance.dataStore.deleteClaimsForPlayer(claim.ownerID, true);
|
||||
GriefPrevention.AddLogEntry(" All of " + claim.getOwnerName() + "'s claims have expired.");
|
||||
|
||||
for(int i = 0; i < claims.size(); i++)
|
||||
|
|
@ -189,9 +189,9 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
}
|
||||
|
||||
//toss that player data out of the cache, it's probably not needed in memory right now
|
||||
if(!GriefPrevention.instance.getServer().getOfflinePlayer(claim.ownerName).isOnline())
|
||||
if(!GriefPrevention.instance.getServer().getOfflinePlayer(claim.ownerID).isOnline())
|
||||
{
|
||||
GriefPrevention.instance.dataStore.clearCachedPlayerData(claim.ownerName);
|
||||
GriefPrevention.instance.dataStore.clearCachedPlayerData(claim.ownerID);
|
||||
}
|
||||
|
||||
//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
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package me.ryanhamshire.GriefPrevention;
|
|||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
|
@ -32,7 +33,7 @@ import org.bukkit.inventory.ItemStack;
|
|||
public abstract class DataStore
|
||||
{
|
||||
//in-memory cache for player data
|
||||
protected ConcurrentHashMap<String, PlayerData> playerNameToPlayerDataMap = new ConcurrentHashMap<String, PlayerData>();
|
||||
protected ConcurrentHashMap<UUID, PlayerData> playerNameToPlayerDataMap = new ConcurrentHashMap<UUID, PlayerData>();
|
||||
|
||||
//in-memory cache for group (permission-based) data
|
||||
protected ConcurrentHashMap<String, Integer> permissionToBonusBlocksMap = new ConcurrentHashMap<String, Integer>();
|
||||
|
|
@ -43,6 +44,9 @@ public abstract class DataStore
|
|||
//in-memory cache for messages
|
||||
private String [] messages;
|
||||
|
||||
//pattern for unique user identifiers (UUIDs)
|
||||
protected final static Pattern uuidpattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
|
||||
|
||||
//next claim ID
|
||||
Long nextClaimID = (long)0;
|
||||
|
||||
|
|
@ -50,6 +54,35 @@ public abstract class DataStore
|
|||
protected final static String dataLayerFolderPath = "plugins" + File.separator + "GriefPreventionData";
|
||||
final static String configFilePath = dataLayerFolderPath + File.separator + "config.yml";
|
||||
final static String messagesFilePath = dataLayerFolderPath + File.separator + "messages.yml";
|
||||
|
||||
//the latest version of the data schema implemented here
|
||||
protected static final int latestSchemaVersion = 1;
|
||||
|
||||
//reading and writing the schema version to the data store
|
||||
abstract int getSchemaVersionFromStorage();
|
||||
abstract void updateSchemaVersionInStorage(int versionToSet);
|
||||
|
||||
//current version of the schema of data in secondary storage
|
||||
private int currentSchemaVersion = -1; //-1 means not determined yet
|
||||
|
||||
protected int getSchemaVersion()
|
||||
{
|
||||
if(this.currentSchemaVersion >= 0)
|
||||
{
|
||||
return this.currentSchemaVersion;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.currentSchemaVersion = this.getSchemaVersionFromStorage();
|
||||
return this.currentSchemaVersion;
|
||||
}
|
||||
}
|
||||
|
||||
protected void setSchemaVersion(int versionToSet)
|
||||
{
|
||||
this.currentSchemaVersion = versionToSet;
|
||||
this.updateSchemaVersionInStorage(versionToSet);
|
||||
}
|
||||
|
||||
//initialization!
|
||||
void initialize() throws Exception
|
||||
|
|
@ -57,7 +90,7 @@ public abstract class DataStore
|
|||
GriefPrevention.AddLogEntry(this.claims.size() + " total claims loaded.");
|
||||
|
||||
//make a list of players who own claims
|
||||
Vector<String> playerNames = new Vector<String>();
|
||||
Vector<UUID> playerNames = new Vector<UUID>();
|
||||
for(int i = 0; i < this.claims.size(); i++)
|
||||
{
|
||||
Claim claim = this.claims.get(i);
|
||||
|
|
@ -65,8 +98,8 @@ public abstract class DataStore
|
|||
//ignore admin claims
|
||||
if(claim.isAdminClaim()) continue;
|
||||
|
||||
if(!playerNames.contains(claim.ownerName))
|
||||
playerNames.add(claim.ownerName);
|
||||
if(!playerNames.contains(claim.ownerID))
|
||||
playerNames.add(claim.ownerID);
|
||||
}
|
||||
|
||||
GriefPrevention.AddLogEntry(playerNames.size() + " players have staked claims.");
|
||||
|
|
@ -74,18 +107,34 @@ public abstract class DataStore
|
|||
//load up all the messages from messages.yml
|
||||
this.loadMessages();
|
||||
|
||||
//if converting up from an earlier schema version, write all claims back to storage using the latest format
|
||||
if(this.getSchemaVersion() < this.latestSchemaVersion)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Please wait. Updating data format.");
|
||||
|
||||
for(Claim claim : this.claims)
|
||||
{
|
||||
this.saveClaim(claim);
|
||||
}
|
||||
}
|
||||
|
||||
//collect garbage, since lots of stuff was loaded into memory and then tossed out
|
||||
System.gc();
|
||||
|
||||
//make a note of the data store schema version
|
||||
this.setSchemaVersion(this.latestSchemaVersion);
|
||||
}
|
||||
|
||||
//removes cached player data from memory
|
||||
synchronized void clearCachedPlayerData(String playerName)
|
||||
synchronized void clearCachedPlayerData(UUID playerID)
|
||||
{
|
||||
this.playerNameToPlayerDataMap.remove(playerName);
|
||||
this.playerNameToPlayerDataMap.remove(playerID);
|
||||
}
|
||||
|
||||
//gets the number of bonus blocks a player has from his permissions
|
||||
synchronized int getGroupBonusBlocks(String playerName)
|
||||
//Bukkit doesn't allow for checking permissions of an offline player.
|
||||
//this will return 0 when he's offline, and the correct number when online.
|
||||
synchronized int getGroupBonusBlocks(UUID playerID)
|
||||
{
|
||||
int bonusBlocks = 0;
|
||||
Set<String> keys = permissionToBonusBlocksMap.keySet();
|
||||
|
|
@ -93,7 +142,7 @@ public abstract class DataStore
|
|||
while(iterator.hasNext())
|
||||
{
|
||||
String groupName = iterator.next();
|
||||
Player player = GriefPrevention.instance.getServer().getPlayer(playerName);
|
||||
Player player = GriefPrevention.instance.getServer().getPlayer(playerID);
|
||||
if(player != null && player.hasPermission(groupName))
|
||||
{
|
||||
bonusBlocks += this.permissionToBonusBlocksMap.get(groupName);
|
||||
|
|
@ -120,7 +169,7 @@ public abstract class DataStore
|
|||
|
||||
abstract void saveGroupBonusBlocks(String groupName, int amount);
|
||||
|
||||
synchronized public void changeClaimOwner(Claim claim, String newOwnerName) throws Exception
|
||||
synchronized public void changeClaimOwner(Claim claim, UUID newOwnerID) throws Exception
|
||||
{
|
||||
//if it's a subdivision, throw an exception
|
||||
if(claim.parent != null)
|
||||
|
|
@ -134,14 +183,14 @@ public abstract class DataStore
|
|||
PlayerData ownerData = null;
|
||||
if(!claim.isAdminClaim())
|
||||
{
|
||||
ownerData = this.getPlayerData(claim.ownerName);
|
||||
ownerData = this.getPlayerData(claim.ownerID);
|
||||
}
|
||||
|
||||
//determine new owner
|
||||
PlayerData newOwnerData = this.getPlayerData(newOwnerName);
|
||||
PlayerData newOwnerData = this.getPlayerData(newOwnerID);
|
||||
|
||||
//transfer
|
||||
claim.ownerName = newOwnerName;
|
||||
claim.ownerID = newOwnerID;
|
||||
this.saveClaim(claim);
|
||||
|
||||
//adjust blocks and other records
|
||||
|
|
@ -149,12 +198,12 @@ public abstract class DataStore
|
|||
{
|
||||
ownerData.claims.remove(claim);
|
||||
ownerData.bonusClaimBlocks -= claim.getArea();
|
||||
this.savePlayerData(claim.ownerName, ownerData);
|
||||
this.savePlayerData(claim.ownerID, ownerData);
|
||||
}
|
||||
|
||||
newOwnerData.claims.add(claim);
|
||||
newOwnerData.bonusClaimBlocks += claim.getArea();
|
||||
this.savePlayerData(newOwnerName, newOwnerData);
|
||||
this.savePlayerData(newOwnerID, newOwnerData);
|
||||
}
|
||||
|
||||
//adds a claim to the datastore, making it an effective claim
|
||||
|
|
@ -181,9 +230,9 @@ public abstract class DataStore
|
|||
//except for administrative claims (which have no owner), update the owner's playerData with the new claim
|
||||
if(!newClaim.isAdminClaim())
|
||||
{
|
||||
PlayerData ownerData = this.getPlayerData(newClaim.getOwnerName());
|
||||
PlayerData ownerData = this.getPlayerData(newClaim.ownerID);
|
||||
ownerData.claims.add(newClaim);
|
||||
this.savePlayerData(newClaim.getOwnerName(), ownerData);
|
||||
this.savePlayerData(newClaim.ownerID, ownerData);
|
||||
}
|
||||
|
||||
//make sure the claim is saved to disk
|
||||
|
|
@ -265,36 +314,36 @@ public abstract class DataStore
|
|||
|
||||
//retrieves player data from memory or secondary storage, as necessary
|
||||
//if the player has never been on the server before, this will return a fresh player data with default values
|
||||
synchronized public PlayerData getPlayerData(String playerName)
|
||||
synchronized public PlayerData getPlayerData(UUID playerID)
|
||||
{
|
||||
//first, look in memory
|
||||
PlayerData playerData = this.playerNameToPlayerDataMap.get(playerName);
|
||||
PlayerData playerData = this.playerNameToPlayerDataMap.get(playerID);
|
||||
|
||||
//if not there, look in secondary storage
|
||||
if(playerData == null)
|
||||
{
|
||||
playerData = this.getPlayerDataFromStorage(playerName);
|
||||
playerData.playerName = playerName;
|
||||
playerData = this.getPlayerDataFromStorage(playerID);
|
||||
playerData.playerID = playerID;
|
||||
|
||||
//find all the claims belonging to this player and note them for future reference
|
||||
for(int i = 0; i < this.claims.size(); i++)
|
||||
{
|
||||
Claim claim = this.claims.get(i);
|
||||
if(claim.ownerName.equals(playerName))
|
||||
if(playerID.equals(claim.ownerID))
|
||||
{
|
||||
playerData.claims.add(claim);
|
||||
}
|
||||
}
|
||||
|
||||
//shove that new player data into the hash map cache
|
||||
this.playerNameToPlayerDataMap.put(playerName, playerData);
|
||||
this.playerNameToPlayerDataMap.put(playerID, playerData);
|
||||
}
|
||||
|
||||
//try the hash map again. if it's STILL not there, we have a bug to fix
|
||||
return this.playerNameToPlayerDataMap.get(playerName);
|
||||
return this.playerNameToPlayerDataMap.get(playerID);
|
||||
}
|
||||
|
||||
abstract PlayerData getPlayerDataFromStorage(String playerName);
|
||||
abstract PlayerData getPlayerDataFromStorage(UUID playerID);
|
||||
|
||||
//deletes a claim or subdivision
|
||||
synchronized public void deleteClaim(Claim claim)
|
||||
|
|
@ -329,7 +378,7 @@ public abstract class DataStore
|
|||
//update player data, except for administrative claims, which have no owner
|
||||
if(!claim.isAdminClaim())
|
||||
{
|
||||
PlayerData ownerData = this.getPlayerData(claim.getOwnerName());
|
||||
PlayerData ownerData = this.getPlayerData(claim.ownerID);
|
||||
for(int i = 0; i < ownerData.claims.size(); i++)
|
||||
{
|
||||
if(ownerData.claims.get(i).id.equals(claim.id))
|
||||
|
|
@ -338,7 +387,7 @@ public abstract class DataStore
|
|||
break;
|
||||
}
|
||||
}
|
||||
this.savePlayerData(claim.getOwnerName(), ownerData);
|
||||
this.savePlayerData(claim.ownerID, ownerData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +443,7 @@ public abstract class DataStore
|
|||
//does NOT check a player has permission to create a claim, or enough claim blocks.
|
||||
//does NOT check minimum claim size constraints
|
||||
//does NOT visualize the new claim for any players
|
||||
synchronized public CreateClaimResult createClaim(World world, int x1, int x2, int y1, int y2, int z1, int z2, String ownerName, Claim parent, Long id)
|
||||
synchronized public CreateClaimResult createClaim(World world, int x1, int x2, int y1, int y2, int z1, int z2, UUID ownerID, Claim parent, Long id)
|
||||
{
|
||||
CreateClaimResult result = new CreateClaimResult();
|
||||
|
||||
|
|
@ -444,7 +493,7 @@ public abstract class DataStore
|
|||
Claim newClaim = new Claim(
|
||||
new Location(world, smallx, smally, smallz),
|
||||
new Location(world, bigx, bigy, bigz),
|
||||
ownerName,
|
||||
ownerID,
|
||||
new String [] {},
|
||||
new String [] {},
|
||||
new String [] {},
|
||||
|
|
@ -488,7 +537,7 @@ public abstract class DataStore
|
|||
}
|
||||
|
||||
//saves changes to player data to secondary storage. MUST be called after you're done making changes, otherwise a reload will lose them
|
||||
public abstract void savePlayerData(String playerName, PlayerData playerData);
|
||||
public abstract void savePlayerData(UUID playerID, PlayerData playerData);
|
||||
|
||||
//extends a claim to a new depth
|
||||
//respects the max depth config variable
|
||||
|
|
@ -522,8 +571,8 @@ public abstract class DataStore
|
|||
{
|
||||
//fill-in the necessary SiegeData instance
|
||||
SiegeData siegeData = new SiegeData(attacker, defender, defenderClaim);
|
||||
PlayerData attackerData = this.getPlayerData(attacker.getName());
|
||||
PlayerData defenderData = this.getPlayerData(defender.getName());
|
||||
PlayerData attackerData = this.getPlayerData(attacker.getUniqueId());
|
||||
PlayerData defenderData = this.getPlayerData(defender.getUniqueId());
|
||||
attackerData.siegeData = siegeData;
|
||||
defenderData.siegeData = siegeData;
|
||||
defenderClaim.siegeData = siegeData;
|
||||
|
|
@ -571,10 +620,10 @@ public abstract class DataStore
|
|||
grantAccess = true;
|
||||
}
|
||||
|
||||
PlayerData attackerData = this.getPlayerData(siegeData.attacker.getName());
|
||||
PlayerData attackerData = this.getPlayerData(siegeData.attacker.getUniqueId());
|
||||
attackerData.siegeData = null;
|
||||
|
||||
PlayerData defenderData = this.getPlayerData(siegeData.defender.getName());
|
||||
PlayerData defenderData = this.getPlayerData(siegeData.defender.getUniqueId());
|
||||
defenderData.siegeData = null;
|
||||
|
||||
//start a cooldown for this attacker/defender pair
|
||||
|
|
@ -587,7 +636,7 @@ public abstract class DataStore
|
|||
{
|
||||
Claim claim = siegeData.claims.get(i);
|
||||
claim.siegeData = null;
|
||||
this.siegeCooldownRemaining.put(siegeData.attacker.getName() + "_" + claim.ownerName, cooldownEnd);
|
||||
this.siegeCooldownRemaining.put(siegeData.attacker.getName() + "_" + claim.getOwnerName(), cooldownEnd);
|
||||
|
||||
//if doors should be opened for looting, do that now
|
||||
if(grantAccess)
|
||||
|
|
@ -674,9 +723,9 @@ public abstract class DataStore
|
|||
}
|
||||
|
||||
//look for an attacker/claim cooldown
|
||||
if(cooldownEnd == null && this.siegeCooldownRemaining.get(attacker.getName() + "_" + defenderClaim.ownerName) != null)
|
||||
if(cooldownEnd == null && this.siegeCooldownRemaining.get(attacker.getName() + "_" + defenderClaim.getOwnerName()) != null)
|
||||
{
|
||||
cooldownEnd = this.siegeCooldownRemaining.get(attacker.getName() + "_" + defenderClaim.ownerName);
|
||||
cooldownEnd = this.siegeCooldownRemaining.get(attacker.getName() + "_" + defenderClaim.getOwnerName());
|
||||
|
||||
if(Calendar.getInstance().getTimeInMillis() < cooldownEnd)
|
||||
{
|
||||
|
|
@ -684,7 +733,7 @@ public abstract class DataStore
|
|||
}
|
||||
|
||||
//if found but expired, remove it
|
||||
this.siegeCooldownRemaining.remove(attacker.getName() + "_" + defenderClaim.ownerName);
|
||||
this.siegeCooldownRemaining.remove(attacker.getName() + "_" + defenderClaim.getOwnerName());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -693,7 +742,7 @@ public abstract class DataStore
|
|||
//extend a siege, if it's possible to do so
|
||||
synchronized void tryExtendSiege(Player player, Claim claim)
|
||||
{
|
||||
PlayerData playerData = this.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.getPlayerData(player.getUniqueId());
|
||||
|
||||
//player must be sieged
|
||||
if(playerData.siegeData == null) return;
|
||||
|
|
@ -713,14 +762,14 @@ public abstract class DataStore
|
|||
}
|
||||
|
||||
//deletes all claims owned by a player
|
||||
synchronized public void deleteClaimsForPlayer(String playerName, boolean deleteCreativeClaims)
|
||||
synchronized public void deleteClaimsForPlayer(UUID playerID, boolean deleteCreativeClaims)
|
||||
{
|
||||
//make a list of the player's claims
|
||||
ArrayList<Claim> claimsToDelete = new ArrayList<Claim>();
|
||||
for(int i = 0; i < this.claims.size(); i++)
|
||||
{
|
||||
Claim claim = this.claims.get(i);
|
||||
if(claim.ownerName.equals(playerName) && (deleteCreativeClaims || !GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner())))
|
||||
if(playerID.equals(claim.ownerID) && (deleteCreativeClaims || !GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner())))
|
||||
claimsToDelete.add(claim);
|
||||
}
|
||||
|
||||
|
|
@ -748,7 +797,7 @@ public abstract class DataStore
|
|||
this.deleteClaim(claim);
|
||||
|
||||
//try to create this new claim, ignoring the original when checking for overlap
|
||||
CreateClaimResult result = this.createClaim(claim.getLesserBoundaryCorner().getWorld(), newx1, newx2, newy1, newy2, newz1, newz2, claim.ownerName, claim.parent, claim.id);
|
||||
CreateClaimResult result = this.createClaim(claim.getLesserBoundaryCorner().getWorld(), newx1, newx2, newy1, newy2, newz1, newz2, claim.ownerID, claim.parent, claim.id);
|
||||
|
||||
//if succeeded
|
||||
if(result.succeeded)
|
||||
|
|
@ -1031,5 +1080,49 @@ public abstract class DataStore
|
|||
return message;
|
||||
}
|
||||
|
||||
abstract void close();
|
||||
//used in updating the data schema from 0 to 1.
|
||||
//converts player names in a list to uuids
|
||||
protected String[] convertNameListToUUIDList(String[] names)
|
||||
{
|
||||
//doesn't apply after schema has been updated to version 1
|
||||
if(this.getSchemaVersion() >= 1) return names;
|
||||
|
||||
//list to build results
|
||||
List<String> resultNames = new ArrayList<String>();
|
||||
|
||||
for(String name : names)
|
||||
{
|
||||
//skip non-player-names (groups and "public"), leave them as-is
|
||||
if(name.startsWith("[") || name.equals("public"))
|
||||
{
|
||||
resultNames.add(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
//otherwise try to convert to a UUID
|
||||
UUID playerID = null;
|
||||
try
|
||||
{
|
||||
playerID = UUIDFetcher.getUUIDOf(name);
|
||||
}
|
||||
catch(Exception ex){ }
|
||||
|
||||
//if successful, replace player name with corresponding UUID
|
||||
if(playerID != null)
|
||||
{
|
||||
resultNames.add(playerID.toString());
|
||||
}
|
||||
}
|
||||
|
||||
//return final result of conversion
|
||||
String [] resultArray = new String [resultNames.size()];
|
||||
for(int i = 0; i < resultNames.size(); i++)
|
||||
{
|
||||
resultArray[i] = resultNames.get(i);
|
||||
}
|
||||
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
abstract void close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,16 @@ public class DatabaseDataStore extends DataStore
|
|||
statement.execute("CREATE TABLE IF NOT EXISTS griefprevention_claimdata (id INT(15), owner VARCHAR(50), lessercorner VARCHAR(100), greatercorner VARCHAR(100), builders VARCHAR(1000), containers VARCHAR(1000), accessors VARCHAR(1000), managers VARCHAR(1000), parentid INT(15));");
|
||||
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS griefprevention_playerdata (name VARCHAR(50), lastlogin DATETIME, accruedblocks INT(15), bonusblocks INT(15));");
|
||||
|
||||
statement.execute("CREATE TABLE IF NOT EXISTS griefprevention_schemaversion (version INT(15));");
|
||||
|
||||
//if the next claim id table is empty, this is a brand new database which will write using the latest schema
|
||||
//otherwise, schema version is determined by schemaversion table (or =0 if table is empty, see getSchemaVersion())
|
||||
ResultSet results = statement.executeQuery("SELECT * FROM griefprevention_nextclaimid;");
|
||||
if(!results.next())
|
||||
{
|
||||
this.setSchemaVersion(latestSchemaVersion);
|
||||
}
|
||||
}
|
||||
catch(Exception e3)
|
||||
{
|
||||
|
|
@ -145,20 +155,49 @@ public class DatabaseDataStore extends DataStore
|
|||
Location greaterBoundaryCorner = this.locationFromString(greaterCornerString);
|
||||
|
||||
String ownerName = results.getString("owner");
|
||||
UUID ownerID = null;
|
||||
if(ownerName.isEmpty())
|
||||
{
|
||||
ownerID = null; //administrative land claim
|
||||
}
|
||||
else if(this.getSchemaVersion() < 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
ownerID = UUIDFetcher.getUUIDOf(ownerName);
|
||||
}
|
||||
catch(Exception ex){ } //if UUID not found, use NULL
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
ownerID = UUID.fromString(ownerName);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Failed to look up UUID for player " + ownerName + ".");
|
||||
GriefPrevention.AddLogEntry(" Converted land claim to administrative @ " + lesserBoundaryCorner.toString());
|
||||
}
|
||||
}
|
||||
|
||||
String buildersString = results.getString("builders");
|
||||
String [] builderNames = buildersString.split(";");
|
||||
builderNames = this.convertNameListToUUIDList(builderNames);
|
||||
|
||||
String containersString = results.getString("containers");
|
||||
String [] containerNames = containersString.split(";");
|
||||
containerNames = this.convertNameListToUUIDList(containerNames);
|
||||
|
||||
String accessorsString = results.getString("accessors");
|
||||
String [] accessorNames = accessorsString.split(";");
|
||||
accessorNames = this.convertNameListToUUIDList(accessorNames);
|
||||
|
||||
String managersString = results.getString("managers");
|
||||
String [] managerNames = managersString.split(";");
|
||||
managerNames = this.convertNameListToUUIDList(managerNames);
|
||||
|
||||
Claim topLevelClaim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerName, builderNames, containerNames, accessorNames, managerNames, claimID);
|
||||
Claim topLevelClaim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerID, builderNames, containerNames, accessorNames, managerNames, claimID);
|
||||
|
||||
//search for another claim overlapping this one
|
||||
Claim conflictClaim = this.getClaimAt(topLevelClaim.lesserBoundaryCorner, true, null);
|
||||
|
|
@ -196,17 +235,21 @@ public class DatabaseDataStore extends DataStore
|
|||
|
||||
buildersString = childResults.getString("builders");
|
||||
builderNames = buildersString.split(";");
|
||||
builderNames = this.convertNameListToUUIDList(builderNames);
|
||||
|
||||
containersString = childResults.getString("containers");
|
||||
containerNames = containersString.split(";");
|
||||
containerNames = this.convertNameListToUUIDList(containerNames);
|
||||
|
||||
accessorsString = childResults.getString("accessors");
|
||||
accessorNames = accessorsString.split(";");
|
||||
accessorNames = this.convertNameListToUUIDList(accessorNames);
|
||||
|
||||
managersString = childResults.getString("managers");
|
||||
managerNames = managersString.split(";");
|
||||
managerNames = this.convertNameListToUUIDList(managerNames);
|
||||
|
||||
Claim childClaim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerName, builderNames, containerNames, accessorNames, managerNames, null);
|
||||
Claim childClaim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, null, builderNames, containerNames, accessorNames, managerNames, null);
|
||||
|
||||
//add this claim to the list of children of the current top level claim
|
||||
childClaim.parent = topLevelClaim;
|
||||
|
|
@ -226,6 +269,57 @@ public class DatabaseDataStore extends DataStore
|
|||
this.deleteClaimFromSecondaryStorage(claimsToRemove.get(i));
|
||||
}
|
||||
|
||||
if(this.getSchemaVersion() == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.refreshDataConnection();
|
||||
|
||||
//pull ALL player data from the database
|
||||
statement = this.databaseConnection.createStatement();
|
||||
results = statement.executeQuery("SELECT * FROM griefprevention_playerdata;");
|
||||
|
||||
//make a list of changes to be made
|
||||
HashMap<String, UUID> changes = new HashMap<String, UUID>();
|
||||
|
||||
//for each result
|
||||
while(results.next())
|
||||
{
|
||||
//get the id
|
||||
String playerName = results.getString("name");
|
||||
|
||||
//ignore groups
|
||||
if(playerName.startsWith("$")) continue;
|
||||
|
||||
//try to convert player name to UUID
|
||||
try
|
||||
{
|
||||
UUID playerID = UUIDFetcher.getUUIDOf(playerName);
|
||||
|
||||
//if successful, update the playerdata row by replacing the player's name with the player's UUID
|
||||
if(playerID != null)
|
||||
{
|
||||
changes.put(playerName, playerID);
|
||||
}
|
||||
}
|
||||
//otherwise leave it as-is. no harm done - it won't be requested by name, and this update only happens once.
|
||||
catch(Exception ex){ }
|
||||
}
|
||||
|
||||
for(String name : changes.keySet())
|
||||
{
|
||||
statement = this.databaseConnection.createStatement();
|
||||
statement.execute("UPDATE griefprevention_playerdata SET name = '" + changes.get(name).toString() + "' WHERE name = '" + name + "';");
|
||||
}
|
||||
}
|
||||
catch(SQLException e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to convert player data. Details:");
|
||||
GriefPrevention.AddLogEntry(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +355,8 @@ public class DatabaseDataStore extends DataStore
|
|||
{
|
||||
String lesserCornerString = this.locationToString(claim.getLesserBoundaryCorner());
|
||||
String greaterCornerString = this.locationToString(claim.getGreaterBoundaryCorner());
|
||||
String owner = claim.ownerName;
|
||||
String owner = "";
|
||||
if(claim.ownerID != null) owner = claim.ownerID.toString();
|
||||
|
||||
ArrayList<String> builders = new ArrayList<String>();
|
||||
ArrayList<String> containers = new ArrayList<String>();
|
||||
|
|
@ -358,22 +453,22 @@ public class DatabaseDataStore extends DataStore
|
|||
}
|
||||
|
||||
@Override
|
||||
synchronized PlayerData getPlayerDataFromStorage(String playerName)
|
||||
synchronized PlayerData getPlayerDataFromStorage(UUID playerID)
|
||||
{
|
||||
PlayerData playerData = new PlayerData();
|
||||
playerData.playerName = playerName;
|
||||
playerData.playerID = playerID;
|
||||
|
||||
try
|
||||
{
|
||||
this.refreshDataConnection();
|
||||
|
||||
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='" + playerID.toString() + "';");
|
||||
|
||||
//if there's no data for this player, create it with defaults
|
||||
if(!results.next())
|
||||
{
|
||||
this.savePlayerData(playerName, playerData);
|
||||
this.savePlayerData(playerID, playerData);
|
||||
}
|
||||
|
||||
//otherwise, just read from the database
|
||||
|
|
@ -386,7 +481,7 @@ public class DatabaseDataStore extends DataStore
|
|||
}
|
||||
catch(SQLException e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to retrieve data for player " + playerName + ". Details:");
|
||||
GriefPrevention.AddLogEntry("Unable to retrieve data for player " + playerID.toString() + ". Details:");
|
||||
GriefPrevention.AddLogEntry(e.getMessage());
|
||||
}
|
||||
|
||||
|
|
@ -395,11 +490,16 @@ public class DatabaseDataStore extends DataStore
|
|||
|
||||
//saves changes to player data. MUST be called after you're done making changes, otherwise a reload will lose them
|
||||
@Override
|
||||
synchronized public void savePlayerData(String playerName, PlayerData playerData)
|
||||
synchronized public void savePlayerData(UUID playerID, PlayerData playerData)
|
||||
{
|
||||
//never save data for the "administrative" account. an empty string for player name indicates administrative account
|
||||
if(playerName.length() == 0) return;
|
||||
if(playerID == null) return;
|
||||
|
||||
this.savePlayerData(playerID.toString(), playerData);
|
||||
}
|
||||
|
||||
private void savePlayerData(String playerID, PlayerData playerData)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.refreshDataConnection();
|
||||
|
|
@ -408,12 +508,12 @@ public class DatabaseDataStore extends DataStore
|
|||
String dateString = sqlFormat.format(playerData.lastLogin);
|
||||
|
||||
Statement statement = databaseConnection.createStatement();
|
||||
statement.execute("DELETE FROM griefprevention_playerdata WHERE name='" + playerName + "';");
|
||||
statement.execute("INSERT INTO griefprevention_playerdata VALUES ('" + playerName + "', '" + dateString + "', " + playerData.accruedClaimBlocks + ", " + playerData.bonusClaimBlocks + ");");
|
||||
statement.execute("DELETE FROM griefprevention_playerdata WHERE name='" + playerID.toString() + "';");
|
||||
statement.execute("INSERT INTO griefprevention_playerdata VALUES ('" + playerID.toString() + "', '" + dateString + "', " + playerData.accruedClaimBlocks + ", " + playerData.bonusClaimBlocks + ");");
|
||||
}
|
||||
catch(SQLException e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to save data for player " + playerName + ". Details:");
|
||||
GriefPrevention.AddLogEntry("Unable to save data for player " + playerID.toString() + ". Details:");
|
||||
GriefPrevention.AddLogEntry(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -487,4 +587,54 @@ public class DatabaseDataStore extends DataStore
|
|||
this.databaseConnection = DriverManager.getConnection(this.databaseUrl, connectionProps);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSchemaVersionFromStorage()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.refreshDataConnection();
|
||||
|
||||
Statement statement = this.databaseConnection.createStatement();
|
||||
ResultSet results = statement.executeQuery("SELECT * FROM griefprevention_schemaversion;");
|
||||
|
||||
//if there's nothing yet, assume 0 and add it
|
||||
if(!results.next())
|
||||
{
|
||||
this.setSchemaVersion(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//otherwise return the value that's in the table
|
||||
else
|
||||
{
|
||||
return results.getInt(0);
|
||||
}
|
||||
|
||||
}
|
||||
catch(SQLException e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to retrieve schema version from database. Details:");
|
||||
GriefPrevention.AddLogEntry(e.getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateSchemaVersionInStorage(int versionToSet)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.refreshDataConnection();
|
||||
|
||||
Statement statement = databaseConnection.createStatement();
|
||||
statement.execute("DELETE FROM griefprevention_schemaversion;");
|
||||
statement.execute("INSERT INTO griefprevention_schemaversion VALUES (" + versionToSet + ");");
|
||||
}
|
||||
catch(SQLException e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to set next schema version to " + versionToSet + ". Details:");
|
||||
GriefPrevention.AddLogEntry(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class DeliverClaimBlocksTask implements Runnable
|
|||
{
|
||||
Player player = players[i];
|
||||
DataStore dataStore = GriefPrevention.instance.dataStore;
|
||||
PlayerData playerData = dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
Location lastLocation = playerData.lastAfkCheckLocation;
|
||||
try //distance squared will throw an exception if the player has changed worlds
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ class EntityEventHandler implements Listener
|
|||
if(!(entity instanceof Player)) return; //only tracking players
|
||||
|
||||
Player player = (Player)entity;
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//if involved in a siege
|
||||
if(playerData.siegeData != null)
|
||||
|
|
@ -327,7 +327,7 @@ class EntityEventHandler implements Listener
|
|||
//otherwise, apply entity-count limitations for creative worlds
|
||||
else if(GriefPrevention.instance.creativeRulesApply(event.getEntity().getLocation()))
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(event.getBlock().getLocation(), false, playerData.lastClaim);
|
||||
if(claim == null) return;
|
||||
|
||||
|
|
@ -389,8 +389,8 @@ class EntityEventHandler implements Listener
|
|||
|
||||
Player defender = (Player)(event.getEntity());
|
||||
|
||||
PlayerData defenderData = this.dataStore.getPlayerData(((Player)event.getEntity()).getName());
|
||||
PlayerData attackerData = this.dataStore.getPlayerData(attacker.getName());
|
||||
PlayerData defenderData = this.dataStore.getPlayerData(((Player)event.getEntity()).getUniqueId());
|
||||
PlayerData attackerData = this.dataStore.getPlayerData(attacker.getUniqueId());
|
||||
|
||||
//otherwise if protecting spawning players
|
||||
if(GriefPrevention.instance.config_pvp_protectFreshSpawns)
|
||||
|
|
@ -461,7 +461,7 @@ class EntityEventHandler implements Listener
|
|||
PlayerData playerData = null;
|
||||
if(attacker != null)
|
||||
{
|
||||
playerData = this.dataStore.getPlayerData(attacker.getName());
|
||||
playerData = this.dataStore.getPlayerData(attacker.getUniqueId());
|
||||
cachedClaim = playerData.lastClaim;
|
||||
}
|
||||
|
||||
|
|
@ -495,7 +495,7 @@ class EntityEventHandler implements Listener
|
|||
PlayerData playerData = null;
|
||||
if(attacker != null)
|
||||
{
|
||||
playerData = this.dataStore.getPlayerData(attacker.getName());
|
||||
playerData = this.dataStore.getPlayerData(attacker.getUniqueId());
|
||||
cachedClaim = playerData.lastClaim;
|
||||
}
|
||||
|
||||
|
|
@ -583,7 +583,7 @@ class EntityEventHandler implements Listener
|
|||
PlayerData playerData = null;
|
||||
if(attacker != null)
|
||||
{
|
||||
playerData = this.dataStore.getPlayerData(attacker.getName());
|
||||
playerData = this.dataStore.getPlayerData(attacker.getUniqueId());
|
||||
cachedClaim = playerData.lastClaim;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class EquipShovelProcessingTask implements Runnable
|
|||
//if he's not holding the golden shovel anymore, do nothing
|
||||
if(player.getItemInHand().getType() != GriefPrevention.instance.config_claims_modificationTool) return;
|
||||
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
int remainingBlocks = playerData.getRemainingClaimBlocks();
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ import java.text.ParseException;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.*;
|
||||
|
||||
//manages data stored in the file system
|
||||
|
|
@ -34,9 +32,8 @@ public class FlatFileDataStore extends DataStore
|
|||
private final static String playerDataFolderPath = dataLayerFolderPath + File.separator + "PlayerData";
|
||||
private final static String claimDataFolderPath = dataLayerFolderPath + File.separator + "ClaimData";
|
||||
private final static String nextClaimIdFilePath = claimDataFolderPath + File.separator + "_nextClaimID";
|
||||
private final static String schemaVersionFilePath = dataLayerFolderPath + File.separator + "_schemaVersion";
|
||||
|
||||
private final static Pattern uuidpattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
|
||||
|
||||
static boolean hasData()
|
||||
{
|
||||
File playerDataFolder = new File(playerDataFolderPath);
|
||||
|
|
@ -55,11 +52,23 @@ public class FlatFileDataStore extends DataStore
|
|||
void initialize() throws Exception
|
||||
{
|
||||
//ensure data folders exist
|
||||
new File(playerDataFolderPath).mkdirs();
|
||||
new File(claimDataFolderPath).mkdirs();
|
||||
boolean newDataStore = false;
|
||||
File playerDataFolder = new File(playerDataFolderPath);
|
||||
File claimDataFolder = new File(claimDataFolderPath);
|
||||
if(!playerDataFolder.exists() || !claimDataFolder.exists())
|
||||
{
|
||||
newDataStore = true;
|
||||
playerDataFolder.mkdirs();
|
||||
claimDataFolder.mkdirs();
|
||||
}
|
||||
|
||||
//if there's no data yet, then anything written will use the schema implemented by this code
|
||||
if(newDataStore)
|
||||
{
|
||||
this.setSchemaVersion(DataStore.latestSchemaVersion);
|
||||
}
|
||||
|
||||
//load group data into memory
|
||||
File playerDataFolder = new File(playerDataFolderPath);
|
||||
File [] files = playerDataFolder.listFiles();
|
||||
for(int i = 0; i < files.length; i++)
|
||||
{
|
||||
|
|
@ -120,14 +129,13 @@ public class FlatFileDataStore extends DataStore
|
|||
|
||||
//load claims data into memory
|
||||
//get a list of all the files in the claims data folder
|
||||
File claimDataFolder = new File(claimDataFolderPath);
|
||||
files = claimDataFolder.listFiles();
|
||||
|
||||
for(int i = 0; i < files.length; i++)
|
||||
{
|
||||
if(files[i].isFile()) //avoids folders
|
||||
{
|
||||
//skip any file starting with an underscore, to avoid the _nextClaimID file.
|
||||
//skip any file starting with an underscore, to avoid special files not representing land claims
|
||||
if(files[i].getName().startsWith("_")) continue;
|
||||
|
||||
//the filename is the claim ID. try to parse it
|
||||
|
|
@ -182,23 +190,52 @@ public class FlatFileDataStore extends DataStore
|
|||
//third line is owner name
|
||||
line = inStream.readLine();
|
||||
String ownerName = line;
|
||||
UUID ownerID = null;
|
||||
if(ownerName.isEmpty() || ownerName.startsWith("--"))
|
||||
{
|
||||
ownerID = null; //administrative land claim or subdivision
|
||||
}
|
||||
else if(this.getSchemaVersion() == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
ownerID = UUIDFetcher.getUUIDOf(ownerName);
|
||||
}
|
||||
catch(Exception ex){ } //if UUID not found, use NULL
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
ownerID = UUID.fromString(ownerName);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Failed to look up UUID for player " + ownerName + ".");
|
||||
GriefPrevention.AddLogEntry(" Converted land claim to administrative @ " + lesserBoundaryCorner.toString());
|
||||
}
|
||||
}
|
||||
|
||||
//fourth line is list of builders
|
||||
line = inStream.readLine();
|
||||
String [] builderNames = line.split(";");
|
||||
builderNames = this.convertNameListToUUIDList(builderNames);
|
||||
|
||||
//fifth line is list of players who can access containers
|
||||
line = inStream.readLine();
|
||||
String [] containerNames = line.split(";");
|
||||
containerNames = this.convertNameListToUUIDList(containerNames);
|
||||
|
||||
//sixth line is list of players who can use buttons and switches
|
||||
line = inStream.readLine();
|
||||
String [] accessorNames = line.split(";");
|
||||
accessorNames = this.convertNameListToUUIDList(accessorNames);
|
||||
|
||||
//seventh line is list of players who can grant permissions
|
||||
line = inStream.readLine();
|
||||
if(line == null) line = "";
|
||||
String [] managerNames = line.split(";");
|
||||
managerNames = this.convertNameListToUUIDList(managerNames);
|
||||
|
||||
//skip any remaining extra lines, until the "===" string, indicating the end of this claim or subdivision
|
||||
line = inStream.readLine();
|
||||
|
|
@ -210,7 +247,7 @@ public class FlatFileDataStore extends DataStore
|
|||
if(topLevelClaim == null)
|
||||
{
|
||||
//instantiate
|
||||
topLevelClaim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerName, builderNames, containerNames, accessorNames, managerNames, claimID);
|
||||
topLevelClaim = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, ownerID, builderNames, containerNames, accessorNames, managerNames, claimID);
|
||||
|
||||
//search for another claim overlapping this one
|
||||
Claim conflictClaim = this.getClaimAt(topLevelClaim.lesserBoundaryCorner, true, null);
|
||||
|
|
@ -241,7 +278,7 @@ public class FlatFileDataStore extends DataStore
|
|||
//otherwise there's already a top level claim, so this must be a subdivision of that top level claim
|
||||
else
|
||||
{
|
||||
Claim subdivision = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, "--subdivision--", builderNames, containerNames, accessorNames, managerNames, null);
|
||||
Claim subdivision = new Claim(lesserBoundaryCorner, greaterBoundaryCorner, null, builderNames, containerNames, accessorNames, managerNames, null);
|
||||
|
||||
subdivision.modifiedDate = new Date(files[i].lastModified());
|
||||
subdivision.parent = topLevelClaim;
|
||||
|
|
@ -259,7 +296,7 @@ public class FlatFileDataStore extends DataStore
|
|||
//if there's any problem with the file's content, log an error message and skip it
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to load data for claim \"" + files[i].getName() + "\": " + e.getMessage());
|
||||
GriefPrevention.AddLogEntry("Unable to load data for claim \"" + files[i].getName() + "\": " + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -270,6 +307,42 @@ public class FlatFileDataStore extends DataStore
|
|||
}
|
||||
}
|
||||
|
||||
//if converting up from schema version 0, rename files using UUIDs instead of player names
|
||||
//get a list of all the files in the claims data folder
|
||||
if(this.getSchemaVersion() == 0)
|
||||
{
|
||||
files = playerDataFolder.listFiles();
|
||||
for(File playerFile : files)
|
||||
{
|
||||
//anything starting with an underscore or dollar sign isn't a player, ignore those
|
||||
String currentFilename = playerFile.getName();
|
||||
if(currentFilename.startsWith("$") || currentFilename.startsWith("_")) continue;
|
||||
|
||||
//try to convert player name to UUID
|
||||
UUID playerID = null;
|
||||
try
|
||||
{
|
||||
playerID = UUIDFetcher.getUUIDOf(currentFilename);
|
||||
|
||||
//if successful, rename the file using the UUID
|
||||
if(playerID != null)
|
||||
{
|
||||
playerFile.renameTo(new File(playerDataFolder, playerID.toString()));
|
||||
}
|
||||
|
||||
//otherwise hide it from the data store for the future
|
||||
else
|
||||
{
|
||||
playerFile.renameTo(new File(playerDataFolder, "__" + currentFilename));
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
playerFile.renameTo(new File(playerDataFolder, "__" + currentFilename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
|
|
@ -301,7 +374,8 @@ public class FlatFileDataStore extends DataStore
|
|||
//if any problem, log it
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unexpected exception saving data for claim \"" + claimID + "\": " + e.getMessage());
|
||||
GriefPrevention.AddLogEntry("Unexpected exception saving data for claim \"" + claimID + "\": " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//close the file
|
||||
|
|
@ -324,7 +398,9 @@ public class FlatFileDataStore extends DataStore
|
|||
outStream.newLine();
|
||||
|
||||
//third line is owner name
|
||||
outStream.write(claim.ownerName);
|
||||
String lineToWrite = "";
|
||||
if(claim.ownerID != null) lineToWrite = claim.ownerID.toString();
|
||||
outStream.write(lineToWrite);
|
||||
outStream.newLine();
|
||||
|
||||
ArrayList<String> builders = new ArrayList<String>();
|
||||
|
|
@ -382,18 +458,18 @@ public class FlatFileDataStore extends DataStore
|
|||
}
|
||||
|
||||
@Override
|
||||
synchronized PlayerData getPlayerDataFromStorage(String playerName)
|
||||
synchronized PlayerData getPlayerDataFromStorage(UUID playerID)
|
||||
{
|
||||
File playerFile = new File(playerDataFolderPath + File.separator + playerName);
|
||||
File playerFile = new File(playerDataFolderPath + File.separator + playerID.toString());
|
||||
|
||||
PlayerData playerData = new PlayerData();
|
||||
playerData.playerName = playerName;
|
||||
playerData.playerID = playerID;
|
||||
|
||||
//if it doesn't exist as a file
|
||||
if(!playerFile.exists())
|
||||
{
|
||||
//create a file with defaults
|
||||
this.savePlayerData(playerName, playerData);
|
||||
this.savePlayerData(playerID, playerData);
|
||||
}
|
||||
|
||||
//otherwise, read the file
|
||||
|
|
@ -441,7 +517,7 @@ public class FlatFileDataStore extends DataStore
|
|||
//if there's any problem with the file's content, log an error message
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to load data for player \"" + playerName + "\": " + e.getMessage());
|
||||
GriefPrevention.AddLogEntry("Unable to load data for player \"" + playerID.toString() + "\": " + e.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -456,16 +532,16 @@ public class FlatFileDataStore extends DataStore
|
|||
|
||||
//saves changes to player data. MUST be called after you're done making changes, otherwise a reload will lose them
|
||||
@Override
|
||||
synchronized public void savePlayerData(String playerName, PlayerData playerData)
|
||||
synchronized public void savePlayerData(UUID playerID, PlayerData playerData)
|
||||
{
|
||||
//never save data for the "administrative" account. an empty string for claim owner indicates administrative account
|
||||
if(playerName.length() == 0) return;
|
||||
//never save data for the "administrative" account. null for claim owner ID indicates administrative account
|
||||
if(playerID == null) return;
|
||||
|
||||
BufferedWriter outStream = null;
|
||||
try
|
||||
{
|
||||
//open the player's file
|
||||
File playerDataFile = new File(playerDataFolderPath + File.separator + playerName);
|
||||
File playerDataFile = new File(playerDataFolderPath + File.separator + playerID.toString());
|
||||
playerDataFile.createNewFile();
|
||||
outStream = new BufferedWriter(new FileWriter(playerDataFile));
|
||||
|
||||
|
|
@ -498,7 +574,7 @@ public class FlatFileDataStore extends DataStore
|
|||
//if any problem, log it
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("GriefPrevention: Unexpected exception saving data for player \"" + playerName + "\": " + e.getMessage());
|
||||
GriefPrevention.AddLogEntry("GriefPrevention: Unexpected exception saving data for player \"" + playerID.toString() + "\": " + e.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -607,9 +683,12 @@ public class FlatFileDataStore extends DataStore
|
|||
//all group data files start with a dollar sign. ignoring those, already handled above
|
||||
if(file.getName().startsWith("$")) continue;
|
||||
|
||||
String playerName = file.getName();
|
||||
databaseStore.savePlayerData(playerName, this.getPlayerData(playerName));
|
||||
this.clearCachedPlayerData(playerName);
|
||||
//ignore special files (claimID)
|
||||
if(file.getName().startsWith("_")) continue;
|
||||
|
||||
UUID playerID = UUID.fromString(file.getName());
|
||||
databaseStore.savePlayerData(playerID, this.getPlayerData(playerID));
|
||||
this.clearCachedPlayerData(playerID);
|
||||
}
|
||||
|
||||
//migrate next claim ID
|
||||
|
|
@ -647,4 +726,69 @@ public class FlatFileDataStore extends DataStore
|
|||
|
||||
@Override
|
||||
synchronized void close() { }
|
||||
|
||||
@Override
|
||||
int getSchemaVersionFromStorage()
|
||||
{
|
||||
File schemaVersionFile = new File(schemaVersionFilePath);
|
||||
if(schemaVersionFile.exists())
|
||||
{
|
||||
BufferedReader inStream = null;
|
||||
int schemaVersion = 0;
|
||||
try
|
||||
{
|
||||
inStream = new BufferedReader(new FileReader(schemaVersionFile.getAbsolutePath()));
|
||||
|
||||
//read the version number
|
||||
String line = inStream.readLine();
|
||||
|
||||
//try to parse into an int value
|
||||
schemaVersion = Integer.parseInt(line);
|
||||
}
|
||||
catch(Exception e){ }
|
||||
|
||||
try
|
||||
{
|
||||
if(inStream != null) inStream.close();
|
||||
}
|
||||
catch(IOException exception) {}
|
||||
|
||||
return schemaVersion;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.updateSchemaVersionInStorage(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void updateSchemaVersionInStorage(int versionToSet)
|
||||
{
|
||||
BufferedWriter outStream = null;
|
||||
|
||||
try
|
||||
{
|
||||
//open the file and write the new value
|
||||
File schemaVersionFile = new File(schemaVersionFilePath);
|
||||
schemaVersionFile.createNewFile();
|
||||
outStream = new BufferedWriter(new FileWriter(schemaVersionFile));
|
||||
|
||||
outStream.write(String.valueOf(versionToSet));
|
||||
}
|
||||
|
||||
//if any problem, log it
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unexpected exception saving schema version: " + e.getMessage());
|
||||
}
|
||||
|
||||
//close the file
|
||||
try
|
||||
{
|
||||
if(outStream != null) outStream.close();
|
||||
}
|
||||
catch(IOException exception) {}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
|||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
|
@ -802,7 +803,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//ignoreclaims
|
||||
if(cmd.getName().equalsIgnoreCase("ignoreclaims") && player != null)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
playerData.ignoreClaims = !playerData.ignoreClaims;
|
||||
|
||||
|
|
@ -831,7 +832,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//count claims
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
int originalClaimCount = playerData.claims.size();
|
||||
|
||||
//check count
|
||||
|
|
@ -842,7 +843,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//delete them
|
||||
this.dataStore.deleteClaimsForPlayer(player.getName(), false);
|
||||
this.dataStore.deleteClaimsForPlayer(player.getUniqueId(), false);
|
||||
|
||||
//inform the player
|
||||
int remainingBlocks = playerData.getRemainingClaimBlocks();
|
||||
|
|
@ -858,7 +859,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
else if(cmd.getName().equalsIgnoreCase("restorenature") && player != null)
|
||||
{
|
||||
//change shovel mode
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.shovelMode = ShovelMode.RestoreNature;
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RestoreNatureActivate);
|
||||
return true;
|
||||
|
|
@ -868,7 +869,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
else if(cmd.getName().equalsIgnoreCase("restorenatureaggressive") && player != null)
|
||||
{
|
||||
//change shovel mode
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.shovelMode = ShovelMode.RestoreNatureAggressive;
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.RestoreNatureAggressiveActivate);
|
||||
return true;
|
||||
|
|
@ -878,7 +879,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
else if(cmd.getName().equalsIgnoreCase("restorenaturefill") && player != null)
|
||||
{
|
||||
//change shovel mode
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.shovelMode = ShovelMode.RestoreNatureFill;
|
||||
|
||||
//set radius based on arguments
|
||||
|
|
@ -931,7 +932,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
return true;
|
||||
}
|
||||
|
||||
OfflinePlayer targetPlayer = this.resolvePlayer(args[0]);
|
||||
OfflinePlayer targetPlayer = this.resolvePlayerByName(args[0]);
|
||||
if(targetPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
|
|
@ -941,7 +942,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//change ownerhsip
|
||||
try
|
||||
{
|
||||
this.dataStore.changeClaimOwner(claim, targetPlayer.getName());
|
||||
this.dataStore.changeClaimOwner(claim, targetPlayer.getUniqueId());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
|
@ -992,7 +993,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(managers.size() > 0)
|
||||
{
|
||||
for(int i = 0; i < managers.size(); i++)
|
||||
permissions.append(managers.get(i) + " ");
|
||||
permissions.append(this.trustEntryToPlayerName(managers.get(i)) + " ");
|
||||
}
|
||||
|
||||
player.sendMessage(permissions.toString());
|
||||
|
|
@ -1002,7 +1003,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(builders.size() > 0)
|
||||
{
|
||||
for(int i = 0; i < builders.size(); i++)
|
||||
permissions.append(builders.get(i) + " ");
|
||||
permissions.append(this.trustEntryToPlayerName(builders.get(i)) + " ");
|
||||
}
|
||||
|
||||
player.sendMessage(permissions.toString());
|
||||
|
|
@ -1012,7 +1013,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(containers.size() > 0)
|
||||
{
|
||||
for(int i = 0; i < containers.size(); i++)
|
||||
permissions.append(containers.get(i) + " ");
|
||||
permissions.append(this.trustEntryToPlayerName(containers.get(i)) + " ");
|
||||
}
|
||||
|
||||
player.sendMessage(permissions.toString());
|
||||
|
|
@ -1022,7 +1023,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(accessors.size() > 0)
|
||||
{
|
||||
for(int i = 0; i < accessors.size(); i++)
|
||||
permissions.append(accessors.get(i) + " ");
|
||||
permissions.append(this.trustEntryToPlayerName(accessors.get(i)) + " ");
|
||||
}
|
||||
|
||||
player.sendMessage(permissions.toString());
|
||||
|
|
@ -1042,7 +1043,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
|
||||
|
||||
//bracket any permissions
|
||||
if(args[0].contains("."))
|
||||
if(args[0].contains(".") && !args[0].startsWith("[") && !args[0].endsWith("]"))
|
||||
{
|
||||
args[0] = "[" + args[0] + "]";
|
||||
}
|
||||
|
|
@ -1068,7 +1069,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//validate player argument or group argument
|
||||
if(!args[0].startsWith("[") || !args[0].endsWith("]"))
|
||||
{
|
||||
otherPlayer = this.resolvePlayer(args[0]);
|
||||
otherPlayer = this.resolvePlayerByName(args[0]);
|
||||
if(!clearPermissions && otherPlayer == null && !args[0].equals("public"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
|
|
@ -1084,7 +1085,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if no claim here, apply changes to all his claims
|
||||
if(claim == null)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
for(int i = 0; i < playerData.claims.size(); i++)
|
||||
{
|
||||
claim = playerData.claims.get(i);
|
||||
|
|
@ -1098,8 +1099,13 @@ public class GriefPrevention extends JavaPlugin
|
|||
//otherwise drop individual permissions
|
||||
else
|
||||
{
|
||||
claim.dropPermission(args[0]);
|
||||
claim.managers.remove(args[0]);
|
||||
String idToDrop = args[0];
|
||||
if(otherPlayer != null)
|
||||
{
|
||||
idToDrop = otherPlayer.getUniqueId().toString();
|
||||
}
|
||||
claim.dropPermission(idToDrop);
|
||||
claim.managers.remove(idToDrop);
|
||||
}
|
||||
|
||||
//save changes
|
||||
|
|
@ -1140,10 +1146,15 @@ public class GriefPrevention extends JavaPlugin
|
|||
//otherwise individual permission drop
|
||||
else
|
||||
{
|
||||
claim.dropPermission(args[0]);
|
||||
String idToDrop = args[0];
|
||||
if(otherPlayer != null)
|
||||
{
|
||||
idToDrop = otherPlayer.getUniqueId().toString();
|
||||
}
|
||||
claim.dropPermission(idToDrop);
|
||||
if(claim.allowEdit(player) == null)
|
||||
{
|
||||
claim.managers.remove(args[0]);
|
||||
claim.managers.remove(idToDrop);
|
||||
|
||||
//beautify for output
|
||||
if(args[0].equals("public"))
|
||||
|
|
@ -1225,14 +1236,14 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if no parameter, just tell player cost per block and balance
|
||||
if(args.length != 1)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BlockPurchaseCost, String.valueOf(GriefPrevention.instance.config_economy_claimBlocksPurchaseCost), String.valueOf(GriefPrevention.economy.getBalance(player.getName())));
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BlockPurchaseCost, String.valueOf(GriefPrevention.instance.config_economy_claimBlocksPurchaseCost), String.valueOf(GriefPrevention.economy.getBalance(player)));
|
||||
return false;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
//determine max purchasable blocks
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
int maxPurchasable = GriefPrevention.instance.config_claims_maxAccruedBlocks - playerData.accruedClaimBlocks;
|
||||
|
||||
//if the player is at his max, tell him so
|
||||
|
|
@ -1265,7 +1276,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//if the player can't afford his purchase, send error message
|
||||
double balance = economy.getBalance(player.getName());
|
||||
double balance = economy.getBalance(player);
|
||||
double totalCost = blockCount * GriefPrevention.instance.config_economy_claimBlocksPurchaseCost;
|
||||
if(totalCost > balance)
|
||||
{
|
||||
|
|
@ -1276,11 +1287,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
else
|
||||
{
|
||||
//withdraw cost
|
||||
economy.withdrawPlayer(player.getName(), totalCost);
|
||||
economy.withdrawPlayer(player, totalCost);
|
||||
|
||||
//add blocks
|
||||
playerData.accruedClaimBlocks += blockCount;
|
||||
this.dataStore.savePlayerData(player.getName(), playerData);
|
||||
this.dataStore.savePlayerData(player.getUniqueId(), playerData);
|
||||
|
||||
//inform player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.PurchaseConfirmation, String.valueOf(totalCost), String.valueOf(playerData.getRemainingClaimBlocks()));
|
||||
|
|
@ -1314,7 +1325,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//load player data
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
int availableBlocks = playerData.getRemainingClaimBlocks();
|
||||
|
||||
//if no amount provided, just tell player value per block sold, and how many he can sell
|
||||
|
|
@ -1351,11 +1362,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
{
|
||||
//compute value and deposit it
|
||||
double totalValue = blockCount * GriefPrevention.instance.config_economy_claimBlocksSellValue;
|
||||
economy.depositPlayer(player.getName(), totalValue);
|
||||
economy.depositPlayer(player, totalValue);
|
||||
|
||||
//subtract blocks
|
||||
playerData.accruedClaimBlocks -= blockCount;
|
||||
this.dataStore.savePlayerData(player.getName(), playerData);
|
||||
this.dataStore.savePlayerData(player.getUniqueId(), playerData);
|
||||
|
||||
//inform player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.BlockSaleConfirmation, String.valueOf(totalValue), String.valueOf(playerData.getRemainingClaimBlocks()));
|
||||
|
|
@ -1367,7 +1378,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//adminclaims
|
||||
else if(cmd.getName().equalsIgnoreCase("adminclaims") && player != null)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.shovelMode = ShovelMode.Admin;
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AdminClaimsMode);
|
||||
|
||||
|
|
@ -1377,7 +1388,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//basicclaims
|
||||
else if(cmd.getName().equalsIgnoreCase("basicclaims") && player != null)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.shovelMode = ShovelMode.Basic;
|
||||
playerData.claimSubdividing = null;
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.BasicClaimsMode);
|
||||
|
|
@ -1388,7 +1399,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//subdivideclaims
|
||||
else if(cmd.getName().equalsIgnoreCase("subdivideclaims") && player != null)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.shovelMode = ShovelMode.Subdivide;
|
||||
playerData.claimSubdividing = null;
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionMode);
|
||||
|
|
@ -1413,7 +1424,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//deleting an admin claim additionally requires the adminclaims permission
|
||||
if(!claim.isAdminClaim() || player.hasPermission("griefprevention.adminclaims"))
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
if(claim.children.size() > 0 && !playerData.warnedAboutMajorDeletion)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.DeletionSubdivisionWarning);
|
||||
|
|
@ -1489,7 +1500,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(args.length != 1) return false;
|
||||
|
||||
//try to find that player
|
||||
OfflinePlayer otherPlayer = this.resolvePlayer(args[0]);
|
||||
OfflinePlayer otherPlayer = this.resolvePlayerByName(args[0]);
|
||||
if(otherPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
|
|
@ -1497,7 +1508,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//delete all that player's claims
|
||||
this.dataStore.deleteClaimsForPlayer(otherPlayer.getName(), true);
|
||||
this.dataStore.deleteClaimsForPlayer(otherPlayer.getUniqueId(), true);
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.DeleteAllSuccess, otherPlayer.getName());
|
||||
if(player != null)
|
||||
|
|
@ -1539,7 +1550,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//otherwise try to find the specified player
|
||||
else
|
||||
{
|
||||
otherPlayer = this.resolvePlayer(args[0]);
|
||||
otherPlayer = this.resolvePlayerByName(args[0]);
|
||||
if(otherPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
|
|
@ -1548,8 +1559,8 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//load the target player's data
|
||||
PlayerData playerData = this.dataStore.getPlayerData(otherPlayer.getName());
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, " " + playerData.accruedClaimBlocks + "(+" + (playerData.bonusClaimBlocks + this.dataStore.getGroupBonusBlocks(otherPlayer.getName())) + ")=" + (playerData.accruedClaimBlocks + playerData.bonusClaimBlocks + this.dataStore.getGroupBonusBlocks(otherPlayer.getName())));
|
||||
PlayerData playerData = this.dataStore.getPlayerData(otherPlayer.getUniqueId());
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, " " + playerData.accruedClaimBlocks + "(+" + (playerData.bonusClaimBlocks + this.dataStore.getGroupBonusBlocks(otherPlayer.getUniqueId())) + ")=" + (playerData.accruedClaimBlocks + playerData.bonusClaimBlocks + this.dataStore.getGroupBonusBlocks(otherPlayer.getUniqueId())));
|
||||
for(int i = 0; i < playerData.claims.size(); i++)
|
||||
{
|
||||
Claim claim = playerData.claims.get(i);
|
||||
|
|
@ -1561,7 +1572,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
//drop the data we just loaded, if the player isn't online
|
||||
if(!otherPlayer.isOnline())
|
||||
this.dataStore.clearCachedPlayerData(otherPlayer.getName());
|
||||
this.dataStore.clearCachedPlayerData(otherPlayer.getUniqueId());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1636,7 +1647,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//delete all admin claims
|
||||
this.dataStore.deleteClaimsForPlayer("", true); //empty string for owner name indicates an administrative claim
|
||||
this.dataStore.deleteClaimsForPlayer(null, true); //null for owner id indicates an administrative claim
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AllAdminDeleted);
|
||||
if(player != null)
|
||||
|
|
@ -1680,7 +1691,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//otherwise, find the specified player
|
||||
OfflinePlayer targetPlayer = this.resolvePlayer(args[0]);
|
||||
OfflinePlayer targetPlayer = this.resolvePlayerByName(args[0]);
|
||||
if(targetPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
|
|
@ -1688,9 +1699,9 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//give blocks to player
|
||||
PlayerData playerData = this.dataStore.getPlayerData(targetPlayer.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(targetPlayer.getUniqueId());
|
||||
playerData.bonusClaimBlocks += adjustment;
|
||||
this.dataStore.savePlayerData(targetPlayer.getName(), playerData);
|
||||
this.dataStore.savePlayerData(targetPlayer.getUniqueId(), playerData);
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AdjustBlocksSuccess, targetPlayer.getName(), String.valueOf(adjustment), String.valueOf(playerData.bonusClaimBlocks));
|
||||
if(player != null) GriefPrevention.AddLogEntry(player.getName() + " adjusted " + targetPlayer.getName() + "'s bonus claim blocks by " + adjustment + ".");
|
||||
|
|
@ -1703,7 +1714,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
{
|
||||
//FEATURE: empower players who get "stuck" in an area where they don't have permission to build to save themselves
|
||||
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), false, playerData.lastClaim);
|
||||
|
||||
//if another /trapped is pending, ignore this slash command
|
||||
|
|
@ -1771,7 +1782,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
//can't start a siege when you're already involved in one
|
||||
Player attacker = player;
|
||||
PlayerData attackerData = this.dataStore.getPlayerData(attacker.getName());
|
||||
PlayerData attackerData = this.dataStore.getPlayerData(attacker.getUniqueId());
|
||||
if(attackerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadySieging);
|
||||
|
|
@ -1813,7 +1824,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//victim must not be under siege already
|
||||
PlayerData defenderData = this.dataStore.getPlayerData(defender.getName());
|
||||
PlayerData defenderData = this.dataStore.getPlayerData(defender.getUniqueId());
|
||||
if(defenderData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadyUnderSiegePlayer);
|
||||
|
|
@ -1875,14 +1886,26 @@ public class GriefPrevention extends JavaPlugin
|
|||
return false;
|
||||
}
|
||||
|
||||
public static String getfriendlyLocationString(Location location)
|
||||
private String trustEntryToPlayerName(String entry)
|
||||
{
|
||||
if(entry.startsWith("[") || entry.equals("public"))
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GriefPrevention.lookupPlayerName(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getfriendlyLocationString(Location location)
|
||||
{
|
||||
return location.getWorld().getName() + "(" + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ() + ")";
|
||||
}
|
||||
|
||||
private boolean abandonClaimHandler(Player player, boolean deleteTopLevelClaim)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//which claim is being abandoned?
|
||||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
|
||||
|
|
@ -1954,6 +1977,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//validate player or group argument
|
||||
String permission = null;
|
||||
OfflinePlayer otherPlayer = null;
|
||||
UUID recipientID = null;
|
||||
if(recipientName.startsWith("[") && recipientName.endsWith("]"))
|
||||
{
|
||||
permission = recipientName.substring(1, recipientName.length() - 1);
|
||||
|
|
@ -1971,7 +1995,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
else
|
||||
{
|
||||
otherPlayer = this.resolvePlayer(recipientName);
|
||||
otherPlayer = this.resolvePlayerByName(recipientName);
|
||||
if(otherPlayer == null && !recipientName.equals("public") && !recipientName.equals("all"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
|
|
@ -1981,6 +2005,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(otherPlayer != null)
|
||||
{
|
||||
recipientName = otherPlayer.getName();
|
||||
recipientID = otherPlayer.getUniqueId();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1992,7 +2017,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
ArrayList<Claim> targetClaims = new ArrayList<Claim>();
|
||||
if(claim == null)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
for(int i = 0; i < playerData.claims.size(); i++)
|
||||
{
|
||||
targetClaims.add(playerData.claims.get(i));
|
||||
|
|
@ -2057,16 +2082,26 @@ public class GriefPrevention extends JavaPlugin
|
|||
for(int i = 0; i < targetClaims.size(); i++)
|
||||
{
|
||||
Claim currentClaim = targetClaims.get(i);
|
||||
String identifierToAdd = recipientName;
|
||||
if(permission != null)
|
||||
{
|
||||
identifierToAdd = "[" + permission + "]";
|
||||
}
|
||||
else if(recipientID != null)
|
||||
{
|
||||
identifierToAdd = recipientID.toString();
|
||||
}
|
||||
|
||||
if(permissionLevel == null)
|
||||
{
|
||||
if(!currentClaim.managers.contains(recipientName))
|
||||
if(!currentClaim.managers.contains(identifierToAdd))
|
||||
{
|
||||
currentClaim.managers.add(recipientName);
|
||||
currentClaim.managers.add(identifierToAdd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentClaim.setPermission(recipientName, permissionLevel);
|
||||
currentClaim.setPermission(identifierToAdd, permissionLevel);
|
||||
}
|
||||
this.dataStore.saveClaim(currentClaim);
|
||||
}
|
||||
|
|
@ -2105,26 +2140,75 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//helper method to resolve a player by name
|
||||
private OfflinePlayer resolvePlayer(String name)
|
||||
private OfflinePlayer resolvePlayerByName(String name)
|
||||
{
|
||||
//try online players first
|
||||
Player player = this.getServer().getPlayer(name);
|
||||
if(player != null) return player;
|
||||
OfflinePlayer [] players = this.getServer().getOnlinePlayers();
|
||||
for(int i = 0; i < players.length; i++)
|
||||
{
|
||||
if(players[i].getName().equalsIgnoreCase(name))
|
||||
{
|
||||
return players[i];
|
||||
}
|
||||
}
|
||||
|
||||
//then search offline players
|
||||
OfflinePlayer [] offlinePlayers = this.getServer().getOfflinePlayers();
|
||||
for(int i = 0; i < offlinePlayers.length; i++)
|
||||
{
|
||||
if(offlinePlayers[i].getName().equalsIgnoreCase(name))
|
||||
{
|
||||
return offlinePlayers[i];
|
||||
}
|
||||
}
|
||||
players = this.getServer().getOfflinePlayers();
|
||||
for(int i = 0; i < players.length; i++)
|
||||
{
|
||||
if(players[i].getName().equalsIgnoreCase(name))
|
||||
{
|
||||
return players[i];
|
||||
}
|
||||
}
|
||||
|
||||
//if none found, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
//helper method to resolve a player name from the player's UUID
|
||||
static String lookupPlayerName(UUID playerID)
|
||||
{
|
||||
//parameter validation
|
||||
if(playerID == null) return "someone";
|
||||
|
||||
//try online players first
|
||||
Player player = GriefPrevention.instance.getServer().getPlayer(playerID);
|
||||
if(player != null) return player.getName();
|
||||
|
||||
//then search offline players
|
||||
OfflinePlayer [] players = GriefPrevention.instance.getServer().getOfflinePlayers();
|
||||
for(int i = 0; i < players.length; i++)
|
||||
{
|
||||
if(players[i].getUniqueId().equals(playerID))
|
||||
{
|
||||
return players[i].getName();
|
||||
}
|
||||
}
|
||||
|
||||
//if none found
|
||||
GriefPrevention.AddLogEntry("Error: Failed to find a local player with UUID: " + playerID.toString());
|
||||
new Exception().printStackTrace();
|
||||
return "someone";
|
||||
}
|
||||
|
||||
//string overload for above helper
|
||||
static String lookupPlayerName(String playerID)
|
||||
{
|
||||
UUID id;
|
||||
try
|
||||
{
|
||||
id = UUID.fromString(playerID);
|
||||
}
|
||||
catch(IllegalArgumentException ex)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Error: Tried to look up a local player name for invalid UUID: " + playerID);
|
||||
return "someone";
|
||||
}
|
||||
|
||||
return lookupPlayerName(id);
|
||||
}
|
||||
|
||||
public void onDisable()
|
||||
{
|
||||
//save data for any online players
|
||||
|
|
@ -2132,9 +2216,9 @@ public class GriefPrevention extends JavaPlugin
|
|||
for(int i = 0; i < players.length; i++)
|
||||
{
|
||||
Player player = players[i];
|
||||
String playerName = player.getName();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(playerName);
|
||||
this.dataStore.savePlayerData(playerName, playerData);
|
||||
UUID playerID = player.getUniqueId();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(playerID);
|
||||
this.dataStore.savePlayerData(playerID, playerData);
|
||||
}
|
||||
|
||||
this.dataStore.close();
|
||||
|
|
@ -2175,7 +2259,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//otherwise, apply immunity
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.pvpImmune = true;
|
||||
|
||||
//inform the player
|
||||
|
|
@ -2471,7 +2555,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
public String allowBuild(Player player, Location location)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim);
|
||||
|
||||
//exception: administrators in ignore claims mode and special player accounts created by server mods
|
||||
|
|
@ -2513,7 +2597,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
public String allowBreak(Player player, Location location)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim);
|
||||
|
||||
//exception: administrators in ignore claims mode, and special player accounts created by server mods
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package me.ryanhamshire.GriefPrevention;
|
|||
import java.net.InetAddress;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
|
||||
import me.ryanhamshire.GriefPrevention.Claim;
|
||||
|
|
@ -33,8 +34,8 @@ import org.bukkit.Location;
|
|||
//holds all of GriefPrevention's player-tied data
|
||||
public class PlayerData
|
||||
{
|
||||
//the player's name
|
||||
public String playerName;
|
||||
//the player's ID
|
||||
public UUID playerID;
|
||||
|
||||
//the player's claims
|
||||
public Vector<Claim> claims = new Vector<Claim>();
|
||||
|
|
@ -151,7 +152,7 @@ public class PlayerData
|
|||
}
|
||||
|
||||
//add any blocks this player might have based on group membership (permissions)
|
||||
remainingBlocks += GriefPrevention.instance.dataStore.getGroupBonusBlocks(this.playerName);
|
||||
remainingBlocks += GriefPrevention.instance.dataStore.getGroupBonusBlocks(this.playerID);
|
||||
|
||||
return remainingBlocks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.Calendar;
|
|||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
|
@ -40,7 +41,6 @@ import org.bukkit.entity.Entity;
|
|||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.entity.minecart.HopperMinecart;
|
||||
import org.bukkit.entity.minecart.PoweredMinecart;
|
||||
import org.bukkit.entity.minecart.StorageMinecart;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
|
@ -131,7 +131,7 @@ class PlayerEventHandler implements Listener
|
|||
boolean spam = false;
|
||||
boolean muted = false;
|
||||
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//remedy any CAPS SPAM, exception for very short messages which could be emoticons like =D or XD
|
||||
if(message.length() > 4 && this.stringsAreSimilar(message.toUpperCase(), message))
|
||||
|
|
@ -367,7 +367,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//if in pvp, block any pvp-banned slash commands
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getUniqueId());
|
||||
if((playerData.inPvpCombat() || playerData.siegeData != null) && GriefPrevention.instance.config_pvp_blockedCommands.contains(command))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
|
|
@ -410,7 +410,7 @@ class PlayerEventHandler implements Listener
|
|||
if(GriefPrevention.instance.config_spam_loginCooldownMinutes > 0 && event.getResult() == Result.ALLOWED)
|
||||
{
|
||||
//determine how long since last login and cooldown remaining
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
long millisecondsSinceLastLogin = (new Date()).getTime() - playerData.lastLogin.getTime();
|
||||
long minutesSinceLastLogin = millisecondsSinceLastLogin / 1000 / 60;
|
||||
long cooldownRemaining = GriefPrevention.instance.config_spam_loginCooldownMinutes - minutesSinceLastLogin;
|
||||
|
|
@ -435,7 +435,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//remember the player's ip address
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.ipAddress = event.getAddress();
|
||||
}
|
||||
|
||||
|
|
@ -443,7 +443,7 @@ class PlayerEventHandler implements Listener
|
|||
@EventHandler(ignoreCancelled = true)
|
||||
void onPlayerRespawn (PlayerRespawnEvent event)
|
||||
{
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(event.getPlayer().getUniqueId());
|
||||
playerData.lastSpawn = Calendar.getInstance().getTimeInMillis();
|
||||
GriefPrevention.instance.checkPvpProtectionNeeded(event.getPlayer());
|
||||
}
|
||||
|
|
@ -453,14 +453,14 @@ class PlayerEventHandler implements Listener
|
|||
void onPlayerJoin(PlayerJoinEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
String playerName = player.getName();
|
||||
UUID playerID = player.getUniqueId();
|
||||
|
||||
//note login time
|
||||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(playerName);
|
||||
PlayerData playerData = this.dataStore.getPlayerData(playerID);
|
||||
playerData.lastSpawn = now;
|
||||
playerData.lastLogin = new Date();
|
||||
this.dataStore.savePlayerData(playerName, playerData);
|
||||
this.dataStore.savePlayerData(playerID, playerData);
|
||||
|
||||
//if player has never played on the server before, may need pvp protection
|
||||
if(!player.hasPlayedBefore())
|
||||
|
|
@ -544,7 +544,7 @@ class PlayerEventHandler implements Listener
|
|||
void onPlayerDeath(PlayerDeathEvent event)
|
||||
{
|
||||
//FEATURE: prevent death message spam by implementing a "cooldown period" for death messages
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getEntity().getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getEntity().getUniqueId());
|
||||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
if(now - playerData.lastDeathTimeStamp < GriefPrevention.instance.config_spam_deathMessageCooldownSeconds * 1000)
|
||||
{
|
||||
|
|
@ -559,7 +559,7 @@ class PlayerEventHandler implements Listener
|
|||
void onPlayerQuit(PlayerQuitEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//if banned, add IP to the temporary IP ban list
|
||||
if(player.isBanned() && playerData.ipAddress != null)
|
||||
|
|
@ -575,7 +575,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.getUniqueId(), playerData);
|
||||
|
||||
this.onPlayerDisconnect(event.getPlayer(), event.getQuitMessage());
|
||||
}
|
||||
|
|
@ -583,8 +583,8 @@ class PlayerEventHandler implements Listener
|
|||
//helper for above
|
||||
private void onPlayerDisconnect(Player player, String notificationMessage)
|
||||
{
|
||||
String playerName = player.getName();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(playerName);
|
||||
UUID playerID = player.getUniqueId();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(playerID);
|
||||
|
||||
//FEATURE: claims where players have allowed explosions will revert back to not allowing them when the owner logs out
|
||||
for(Claim claim : playerData.claims)
|
||||
|
|
@ -607,7 +607,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//drop data about this player
|
||||
this.dataStore.clearCachedPlayerData(player.getName());
|
||||
this.dataStore.clearCachedPlayerData(playerID);
|
||||
}
|
||||
|
||||
//determines whether or not a login or logout notification should be silenced, depending on how many there have been in the last minute
|
||||
|
|
@ -650,7 +650,7 @@ class PlayerEventHandler implements Listener
|
|||
return;
|
||||
}
|
||||
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//FEATURE: players under siege or in PvP combat, can't throw items on the ground to hide
|
||||
//them or give them away to other players before they are defeated
|
||||
|
|
@ -675,7 +675,7 @@ class PlayerEventHandler implements Listener
|
|||
public void onPlayerTeleport(PlayerTeleportEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//FEATURE: prevent players from using ender pearls to gain access to secured claims
|
||||
if(event.getCause() == TeleportCause.ENDER_PEARL && GriefPrevention.instance.config_claims_enderPearlsRequireAccessTrust)
|
||||
|
|
@ -723,7 +723,7 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
Player player = event.getPlayer();
|
||||
Entity entity = event.getRightClicked();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//don't allow interaction with item frames in claimed areas without build permission
|
||||
if(entity instanceof Hanging)
|
||||
|
|
@ -825,7 +825,7 @@ class PlayerEventHandler implements Listener
|
|||
if(GriefPrevention.instance.config_pvp_protectFreshSpawns && (player.getItemInHand().getType() == Material.AIR))
|
||||
{
|
||||
//if that player is currently immune to pvp
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getUniqueId());
|
||||
if(playerData.pvpImmune)
|
||||
{
|
||||
//if it's been less than 10 seconds since the last time he spawned, don't pick up the item
|
||||
|
|
@ -854,7 +854,7 @@ 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());
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//always reset to basic claims mode
|
||||
if(playerData.shovelMode != ShovelMode.Basic)
|
||||
|
|
@ -916,7 +916,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//if the bucket is being used in a claim, allow for dumping lava closer to other players
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
Claim claim = this.dataStore.getClaimAt(block.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
|
|
@ -1011,7 +1011,7 @@ class PlayerEventHandler implements Listener
|
|||
Material clickedBlockType = clickedBlock.getType();
|
||||
|
||||
//apply rules for putting out fires (requires build permission)
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
if(event.getClickedBlock() != null && event.getClickedBlock().getRelative(event.getBlockFace()).getType() == Material.FIRE)
|
||||
{
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
|
|
@ -1248,7 +1248,7 @@ class PlayerEventHandler implements Listener
|
|||
//if deleteclaims permission, tell about the player's offline time
|
||||
if(!claim.isAdminClaim() && player.hasPermission("griefprevention.deleteclaims"))
|
||||
{
|
||||
PlayerData otherPlayerData = this.dataStore.getPlayerData(claim.getOwnerName());
|
||||
PlayerData otherPlayerData = this.dataStore.getPlayerData(claim.ownerID);
|
||||
Date lastLogin = otherPlayerData.lastLogin;
|
||||
Date now = new Date();
|
||||
long daysElapsed = (now.getTime() - lastLogin.getTime()) / (1000 * 60 * 60 * 24);
|
||||
|
|
@ -1256,8 +1256,8 @@ class PlayerEventHandler implements Listener
|
|||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.PlayerOfflineTime, String.valueOf(daysElapsed));
|
||||
|
||||
//drop the data we just loaded, if the player isn't online
|
||||
if(GriefPrevention.instance.getServer().getPlayerExact(claim.getOwnerName()) == null)
|
||||
this.dataStore.clearCachedPlayerData(claim.getOwnerName());
|
||||
if(GriefPrevention.instance.getServer().getPlayer(claim.ownerID) == null)
|
||||
this.dataStore.clearCachedPlayerData(claim.ownerID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1283,8 +1283,8 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//if the player is in restore nature mode, do only that
|
||||
String playerName = player.getName();
|
||||
playerData = this.dataStore.getPlayerData(player.getName());
|
||||
UUID playerID = player.getUniqueId();
|
||||
playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||
if(playerData.shovelMode == ShovelMode.RestoreNature || playerData.shovelMode == ShovelMode.RestoreNatureAggressive)
|
||||
{
|
||||
//if the clicked block is in a claim, visualize that claim and deliver an error message
|
||||
|
|
@ -1538,7 +1538,7 @@ class PlayerEventHandler implements Listener
|
|||
Claim newClaim = new Claim(
|
||||
new Location(oldClaim.getLesserBoundaryCorner().getWorld(), newx1, newy1, newz1),
|
||||
new Location(oldClaim.getLesserBoundaryCorner().getWorld(), newx2, newy2, newz2),
|
||||
"", new String[]{}, new String[]{}, new String[]{}, new String[]{}, null);
|
||||
null, new String[]{}, new String[]{}, new String[]{}, new String[]{}, null);
|
||||
|
||||
//if the new claim is smaller
|
||||
if(!newClaim.contains(oldClaim.getLesserBoundaryCorner(), true, false) || !newClaim.contains(oldClaim.getGreaterBoundaryCorner(), true, false))
|
||||
|
|
@ -1568,9 +1568,9 @@ class PlayerEventHandler implements Listener
|
|||
Visualization.Apply(player, visualization);
|
||||
|
||||
//if resizing someone else's claim, make a log entry
|
||||
if(!playerData.claimResizing.ownerName.equals(playerName))
|
||||
if(!playerID.equals(playerData.claimResizing.ownerID))
|
||||
{
|
||||
GriefPrevention.AddLogEntry(playerName + " resized " + playerData.claimResizing.getOwnerName() + "'s claim at " + GriefPrevention.getfriendlyLocationString(playerData.claimResizing.lesserBoundaryCorner) + ".");
|
||||
GriefPrevention.AddLogEntry(player.getName() + " resized " + playerData.claimResizing.getOwnerName() + "'s claim at " + GriefPrevention.getfriendlyLocationString(playerData.claimResizing.lesserBoundaryCorner) + ".");
|
||||
}
|
||||
|
||||
//if in a creative mode world and shrinking an existing claim, restore any unclaimed area
|
||||
|
|
@ -1654,7 +1654,7 @@ class PlayerEventHandler implements Listener
|
|||
playerData.lastShovelLocation.getBlockX(), clickedBlock.getX(),
|
||||
playerData.lastShovelLocation.getBlockY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance, clickedBlock.getY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance,
|
||||
playerData.lastShovelLocation.getBlockZ(), clickedBlock.getZ(),
|
||||
"--subdivision--", //owner name is not used for subdivisions
|
||||
null, //owner is not used for subdivisions
|
||||
playerData.claimSubdividing,
|
||||
null);
|
||||
|
||||
|
|
@ -1720,7 +1720,7 @@ class PlayerEventHandler implements Listener
|
|||
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 visualization = Visualization.FromClaim(new Claim(clickedBlock.getLocation(), clickedBlock.getLocation(), null, new String[]{}, new String[]{}, new String[]{}, new String[]{}, null), clickedBlock.getY(), VisualizationType.RestoreNature, player.getLocation());
|
||||
Visualization.Apply(player, visualization);
|
||||
}
|
||||
|
||||
|
|
@ -1759,7 +1759,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
else
|
||||
{
|
||||
playerName = "";
|
||||
playerID = null;
|
||||
}
|
||||
|
||||
//try to create a new claim (will return null if this claim overlaps another)
|
||||
|
|
@ -1768,7 +1768,7 @@ class PlayerEventHandler implements Listener
|
|||
lastShovelLocation.getBlockX(), clickedBlock.getX(),
|
||||
lastShovelLocation.getBlockY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance, clickedBlock.getY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance,
|
||||
lastShovelLocation.getBlockZ(), clickedBlock.getZ(),
|
||||
playerName,
|
||||
playerID,
|
||||
null, null);
|
||||
|
||||
//if it didn't succeed, tell the player why
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class PlayerKickBanTask implements Runnable
|
|||
if(this.banReason != null)
|
||||
{
|
||||
//ban
|
||||
GriefPrevention.instance.getServer().getOfflinePlayer(this.player.getName()).setBanned(true);
|
||||
GriefPrevention.instance.getServer().getOfflinePlayer(this.player.getUniqueId()).setBanned(true);
|
||||
|
||||
//kick
|
||||
if(this.player.isOnline())
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class PlayerRescueTask implements Runnable
|
|||
if(!player.isOnline()) return;
|
||||
|
||||
//he no longer has a pending /trapped slash command, so he can try to use it again now
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
|
||||
playerData.pendingTrapped = false;
|
||||
|
||||
//if the player moved three or more blocks from where he used /trapped, admonish him and don't save him
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class RestoreNatureExecutionTask implements Runnable
|
|||
//show visualization to player who started the restoration
|
||||
if(player != null)
|
||||
{
|
||||
Claim claim = new Claim(lesserCorner, greaterCorner, "", new String[] {}, new String[] {}, new String[] {}, new String[] {}, null);
|
||||
Claim claim = new Claim(lesserCorner, greaterCorner, null, new String[] {}, new String[] {}, new String[] {}, new String[] {}, null);
|
||||
Visualization visualization = Visualization.FromClaim(claim, player.getLocation().getBlockY(), VisualizationType.RestoreNature, player.getLocation());
|
||||
Visualization.Apply(player, visualization);
|
||||
}
|
||||
|
|
|
|||
145
src/me/ryanhamshire/GriefPrevention/UUIDFetcher.java
Normal file
145
src/me/ryanhamshire/GriefPrevention/UUIDFetcher.java
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
//BIG THANKS to EvilMidget38 for providing this handy UUID lookup tool to the Bukkit community! :)
|
||||
|
||||
package me.ryanhamshire.GriefPrevention;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
class UUIDFetcher implements Callable<Map<String, UUID>> {
|
||||
private static final double PROFILES_PER_REQUEST = 100;
|
||||
private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
|
||||
private final JSONParser jsonParser = new JSONParser();
|
||||
private final List<String> names;
|
||||
private final boolean rateLimiting;
|
||||
|
||||
//cache for username -> uuid lookups
|
||||
private static HashMap<String, UUID> lookupCache;
|
||||
|
||||
public UUIDFetcher(List<String> names, boolean rateLimiting) {
|
||||
this.names = ImmutableList.copyOf(names);
|
||||
this.rateLimiting = rateLimiting;
|
||||
}
|
||||
|
||||
public UUIDFetcher(List<String> names) {
|
||||
this(names, true);
|
||||
}
|
||||
|
||||
public Map<String, UUID> call() throws Exception {
|
||||
Map<String, UUID> uuidMap = new HashMap<String, UUID>();
|
||||
int requests = (int) Math.ceil(names.size() / PROFILES_PER_REQUEST);
|
||||
for (int i = 0; i < requests; i++) {
|
||||
HttpURLConnection connection = createConnection();
|
||||
String body = JSONArray.toJSONString(names.subList(i * 100, Math.min((i + 1) * 100, names.size())));
|
||||
writeBody(connection, body);
|
||||
JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream()));
|
||||
for (Object profile : array) {
|
||||
JSONObject jsonProfile = (JSONObject) profile;
|
||||
String id = (String) jsonProfile.get("id");
|
||||
String name = (String) jsonProfile.get("name");
|
||||
UUID uuid = UUIDFetcher.getUUID(id);
|
||||
uuidMap.put(name, uuid);
|
||||
}
|
||||
if (rateLimiting && i != requests - 1) {
|
||||
Thread.sleep(100L);
|
||||
}
|
||||
}
|
||||
return uuidMap;
|
||||
}
|
||||
|
||||
private static void writeBody(HttpURLConnection connection, String body) throws Exception {
|
||||
OutputStream stream = connection.getOutputStream();
|
||||
stream.write(body.getBytes());
|
||||
stream.flush();
|
||||
stream.close();
|
||||
}
|
||||
|
||||
private static HttpURLConnection createConnection() throws Exception {
|
||||
URL url = new URL(PROFILE_URL);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setUseCaches(false);
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
return connection;
|
||||
}
|
||||
|
||||
private static UUID getUUID(String id) {
|
||||
return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" +id.substring(20, 32));
|
||||
}
|
||||
|
||||
public static byte[] toBytes(UUID uuid) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
|
||||
byteBuffer.putLong(uuid.getMostSignificantBits());
|
||||
byteBuffer.putLong(uuid.getLeastSignificantBits());
|
||||
return byteBuffer.array();
|
||||
}
|
||||
|
||||
public static UUID fromBytes(byte[] array) {
|
||||
if (array.length != 16) {
|
||||
throw new IllegalArgumentException("Illegal byte array length: " + array.length);
|
||||
}
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(array);
|
||||
long mostSignificant = byteBuffer.getLong();
|
||||
long leastSignificant = byteBuffer.getLong();
|
||||
return new UUID(mostSignificant, leastSignificant);
|
||||
}
|
||||
|
||||
public static UUID getUUIDOf(String name) throws Exception
|
||||
{
|
||||
if(lookupCache == null)
|
||||
{
|
||||
lookupCache = new HashMap<String, UUID>();
|
||||
}
|
||||
|
||||
UUID result = lookupCache.get(name);
|
||||
if(result == null)
|
||||
{
|
||||
if(lookupCache.containsKey(name)) return null;
|
||||
|
||||
String correctCasingName = getNameWithCasing(name);
|
||||
|
||||
result = new UUIDFetcher(Arrays.asList(name)).call().get(correctCasingName);
|
||||
if(result == null)
|
||||
{
|
||||
GriefPrevention.AddLogEntry(correctCasingName + " --> ???");
|
||||
lookupCache.put(name, null);
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
GriefPrevention.AddLogEntry(correctCasingName + " --> " + result.toString());
|
||||
lookupCache.put(name, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String getNameWithCasing(String name)
|
||||
{
|
||||
OfflinePlayer [] players = GriefPrevention.instance.getServer().getOfflinePlayers();
|
||||
for(OfflinePlayer player : players)
|
||||
{
|
||||
if(player.getName().equalsIgnoreCase(name))
|
||||
{
|
||||
if(!player.getName().equals(name))
|
||||
{
|
||||
GriefPrevention.AddLogEntry(name + " --> " + player.getName());
|
||||
}
|
||||
return player.getName();
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ public class Visualization
|
|||
//sends a visualization to a player
|
||||
public static void Apply(Player player, Visualization visualization)
|
||||
{
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
//if he has any current visualization, clear it first
|
||||
if(playerData.currentVisualization != null)
|
||||
|
|
@ -55,7 +55,7 @@ public class Visualization
|
|||
//reverts a visualization by sending another block change list, this time with the real world block values
|
||||
public static void Revert(Player player)
|
||||
{
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
|
||||
|
||||
Visualization visualization = playerData.currentVisualization;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user