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.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider; import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File; import java.io.File;
import java.text.DecimalFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -25,9 +26,27 @@ public class ExportDataTreeNode extends CommandTreeNode {
super(parent, "exportdata"); 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 @Override
public CommandResult execute(CommandSender sender, String[] strings) { 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()) final List<UUID> playerIds = Arrays.stream(new File(MMOCore.plugin.getDataFolder() + "/userdata").listFiles())
.map(file -> UUID.fromString(file.getName().replace(".yml", ""))).collect(Collectors.toList()); .map(file -> UUID.fromString(file.getName().replace(".yml", ""))).collect(Collectors.toList());
@ -40,31 +59,48 @@ public class ExportDataTreeNode extends CommandTreeNode {
return CommandResult.FAILURE; 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("Exporting " + playerIds.size() + " player data(s).. See console for details");
sender.sendMessage("Minimum expected time: " + decFormat.format(timeEstimation) + "s");
// Save player data // Save player data
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { new BukkitRunnable() {
// Loop first for garbage collection
int errorCount = 0; int errorCount = 0;
for (UUID playerId : playerIds) int batchCounter = 0;
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 @Override
sqlProvider.getDataManager().saveData(offlinePlayerData); public void run() {
} catch (RuntimeException exception) { for (int i = 0; i < BATCH_AMOUNT; i++) {
errorCount++; final int index = BATCH_AMOUNT * batchCounter + i;
exception.printStackTrace();
/*
* 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); batchCounter++;
}
// Close connection to avoid memory leaks }.runTaskTimerAsynchronously(MMOCore.plugin, 0, BATCH_PERIOD);
sqlProvider.close();
});
return CommandResult.SUCCESS; return CommandResult.SUCCESS;
} }