151 lines
5.3 KiB
Java
151 lines
5.3 KiB
Java
package com.songoda.epicanchors.files.migration;
|
|
|
|
import com.craftaro.core.configuration.Config;
|
|
import com.craftaro.core.configuration.ConfigSection;
|
|
import com.craftaro.core.database.DataMigration;
|
|
import com.craftaro.core.database.DataMigrationManager;
|
|
import com.craftaro.core.database.DatabaseConnector;
|
|
import com.songoda.epicanchors.files.DataManager;
|
|
import com.songoda.epicanchors.utils.ThreadSync;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.plugin.Plugin;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import java.util.logging.Level;
|
|
|
|
public class AnchorMigration extends DataMigrationManager {
|
|
private final DataManager dataManager;
|
|
|
|
public AnchorMigration(DatabaseConnector databaseConnector, DataManager dataManager, DataMigration... migrations) {
|
|
super(databaseConnector, dataManager, migrations);
|
|
|
|
this.dataManager = dataManager;
|
|
}
|
|
|
|
public void migrateLegacyData(Plugin plugin) {
|
|
long start = System.nanoTime();
|
|
|
|
AtomicBoolean abortMigration = new AtomicBoolean(false);
|
|
int migratedAnchors = 0;
|
|
|
|
Config legacyData = new Config(plugin, "data.yml");
|
|
|
|
if (legacyData.getFile().exists()) {
|
|
ThreadSync thSync = new ThreadSync();
|
|
|
|
legacyData.load();
|
|
|
|
ConfigSection cfgSection = legacyData.getConfigurationSection("Anchors");
|
|
|
|
if (cfgSection == null) return;
|
|
|
|
List<LegacyAnchorEntry> anchorQueue = new ArrayList<>();
|
|
|
|
for (String locationStr : cfgSection.getKeys(false)) {
|
|
int ticksLeft = cfgSection.getInt(locationStr + ".ticksLeft");
|
|
String[] locArgs = deserializeLegacyLocation(locationStr);
|
|
|
|
if (ticksLeft == -99) {
|
|
ticksLeft = -1;
|
|
}
|
|
|
|
if (locArgs.length == 0) {
|
|
abortMigration.set(true);
|
|
|
|
plugin.getLogger().warning(() -> "Error migrating anchor '" + locationStr + "': invalid format - expected 'worldName:X:Y:Z'");
|
|
break;
|
|
}
|
|
|
|
String worldName = locArgs[0];
|
|
int x = Location.locToBlock(Double.parseDouble(locArgs[1]));
|
|
int y = Location.locToBlock(Double.parseDouble(locArgs[2]));
|
|
int z = Location.locToBlock(Double.parseDouble(locArgs[3]));
|
|
|
|
int finalTicksLeft = ticksLeft;
|
|
this.dataManager.exists(worldName, x, y, z, (ex, anchorExists) -> {
|
|
if (ex == null) {
|
|
if (anchorExists) {
|
|
cfgSection.set(locationStr, null);
|
|
} else {
|
|
anchorQueue.add(new LegacyAnchorEntry(worldName, x, y, z, finalTicksLeft));
|
|
}
|
|
} else {
|
|
abortMigration.set(true);
|
|
|
|
plugin.getLogger().log(Level.SEVERE, ex, () -> "Error migrating Anchor '" + locationStr + "' from '" +
|
|
legacyData.getFile().getName() + "'");
|
|
}
|
|
|
|
thSync.release();
|
|
});
|
|
|
|
thSync.waitForRelease();
|
|
thSync.reset();
|
|
|
|
if (abortMigration.get()) break;
|
|
|
|
++migratedAnchors;
|
|
}
|
|
|
|
if (!abortMigration.get()) {
|
|
int finalMigratedAnchors = migratedAnchors;
|
|
this.dataManager.migrateAnchor(anchorQueue, ex -> {
|
|
long end = System.nanoTime();
|
|
|
|
if (ex == null) {
|
|
try {
|
|
Files.deleteIfExists(legacyData.getFile().toPath());
|
|
} catch (IOException err) {
|
|
plugin.getLogger().warning("Could not delete '" + legacyData.getFile().getName() + "' after data migration: " + err.getMessage());
|
|
}
|
|
|
|
plugin.getLogger().info("Successfully migrated " + finalMigratedAnchors + " Anchors from '" +
|
|
legacyData.getFile().getName() + "' (" + TimeUnit.NANOSECONDS.toMillis(end - start) + "ms)");
|
|
} else {
|
|
legacyData.save();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
private String[] deserializeLegacyLocation(String str) {
|
|
if (str == null || str.isEmpty()) {
|
|
return new String[0];
|
|
}
|
|
|
|
str = str
|
|
.replace("w:", "")
|
|
.replace("x:", ":")
|
|
.replace("y:", ":")
|
|
.replace("z:", ":")
|
|
.replace("/", ".");
|
|
|
|
String[] args = str.split(":");
|
|
|
|
return args.length == 4 ? args : new String[0];
|
|
}
|
|
|
|
public static class LegacyAnchorEntry {
|
|
public final String worldName;
|
|
public final int x;
|
|
public final int y;
|
|
public final int z;
|
|
|
|
public final int ticksLeft;
|
|
|
|
public LegacyAnchorEntry(String worldName, int x, int y, int z, int ticksLeft) {
|
|
this.worldName = worldName;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.ticksLeft = ticksLeft;
|
|
}
|
|
}
|
|
}
|