Made player data saving/loading more reliable.
Refactoring and retry loops are both EVIL, but I'm out of better ideas now regarding the "player data randomly resets" bug.
This commit is contained in:
parent
eb23d788bf
commit
febd8f0525
|
|
@ -19,6 +19,8 @@
|
||||||
package me.ryanhamshire.GriefPrevention;
|
package me.ryanhamshire.GriefPrevention;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.lang.management.ThreadInfo;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|
@ -26,6 +28,8 @@ import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
//manages data stored in the file system
|
//manages data stored in the file system
|
||||||
public class FlatFileDataStore extends DataStore
|
public class FlatFileDataStore extends DataStore
|
||||||
{
|
{
|
||||||
|
|
@ -466,57 +470,73 @@ public class FlatFileDataStore extends DataStore
|
||||||
//if it exists as a file, read the file
|
//if it exists as a file, read the file
|
||||||
if(playerFile.exists())
|
if(playerFile.exists())
|
||||||
{
|
{
|
||||||
BufferedReader inStream = null;
|
boolean needRetry = false;
|
||||||
try
|
int retriesRemaining = 5;
|
||||||
{
|
Exception latestException = null;
|
||||||
inStream = new BufferedReader(new FileReader(playerFile.getAbsolutePath()));
|
do
|
||||||
|
{
|
||||||
//first line is last login timestamp
|
try
|
||||||
String lastLoginTimestampString = inStream.readLine();
|
{
|
||||||
|
needRetry = false;
|
||||||
//convert that to a date and store it
|
|
||||||
DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
|
//read the file content and immediately close it
|
||||||
try
|
List<String> lines = Files.readLines(playerFile, Charset.forName("UTF-8"));
|
||||||
{
|
Iterator<String> iterator = lines.iterator();
|
||||||
playerData.setLastLogin(dateFormat.parse(lastLoginTimestampString));
|
|
||||||
}
|
//first line is last login timestamp
|
||||||
catch(ParseException parseException)
|
String lastLoginTimestampString = iterator.next();
|
||||||
{
|
|
||||||
GriefPrevention.AddLogEntry("Unable to load last login for \"" + playerFile.getName() + "\".");
|
//convert that to a date and store it
|
||||||
playerData.setLastLogin(null);
|
DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
|
||||||
}
|
try
|
||||||
|
{
|
||||||
//second line is accrued claim blocks
|
playerData.setLastLogin(dateFormat.parse(lastLoginTimestampString));
|
||||||
String accruedBlocksString = inStream.readLine();
|
}
|
||||||
|
catch(ParseException parseException)
|
||||||
//convert that to a number and store it
|
{
|
||||||
playerData.setAccruedClaimBlocks(Integer.parseInt(accruedBlocksString));
|
GriefPrevention.AddLogEntry("Unable to load last login for \"" + playerFile.getName() + "\".");
|
||||||
|
playerData.setLastLogin(null);
|
||||||
//third line is any bonus claim blocks granted by administrators
|
}
|
||||||
String bonusBlocksString = inStream.readLine();
|
|
||||||
|
//second line is accrued claim blocks
|
||||||
//convert that to a number and store it
|
String accruedBlocksString = iterator.next();
|
||||||
playerData.setBonusClaimBlocks(Integer.parseInt(bonusBlocksString));
|
|
||||||
|
//convert that to a number and store it
|
||||||
//fourth line is a double-semicolon-delimited list of claims, which is currently ignored
|
playerData.setAccruedClaimBlocks(Integer.parseInt(accruedBlocksString));
|
||||||
//String claimsString = inStream.readLine();
|
|
||||||
inStream.readLine();
|
//third line is any bonus claim blocks granted by administrators
|
||||||
|
String bonusBlocksString = iterator.next();
|
||||||
inStream.close();
|
|
||||||
}
|
//convert that to a number and store it
|
||||||
|
playerData.setBonusClaimBlocks(Integer.parseInt(bonusBlocksString));
|
||||||
//if there's any problem with the file's content, log an error message
|
|
||||||
catch(Exception e)
|
//fourth line is a double-semicolon-delimited list of claims, which is currently ignored
|
||||||
{
|
//String claimsString = inStream.readLine();
|
||||||
GriefPrevention.AddLogEntry("Unable to load data for player \"" + playerID.toString() + "\": " + e.toString());
|
//iterator.next();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
|
||||||
|
//if there's any problem with the file's content, retry up to 5 times with 5 milliseconds between
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
latestException = e;
|
||||||
|
needRetry = true;
|
||||||
|
retriesRemaining--;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(needRetry) Thread.sleep(5);
|
||||||
|
}
|
||||||
|
catch(InterruptedException exception) {}
|
||||||
|
|
||||||
|
}while(needRetry && retriesRemaining >= 0);
|
||||||
|
|
||||||
try
|
//if last attempt failed, log information about the problem
|
||||||
|
if(needRetry)
|
||||||
{
|
{
|
||||||
if(inStream != null) inStream.close();
|
GriefPrevention.AddLogEntry("Retry attempts exhausted. Unable to load data for player \"" + playerID.toString() + "\": " + latestException.toString());
|
||||||
|
latestException.printStackTrace();
|
||||||
}
|
}
|
||||||
catch(IOException exception) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return playerData;
|
return playerData;
|
||||||
|
|
@ -529,38 +549,37 @@ public class FlatFileDataStore extends DataStore
|
||||||
//never save data for the "administrative" account. null for claim owner ID indicates administrative account
|
//never save data for the "administrative" account. null for claim owner ID indicates administrative account
|
||||||
if(playerID == null) return;
|
if(playerID == null) return;
|
||||||
|
|
||||||
BufferedWriter outStream = null;
|
StringBuilder fileContent = new StringBuilder();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//open the player's file
|
|
||||||
File playerDataFile = new File(playerDataFolderPath + File.separator + playerID.toString());
|
|
||||||
playerDataFile.createNewFile();
|
|
||||||
outStream = new BufferedWriter(new FileWriter(playerDataFile));
|
|
||||||
|
|
||||||
//first line is last login timestamp
|
//first line is last login timestamp
|
||||||
if(playerData.getLastLogin() == null) playerData.setLastLogin(new Date());
|
if(playerData.getLastLogin() == null) playerData.setLastLogin(new Date());
|
||||||
DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
|
DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
|
||||||
outStream.write(dateFormat.format(playerData.getLastLogin()));
|
fileContent.append(dateFormat.format(playerData.getLastLogin()));
|
||||||
outStream.newLine();
|
fileContent.append("\n");
|
||||||
|
|
||||||
//second line is accrued claim blocks
|
//second line is accrued claim blocks
|
||||||
outStream.write(String.valueOf(playerData.getAccruedClaimBlocks()));
|
fileContent.append(String.valueOf(playerData.getAccruedClaimBlocks()));
|
||||||
outStream.newLine();
|
fileContent.append("\n");
|
||||||
|
|
||||||
//third line is bonus claim blocks
|
//third line is bonus claim blocks
|
||||||
outStream.write(String.valueOf(playerData.getBonusClaimBlocks()));
|
fileContent.append(String.valueOf(playerData.getBonusClaimBlocks()));
|
||||||
outStream.newLine();
|
fileContent.append("\n");
|
||||||
|
|
||||||
//fourth line is a double-semicolon-delimited list of claims
|
//fourth line is a double-semicolon-delimited list of claims
|
||||||
if(playerData.getClaims().size() > 0)
|
if(playerData.getClaims().size() > 0)
|
||||||
{
|
{
|
||||||
outStream.write(this.locationToString(playerData.getClaims().get(0).getLesserBoundaryCorner()));
|
fileContent.append(this.locationToString(playerData.getClaims().get(0).getLesserBoundaryCorner()));
|
||||||
for(int i = 1; i < playerData.getClaims().size(); i++)
|
for(int i = 1; i < playerData.getClaims().size(); i++)
|
||||||
{
|
{
|
||||||
outStream.write(";;" + this.locationToString(playerData.getClaims().get(i).getLesserBoundaryCorner()));
|
fileContent.append(";;" + this.locationToString(playerData.getClaims().get(i).getLesserBoundaryCorner()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outStream.newLine();
|
fileContent.append("\n");
|
||||||
|
|
||||||
|
//write data to file
|
||||||
|
File playerDataFile = new File(playerDataFolderPath + File.separator + playerID.toString());
|
||||||
|
Files.write(fileContent.toString().getBytes("UTF-8"), playerDataFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if any problem, log it
|
//if any problem, log it
|
||||||
|
|
@ -568,16 +587,6 @@ public class FlatFileDataStore extends DataStore
|
||||||
{
|
{
|
||||||
GriefPrevention.AddLogEntry("GriefPrevention: Unexpected exception saving data for player \"" + playerID.toString() + "\": " + e.getMessage());
|
GriefPrevention.AddLogEntry("GriefPrevention: Unexpected exception saving data for player \"" + playerID.toString() + "\": " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//close the file
|
|
||||||
if(outStream != null)
|
|
||||||
{
|
|
||||||
outStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(IOException exception){}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user