mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-02-23 15:38:29 +01:00
@@ -70,6 +70,6 @@ public final class WorldContext {
|
|||||||
ChecksumBuilder checksumBuilder = new ChecksumBuilder();
|
ChecksumBuilder checksumBuilder = new ChecksumBuilder();
|
||||||
model.addToChecksum(checksumBuilder);
|
model.addToChecksum(checksumBuilder);
|
||||||
maps.addToChecksum(checksumBuilder, this);
|
maps.addToChecksum(checksumBuilder, this);
|
||||||
return checksumBuilder.build();
|
return checksumBuilder.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,103 +13,103 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
|
|
||||||
public class ChecksumBuilder {
|
public class ChecksumBuilder {
|
||||||
|
|
||||||
public static final int CHECKSUM_LENGTH = 32;// 256 bits (depends on the hash algorithm)
|
public static final int CHECKSUM_LENGTH = 32;// 256 bits (depends on the hash algorithm)
|
||||||
public static final String CHECKSUM_ALGORITHM = "SHA-256"; //Should be available in all Android versions
|
public static final String CHECKSUM_ALGORITHM = "SHA-256"; //Should be available in all Android versions
|
||||||
private ByteBuffer buffer;
|
private ByteBuffer buffer;
|
||||||
private final MessageDigest digest;
|
private final MessageDigest digest;
|
||||||
|
|
||||||
private ChecksumBuilder(int initialCapacity, ByteOrder byteOrder) {
|
private ChecksumBuilder(int initialCapacity, ByteOrder byteOrder) {
|
||||||
buffer = ByteBuffer.allocate(initialCapacity);
|
buffer = ByteBuffer.allocate(initialCapacity);
|
||||||
buffer.order(byteOrder);
|
buffer.order(byteOrder);
|
||||||
try {
|
try {
|
||||||
digest = MessageDigest.getInstance(CHECKSUM_ALGORITHM); // Or SHA-512 for even stronger hash
|
digest = MessageDigest.getInstance(CHECKSUM_ALGORITHM); // Or SHA-512 for even stronger hash
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
throw new RuntimeException("Hash algorithm not found", e);
|
throw new RuntimeException("Hash algorithm not found", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChecksumBuilder(int initialCapacity) {
|
private ChecksumBuilder(int initialCapacity) {
|
||||||
this(initialCapacity, ByteOrder.BIG_ENDIAN); // Default to big-endian
|
this(initialCapacity, ByteOrder.BIG_ENDIAN); // Default to big-endian
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChecksumBuilder() {
|
public ChecksumBuilder() {
|
||||||
this(1024*10); // A reasonable default initial capacity
|
this(1024*10); // A reasonable default initial capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Methods for adding different data types ---
|
// --- Methods for adding different data types ---
|
||||||
|
|
||||||
public ChecksumBuilder add(String value) {
|
public ChecksumBuilder add(String value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
bytes = value.getBytes(StandardCharsets.UTF_8);
|
bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||||
} else {
|
} else {
|
||||||
bytes = value.getBytes();
|
bytes = value.getBytes();
|
||||||
}
|
}
|
||||||
add(bytes);
|
add(bytes);
|
||||||
} else {
|
} else {
|
||||||
add(-1); // Use -1 to represent a null string
|
add(-1); // Use -1 to represent a null string
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChecksumBuilder add(byte[] bytes) {
|
public ChecksumBuilder add(byte[] bytes) {
|
||||||
add(bytes.length); // Add length prefix
|
add(bytes.length); // Add length prefix
|
||||||
ensureCapacity(bytes.length + 4); // +4 for length prefix (int)
|
ensureCapacity(bytes.length + 4); // +4 for length prefix (int)
|
||||||
buffer.put(bytes);
|
buffer.put(bytes);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChecksumBuilder add(boolean value) {
|
public ChecksumBuilder add(boolean value) {
|
||||||
ensureCapacity(1);
|
ensureCapacity(1);
|
||||||
buffer.put(value ? (byte) 1 : (byte) 0);
|
buffer.put(value ? (byte) 1 : (byte) 0);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChecksumBuilder add(long value) {
|
public ChecksumBuilder add(long value) {
|
||||||
ensureCapacity(8);
|
ensureCapacity(8);
|
||||||
buffer.putLong(value);
|
buffer.putLong(value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChecksumBuilder add(int value) {
|
public ChecksumBuilder add(int value) {
|
||||||
ensureCapacity(4);
|
ensureCapacity(4);
|
||||||
buffer.putInt(value);
|
buffer.putInt(value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChecksumBuilder add(float value) {
|
public ChecksumBuilder add(float value) {
|
||||||
ensureCapacity(8);
|
ensureCapacity(8);
|
||||||
buffer.putFloat(value);
|
buffer.putFloat(value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChecksumBuilder add(double value) {
|
public ChecksumBuilder add(double value) {
|
||||||
ensureCapacity(4);
|
ensureCapacity(4);
|
||||||
buffer.putDouble(value);
|
buffer.putDouble(value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Method to finalize and get the checksum ---
|
// --- Method to finalize and get the checksum ---
|
||||||
|
|
||||||
public byte[] build() throws DigestException {
|
public byte[] build() throws DigestException {
|
||||||
buffer.flip(); // Prepare for reading
|
buffer.flip(); // Prepare for reading
|
||||||
digest.update(buffer);// Only use the actually used part of the buffer
|
digest.update(buffer);// Only use the actually used part of the buffer
|
||||||
buffer.flip(); // Prepare for further writing
|
buffer.flip(); // Prepare for further writing
|
||||||
return digest.digest();
|
return digest.digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- Utility method to ensure sufficient capacity ---
|
// --- Utility method to ensure sufficient capacity ---
|
||||||
private void ensureCapacity(int required) {
|
private void ensureCapacity(int required) {
|
||||||
if (buffer.remaining() < required) {
|
if (buffer.remaining() < required) {
|
||||||
int newCapacity = Math.max(buffer.capacity() * 2, buffer.capacity() + required);
|
int newCapacity = Math.max(buffer.capacity() * 2, buffer.capacity() + required);
|
||||||
ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity);
|
ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity);
|
||||||
newBuffer.order(buffer.order());
|
newBuffer.order(buffer.order());
|
||||||
buffer.flip(); // Prepare for reading
|
buffer.flip(); // Prepare for reading
|
||||||
newBuffer.put(buffer); // Copy existing data
|
newBuffer.put(buffer); // Copy existing data
|
||||||
buffer = newBuffer; // Assign the new buffer to the field
|
buffer = newBuffer; // Assign the new buffer to the field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,11 +84,11 @@ public final class Savegames {
|
|||||||
L.log("Error saving world: " + e.toString());
|
L.log("Error saving world: " + e.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
|
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
|
||||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||||
ensureDirExists(cheatDetectionFolder);
|
ensureDirExists(cheatDetectionFolder);
|
||||||
File backupFile = new File(cheatDetectionFolder, playerId + "X");
|
File backupFile = new File(cheatDetectionFolder, playerId + "X");
|
||||||
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
|
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
|
||||||
fileOutputStream.write(savegame);
|
fileOutputStream.write(savegame);
|
||||||
@@ -109,8 +109,8 @@ public final class Savegames {
|
|||||||
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, androidContext, fos, fh);
|
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, androidContext, fos, fh);
|
||||||
fos.close();
|
fos.close();
|
||||||
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
|
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
|
||||||
// save to the quicksave slot before deleting the file
|
// save to the quicksave slot before deleting the file
|
||||||
if (!saveWorld(world, androidContext, SLOT_QUICKSAVE)) {
|
if (!saveWorld(world, androidContext, SLOT_QUICKSAVE)) {
|
||||||
return LoadSavegameResult.unknownError;
|
return LoadSavegameResult.unknownError;
|
||||||
}
|
}
|
||||||
getSlotFile(slot, androidContext).delete();
|
getSlotFile(slot, androidContext).delete();
|
||||||
@@ -127,35 +127,35 @@ public final class Savegames {
|
|||||||
}
|
}
|
||||||
return LoadSavegameResult.unknownError;
|
return LoadSavegameResult.unknownError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean triedToCheat(Context androidContext, FileHeader fh) throws IOException {
|
private static boolean triedToCheat(Context androidContext, FileHeader fh) throws IOException {
|
||||||
long savedVersionToCheck = 0;
|
long savedVersionToCheck = 0;
|
||||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||||
ensureDirExists(cheatDetectionFolder);
|
ensureDirExists(cheatDetectionFolder);
|
||||||
File cheatDetectionFile = new File(cheatDetectionFolder, fh.playerId);
|
File cheatDetectionFile = new File(cheatDetectionFolder, fh.playerId);
|
||||||
if (cheatDetectionFile.exists()) {
|
if (cheatDetectionFile.exists()) {
|
||||||
FileInputStream fileInputStream = new FileInputStream(cheatDetectionFile);
|
FileInputStream fileInputStream = new FileInputStream(cheatDetectionFile);
|
||||||
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
||||||
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
||||||
savedVersionToCheck = cheatDetection.savedVersion;
|
savedVersionToCheck = cheatDetection.savedVersion;
|
||||||
dataInputStream.close();
|
dataInputStream.close();
|
||||||
fileInputStream.close();
|
fileInputStream.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
|
if (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (androidContext.getFileStreamPath(fh.playerId).exists()) {
|
if (androidContext.getFileStreamPath(fh.playerId).exists()) {
|
||||||
FileInputStream fileInputStream = androidContext.openFileInput(fh.playerId);
|
FileInputStream fileInputStream = androidContext.openFileInput(fh.playerId);
|
||||||
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
|
||||||
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
|
||||||
if (cheatDetection.savedVersion == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
|
if (cheatDetection.savedVersion == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
|
||||||
savedVersionToCheck = DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED;
|
savedVersionToCheck = DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED;
|
||||||
} else if (cheatDetection.savedVersion > savedVersionToCheck) {
|
} else if (cheatDetection.savedVersion > savedVersionToCheck) {
|
||||||
savedVersionToCheck = cheatDetection.savedVersion;
|
savedVersionToCheck = cheatDetection.savedVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
|
||||||
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
|
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
|
||||||
@@ -168,48 +168,48 @@ public final class Savegames {
|
|||||||
return (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED || fh.savedVersion < savedVersionToCheck);
|
return (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED || fh.savedVersion < savedVersionToCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FileOutputStream getOutputFile(Context androidContext, int slot) throws IOException {
|
private static FileOutputStream getOutputFile(Context androidContext, int slot) throws IOException {
|
||||||
if (slot == SLOT_QUICKSAVE) {
|
if (slot == SLOT_QUICKSAVE) {
|
||||||
return androidContext.openFileOutput(Constants.FILENAME_SAVEGAME_QUICKSAVE, Context.MODE_PRIVATE);
|
return androidContext.openFileOutput(Constants.FILENAME_SAVEGAME_QUICKSAVE, Context.MODE_PRIVATE);
|
||||||
} else {
|
} else {
|
||||||
ensureSavegameDirectoryExists(androidContext);
|
ensureSavegameDirectoryExists(androidContext);
|
||||||
return new FileOutputStream(getSlotFile(slot, androidContext));
|
return new FileOutputStream(getSlotFile(slot, androidContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ensureSavegameDirectoryExists(Context context) {
|
private static void ensureSavegameDirectoryExists(Context context) {
|
||||||
File dir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
File dir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||||
ensureDirExists(dir);
|
ensureDirExists(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ensureDirExists(File dir) {
|
public static boolean ensureDirExists(File dir) {
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
boolean worked = dir.mkdir();
|
boolean worked = dir.mkdir();
|
||||||
return worked;
|
return worked;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FileInputStream getInputFile(Context androidContext, int slot) throws IOException {
|
private static FileInputStream getInputFile(Context androidContext, int slot) throws IOException {
|
||||||
if (slot == SLOT_QUICKSAVE) {
|
if (slot == SLOT_QUICKSAVE) {
|
||||||
return androidContext.openFileInput(Constants.FILENAME_SAVEGAME_QUICKSAVE);
|
return androidContext.openFileInput(Constants.FILENAME_SAVEGAME_QUICKSAVE);
|
||||||
} else {
|
} else {
|
||||||
return new FileInputStream(getSlotFile(slot, androidContext));
|
return new FileInputStream(getSlotFile(slot, androidContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getSlotFile(int slot, Context context) {
|
public static File getSlotFile(int slot, Context context) {
|
||||||
File root = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
File root = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||||
return getSlotFile(slot, root);
|
return getSlotFile(slot, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getSlotFile(int slot, File directory) {
|
public static File getSlotFile(int slot, File directory) {
|
||||||
return new File(directory, getSlotFileName(slot));
|
return new File(directory, getSlotFileName(slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSlotFileName(int slot) {
|
public static String getSlotFileName(int slot) {
|
||||||
return Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot;
|
return Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException, DigestException {
|
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException, DigestException {
|
||||||
@@ -230,11 +230,11 @@ public final class Savegames {
|
|||||||
dest.close();
|
dest.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, Context androidContext, InputStream inState, FileHeader fh) throws IOException, DigestException {
|
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, Context androidContext, InputStream inState, FileHeader fh) throws IOException, DigestException {
|
||||||
DataInputStream src = new DataInputStream(inState);
|
DataInputStream src = new DataInputStream(inState);
|
||||||
final FileHeader header = new FileHeader(src, fh.skipIcon);
|
final FileHeader header = new FileHeader(src, fh.skipIcon);
|
||||||
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION)
|
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION)
|
||||||
return LoadSavegameResult.savegameIsFromAFutureVersion;
|
return LoadSavegameResult.savegameIsFromAFutureVersion;
|
||||||
|
|
||||||
world.maps.readFromParcel(src, world, controllers, header.fileversion);
|
world.maps.readFromParcel(src, world, controllers, header.fileversion);
|
||||||
world.model = new ModelContainer(src, world, controllers, header.fileversion);
|
world.model = new ModelContainer(src, world, controllers, header.fileversion);
|
||||||
@@ -247,7 +247,7 @@ public final class Savegames {
|
|||||||
if (header.fileversion < 45) {
|
if (header.fileversion < 45) {
|
||||||
LegacySavegamesContentAdaptations.adaptToNewContentForVersion45(world, controllers, res);
|
LegacySavegamesContentAdaptations.adaptToNewContentForVersion45(world, controllers, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
onWorldLoaded(res, world, controllers);
|
onWorldLoaded(res, world, controllers);
|
||||||
|
|
||||||
return LoadSavegameResult.success;
|
return LoadSavegameResult.success;
|
||||||
@@ -284,15 +284,15 @@ public final class Savegames {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeCheatCheck(Context androidContext, long savedVersion, String playerId) throws IOException {
|
private static void writeCheatCheck(Context androidContext, long savedVersion, String playerId) throws IOException {
|
||||||
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
|
||||||
ensureDirExists(cheatDetectionFolder);
|
ensureDirExists(cheatDetectionFolder);
|
||||||
File cheatDetectionFile = new File(cheatDetectionFolder, playerId);
|
File cheatDetectionFile = new File(cheatDetectionFolder, playerId);
|
||||||
FileOutputStream fileOutputStream = new FileOutputStream(cheatDetectionFile);
|
FileOutputStream fileOutputStream = new FileOutputStream(cheatDetectionFile);
|
||||||
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
|
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
|
||||||
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
|
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
|
||||||
dataOutputStream.close();
|
dataOutputStream.close();
|
||||||
fileOutputStream.close();
|
fileOutputStream.close();
|
||||||
|
|
||||||
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
|
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
|
||||||
dataOutputStream = new DataOutputStream(fileOutputStream);
|
dataOutputStream = new DataOutputStream(fileOutputStream);
|
||||||
@@ -303,26 +303,26 @@ public final class Savegames {
|
|||||||
|
|
||||||
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
|
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
|
||||||
|
|
||||||
public static List<Integer> getUsedSavegameSlots(Context context) {
|
public static List<Integer> getUsedSavegameSlots(Context context) {
|
||||||
try {
|
try {
|
||||||
final List<Integer> result = new ArrayList<Integer>();
|
final List<Integer> result = new ArrayList<Integer>();
|
||||||
AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY).listFiles(new FilenameFilter() {
|
AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY).listFiles(new FilenameFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File f, String filename) {
|
public boolean accept(File f, String filename) {
|
||||||
Matcher m = savegameFilenamePattern.matcher(filename);
|
Matcher m = savegameFilenamePattern.matcher(filename);
|
||||||
if (m != null && m.matches()) {
|
if (m != null && m.matches()) {
|
||||||
result.add(Integer.parseInt(m.group(1)));
|
result.add(Integer.parseInt(m.group(1)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Collections.sort(result);
|
Collections.sort(result);
|
||||||
return result;
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return new ArrayList<Integer>();
|
return new ArrayList<Integer>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class CheatDetection {
|
private static final class CheatDetection {
|
||||||
public final int fileversion;
|
public final int fileversion;
|
||||||
@@ -342,17 +342,17 @@ public final class Savegames {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class FileHeader {
|
public static final class FileHeader {
|
||||||
public final int fileversion;
|
public final int fileversion;
|
||||||
public final String playerName;
|
public final String playerName;
|
||||||
public final String displayInfo;
|
public final String displayInfo;
|
||||||
public final int iconID;
|
public final int iconID;
|
||||||
public final boolean isAlteredSavegame;
|
public final boolean isAlteredSavegame;
|
||||||
public boolean skipIcon = false;
|
public boolean skipIcon = false;
|
||||||
public final boolean isDead;
|
public final boolean isDead;
|
||||||
public final boolean hasUnlimitedSaves;
|
public final boolean hasUnlimitedSaves;
|
||||||
public final String playerId;
|
public final String playerId;
|
||||||
public final long savedVersion;
|
public final long savedVersion;
|
||||||
|
|
||||||
public String describe() {
|
public String describe() {
|
||||||
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo;
|
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo;
|
||||||
@@ -361,18 +361,18 @@ public final class Savegames {
|
|||||||
|
|
||||||
// ====== PARCELABLE ===================================================================
|
// ====== PARCELABLE ===================================================================
|
||||||
|
|
||||||
public FileHeader(DataInputStream src, boolean skipIcon) throws IOException {
|
public FileHeader(DataInputStream src, boolean skipIcon) throws IOException {
|
||||||
int fileversion = src.readInt();
|
int fileversion = src.readInt();
|
||||||
if (fileversion == 11)
|
if (fileversion == 11)
|
||||||
fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
|
fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
|
||||||
this.fileversion = fileversion;
|
this.fileversion = fileversion;
|
||||||
if (fileversion >= 14) { // Before fileversion 14 (0.6.7), we had no file header.
|
if (fileversion >= 14) { // Before fileversion 14 (0.6.7), we had no file header.
|
||||||
this.playerName = src.readUTF();
|
this.playerName = src.readUTF();
|
||||||
this.displayInfo = src.readUTF();
|
this.displayInfo = src.readUTF();
|
||||||
} else {
|
} else {
|
||||||
this.playerName = null;
|
this.playerName = null;
|
||||||
this.displayInfo = null;
|
this.displayInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileversion >= 43) {
|
if (fileversion >= 43) {
|
||||||
int id = src.readInt();
|
int id = src.readInt();
|
||||||
|
|||||||
Reference in New Issue
Block a user