Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.mvplugins.multiverse.inventories.commands.bulkedit.playerprofile;

import com.google.common.io.Files;
import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.command.MVCommandIssuer;
import org.mvplugins.multiverse.core.command.queue.CommandQueueManager;
Expand All @@ -17,8 +18,16 @@
import org.mvplugins.multiverse.inventories.profile.key.ProfileKey;
import org.mvplugins.multiverse.inventories.profile.key.ProfileTypes;
import org.mvplugins.multiverse.inventories.profile.key.ContainerType;
import org.mvplugins.multiverse.inventories.profile.ProfileFilesLocator;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicLong;

Expand All @@ -28,16 +37,19 @@ final class MigrateInventorySerializationCommand extends InventoriesCommand {
private final CommandQueueManager commandQueueManager;
private final ProfileDataSource profileDataSource;
private final InventoriesConfig inventoriesConfig;
private final ProfileFilesLocator profileFilesLocator;

@Inject
MigrateInventorySerializationCommand(
@NotNull CommandQueueManager commandQueueManager,
@NotNull ProfileDataSource profileDataSource,
@NotNull InventoriesConfig inventoriesConfig
@NotNull InventoriesConfig inventoriesConfig,
@NotNull ProfileFilesLocator profileFilesLocator
) {
this.commandQueueManager = commandQueueManager;
this.profileDataSource = profileDataSource;
this.inventoriesConfig = inventoriesConfig;
this.profileFilesLocator = profileFilesLocator;
}

@Subcommand("bulkedit migrate inventory-serialization nbt")
Expand All @@ -62,23 +74,63 @@ private void doMigration(MVCommandIssuer issuer, boolean useByteSerialization) {

long startTime = System.nanoTime();
AtomicLong profileCounter = new AtomicLong(0);
CompletableFuture.allOf(profileDataSource.listGlobalProfileUUIDs()
.stream()
.map(playerUUID -> profileDataSource.getGlobalProfile(GlobalProfileKey.of(playerUUID, ""))
.thenCompose(profile -> run(profile, profileCounter))
.exceptionally(throwable -> {
issuer.sendMessage("Error updating player " + playerUUID + ": " + throwable.getMessage());
return null;
}))
.toArray(CompletableFuture[]::new))
.thenRun(() -> {
long timeDuration = (System.nanoTime() - startTime) / 1000000;
issuer.sendMessage("Updated " + profileCounter.get() + " player profiles.");
issuer.sendMessage("Bulk edit completed in " + timeDuration + " ms.");
});

// Scan global files
Set<String> fileNamesSet = new HashSet<>();
profileFilesLocator.listGlobalFiles().forEach(file ->
fileNamesSet.add(Files.getNameWithoutExtension(file.getName())));

// Scan world and group files
for (ContainerType type : ContainerType.values()) {
for (File folder : profileFilesLocator.listProfileContainerFolders(type)) {
profileFilesLocator.listPlayerProfileFiles(type, folder.getName()).forEach(file ->
fileNamesSet.add(Files.getNameWithoutExtension(file.getName())));
}
}

List<String> fileNames = new ArrayList<>(fileNamesSet);
issuer.sendMessage("Found " + fileNames.size() + " unique players to migrate.");

CompletableFuture<Void> future = CompletableFuture.completedFuture(null);
for (int i = 0; i < fileNames.size(); i++) {
final int index = i;
final String fileName = fileNames.get(i);

future = future.thenCompose(v -> {
UUID playerUUID;
try {
playerUUID = UUID.fromString(fileName);
} catch (IllegalArgumentException e) {
playerUUID = UUID.nameUUIDFromBytes(("OfflinePlayer:" + fileName).getBytes(StandardCharsets.UTF_8));
}

if (index % 100 == 0) {
issuer.sendMessage("Processed " + index + " players...");
}

return profileDataSource.getGlobalProfile(GlobalProfileKey.of(playerUUID, fileName))
.thenCompose(profile -> run(profile, profileCounter))
.exceptionally(throwable -> {
issuer.sendMessage("Error updating player " + fileName + ": " + throwable.getMessage());
return null;
});
});
}

future.thenRun(() -> {
long timeDuration = (System.nanoTime() - startTime) / 1000000;
issuer.sendMessage("Updated " + profileCounter.get() + " player profiles.");
issuer.sendMessage("Bulk edit completed in " + timeDuration + " ms.");
});
}

private CompletableFuture<Void> run(GlobalProfile profile, AtomicLong profileCounter) {
String fileName = profile.getLastKnownName();
if (fileName == null || fileName.isEmpty()) {
fileName = profile.getPlayerUUID().toString();
}
final String finalFileName = fileName;

return CompletableFuture.allOf(Arrays.stream(ContainerType.values())
.flatMap(containerType -> profileDataSource.listContainerDataNames(containerType).stream()
.flatMap(dataName -> ProfileTypes.getTypes().stream()
Expand All @@ -87,7 +139,7 @@ private CompletableFuture<Void> run(GlobalProfile profile, AtomicLong profileCou
dataName,
profileType,
profile.getPlayerUUID(),
profile.getLastKnownName()
finalFileName
)).thenCompose(playerProfile -> {
if (playerProfile.getData().isEmpty()) {
return CompletableFuture.completedFuture(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import java.util.UUID;

@Service
final class ProfileFilesLocator {
public final class ProfileFilesLocator {

private static final String JSON = ".json";

Expand Down Expand Up @@ -67,7 +67,7 @@ File getContainerFolder(ContainerType type) {
};
}

List<File> listProfileContainerFolders(ContainerType type) {
public List<File> listProfileContainerFolders(ContainerType type) {
return Option.of(getContainerFolder(type).listFiles())
.map(filesList -> Arrays.stream(filesList)
.filter(File::isDirectory)
Expand All @@ -83,7 +83,7 @@ File getProfileContainerFolder(ContainerType type, String folderName) {
return folder;
}

List<File> listPlayerProfileFiles(ContainerType type, String dataName) {
public List<File> listPlayerProfileFiles(ContainerType type, String dataName) {
return Option.of(getProfileContainerFolder(type, dataName).listFiles())
.map(filesList -> Arrays.stream(filesList)
.filter(File::isFile)
Expand Down Expand Up @@ -120,7 +120,7 @@ File getGlobalFolder() {
return this.globalFolder;
}

List<File> listGlobalFiles() {
public List<File> listGlobalFiles() {
return Option.of(this.globalFolder.listFiles())
.map(filesList -> Arrays.stream(filesList)
.filter(File::isFile)
Expand Down