Fixed /.. exportdata

This commit is contained in:
Indyuce 2022-10-16 22:11:14 +02:00
parent dcbd92e2ee
commit fb2cffe57f

View File

@ -5,10 +5,11 @@ import io.lumine.mythic.lib.command.api.CommandTreeNode;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
@ -25,9 +26,27 @@ public class ExportDataTreeNode extends CommandTreeNode {
super(parent, "exportdata");
}
/**
* Amount of requests generated every batch
*/
private static final int BATCH_AMOUNT = 50;
/**
* Period in ticks
*/
private static final int BATCH_PERIOD = 20;
private static final DecimalFormat decFormat = new DecimalFormat("0.#");
@Override
public CommandResult execute(CommandSender sender, String[] strings) {
if (!MMOCore.plugin.dataProvider.getDataManager().getLoaded().isEmpty()) {
sender.sendMessage("Please make sure no players are logged in when using this command. " +
"If you are still seeing this message, restart your server and execute this command before any player logs in.");
return CommandResult.FAILURE;
}
final List<UUID> playerIds = Arrays.stream(new File(MMOCore.plugin.getDataFolder() + "/userdata").listFiles())
.map(file -> UUID.fromString(file.getName().replace(".yml", ""))).collect(Collectors.toList());
@ -40,31 +59,48 @@ public class ExportDataTreeNode extends CommandTreeNode {
return CommandResult.FAILURE;
}
final double timeEstimation = (double) playerIds.size() / BATCH_AMOUNT * BATCH_PERIOD / 20;
sender.sendMessage("Exporting " + playerIds.size() + " player data(s).. See console for details");
sender.sendMessage("Minimum expected time: " + decFormat.format(timeEstimation) + "s");
// Save player data
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
// Loop first for garbage collection
new BukkitRunnable() {
int errorCount = 0;
for (UUID playerId : playerIds)
try {
final PlayerData offlinePlayerData = new PlayerData(new MMOPlayerData(playerId));
MMOCore.plugin.dataProvider.getDataManager().loadData(offlinePlayerData);
int batchCounter = 0;
// Player data is loaded, now it gets saved through SQL
sqlProvider.getDataManager().saveData(offlinePlayerData);
} catch (RuntimeException exception) {
errorCount++;
exception.printStackTrace();
@Override
public void run() {
for (int i = 0; i < BATCH_AMOUNT; i++) {
final int index = BATCH_AMOUNT * batchCounter + i;
/*
* Saving is done. Close connection to avoid memory
* leaks and ouput the results to the command executor
*/
if (index >= playerIds.size()) {
cancel();
sqlProvider.close();
MMOCore.plugin.getLogger().log(Level.WARNING, "Exported " + playerIds.size() + " player datas to SQL database. Total errors: " + errorCount);
return;
}
final UUID playerId = playerIds.get(index);
try {
final PlayerData offlinePlayerData = new PlayerData(new MMOPlayerData(playerId));
MMOCore.plugin.dataProvider.getDataManager().loadData(offlinePlayerData);
// Player data is loaded, now it gets saved through SQL
sqlProvider.getDataManager().saveData(offlinePlayerData);
} catch (RuntimeException exception) {
errorCount++;
exception.printStackTrace();
}
}
MMOCore.plugin.getLogger().log(Level.WARNING, "Exported player data to SQL database. Total errors: " + errorCount);
// Close connection to avoid memory leaks
sqlProvider.close();
});
batchCounter++;
}
}.runTaskTimerAsynchronously(MMOCore.plugin, 0, BATCH_PERIOD);
return CommandResult.SUCCESS;
}