Skip to content

Commit a0ce5c5

Browse files
authored
Merge pull request #561 from Multiverse/ben/mv5/playernamechange
Fix player name change migration
2 parents e16f4bb + 403b5ea commit a0ce5c5

File tree

3 files changed

+76
-48
lines changed

3 files changed

+76
-48
lines changed

src/main/java/org/mvplugins/multiverse/inventories/listeners/InventoriesListener.java

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import java.io.File;
5454
import java.io.IOException;
5555
import java.util.List;
56+
import java.util.UUID;
5657
import java.util.stream.Collectors;
5758

5859
/**
@@ -183,27 +184,9 @@ public void playerPreLogin(AsyncPlayerPreLoginEvent event) {
183184
if (event.getLoginResult() != Result.ALLOWED) {
184185
return;
185186
}
186-
187187
Logging.finer("Loading global profile for Player{name:'%s', uuid:'%s'}.",
188188
event.getName(), event.getUniqueId());
189-
190-
GlobalProfile globalProfile = profileDataSource.getGlobalProfile(event.getName(), event.getUniqueId());
191-
if (!globalProfile.getLastKnownName().equalsIgnoreCase(event.getName())) {
192-
// Data must be migrated
193-
Logging.info("Player %s changed name from '%s' to '%s'. Attempting to migrate playerdata...",
194-
event.getUniqueId(), globalProfile.getLastKnownName(), event.getName());
195-
try {
196-
profileDataSource.migratePlayerData(globalProfile.getLastKnownName(), event.getName(),
197-
event.getUniqueId(), true);
198-
} catch (IOException e) {
199-
Logging.severe("An error occurred while trying to migrate playerdata.");
200-
e.printStackTrace();
201-
}
202-
203-
globalProfile.setLastKnownName(event.getName());
204-
profileDataSource.updateGlobalProfile(globalProfile);
205-
Logging.info("Migration complete!");
206-
}
189+
verifyCorrectPlayerName(event.getUniqueId(), event.getName());
207190
}
208191

209192
/**
@@ -214,6 +197,9 @@ public void playerPreLogin(AsyncPlayerPreLoginEvent event) {
214197
@EventHandler
215198
public void playerJoin(final PlayerJoinEvent event) {
216199
final Player player = event.getPlayer();
200+
// Just in case AsyncPlayerPreLoginEvent was still the old name
201+
verifyCorrectPlayerName(player.getUniqueId(), player.getName());
202+
217203
final GlobalProfile globalProfile = profileDataSource.getGlobalProfile(player.getName(), player.getUniqueId());
218204
final String world = globalProfile.getLastWorld();
219205
if (config.usingLoggingSaveLoad() && globalProfile.shouldLoadOnLogin()) {
@@ -228,6 +214,26 @@ public void playerJoin(final PlayerJoinEvent event) {
228214
verifyCorrectWorld(player, player.getWorld().getName(), globalProfile);
229215
}
230216

217+
private void verifyCorrectPlayerName(UUID uuid, String name) {
218+
GlobalProfile globalProfile = profileDataSource.getGlobalProfile(name, uuid);
219+
if (globalProfile.getLastKnownName().equals(name)) {
220+
return;
221+
}
222+
223+
// Data must be migrated
224+
Logging.info("Player %s changed name from '%s' to '%s'. Attempting to migrate playerdata...",
225+
uuid, globalProfile.getLastKnownName(), name);
226+
try {
227+
profileDataSource.migratePlayerData(globalProfile.getLastKnownName(), name, uuid);
228+
} catch (IOException e) {
229+
Logging.severe("An error occurred while trying to migrate playerdata.");
230+
e.printStackTrace();
231+
}
232+
globalProfile.setLastKnownName(name);
233+
profileDataSource.updateGlobalProfile(globalProfile);
234+
Logging.info("Migration complete!");
235+
}
236+
231237
/**
232238
* Called when a player leaves the server.
233239
*

src/main/java/org/mvplugins/multiverse/inventories/profile/FlatFileProfileDataSource.java

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.dumptruckman.minecraft.util.Logging;
55
import com.google.common.cache.Cache;
66
import com.google.common.cache.CacheBuilder;
7+
import com.google.common.collect.Sets;
78
import net.minidev.json.parser.JSONParser;
89
import net.minidev.json.parser.ParseException;
910
import org.bukkit.configuration.InvalidConfigurationException;
@@ -143,11 +144,26 @@ private File getFolder(ContainerType type, String folderName) {
143144
* @return The data file for a player.
144145
* @throws IOException if there was a problem creating the file.
145146
*/
146-
File getPlayerFile(ContainerType type, String dataName, String playerName) throws IOException {
147+
private File getPlayerFile(ContainerType type, String dataName, String playerName) throws IOException {
148+
return getPlayerFile(type, dataName, playerName, true);
149+
}
150+
151+
/**
152+
* Retrieves the data file for a player based on a given world/group name, creating it if necessary.
153+
*
154+
* @param type Indicates whether data is for group or world.
155+
* @param dataName The name of the group or world.
156+
* @param playerName The name of the player.
157+
* @return The data file for a player.
158+
* @throws IOException if there was a problem creating the file.
159+
*/
160+
private File getPlayerFile(ContainerType type, String dataName, String playerName, boolean createNew) throws IOException {
147161
File jsonPlayerFile = new File(this.getFolder(type, dataName), playerName + JSON);
148162
if (!jsonPlayerFile.exists()) {
149163
try {
150-
jsonPlayerFile.createNewFile();
164+
if (createNew) {
165+
jsonPlayerFile.createNewFile();
166+
}
151167
} catch (IOException e) {
152168
throw new IOException("Could not create necessary player data file: " + jsonPlayerFile.getPath()
153169
+ ". Data for " + playerName + " in " + type.name().toLowerCase() + " " + dataName
@@ -547,7 +563,9 @@ public void setLoadOnLogin(final String playerName, final boolean loadOnLogin) {
547563
}
548564

549565
@Override
550-
public void migratePlayerData(String oldName, String newName, UUID uuid, boolean removeOldData) throws IOException {
566+
public void migratePlayerData(String oldName, String newName, UUID uuid) throws IOException {
567+
clearPlayerCache(uuid);
568+
551569
File[] worldFolders = worldFolder.listFiles(File::isDirectory);
552570
if (worldFolders == null) {
553571
throw new IOException("Could not enumerate world folders");
@@ -557,36 +575,41 @@ public void migratePlayerData(String oldName, String newName, UUID uuid, boolean
557575
throw new IOException("Could not enumerate group folders");
558576
}
559577

560-
for (File worldFolder : worldFolders) {
561-
ProfileKey key = ProfileKey.createProfileKey(ContainerType.WORLD, worldFolder.getName(),
562-
ProfileTypes.ADVENTURE, uuid, oldName);
563-
updatePlayerData(getPlayerData(key));
564-
updatePlayerData(getPlayerData(ProfileKey.createProfileKey(key, ProfileTypes.CREATIVE)));
565-
updatePlayerData(getPlayerData(ProfileKey.createProfileKey(key, ProfileTypes.SURVIVAL)));
566-
}
567-
568-
for (File groupFolder : groupFolders) {
569-
ProfileKey key = ProfileKey.createProfileKey(ContainerType.GROUP, groupFolder.getName(),
570-
ProfileTypes.ADVENTURE, uuid, oldName);
571-
updatePlayerData(getPlayerData(key));
572-
updatePlayerData(getPlayerData(ProfileKey.createProfileKey(key, ProfileTypes.CREATIVE)));
573-
updatePlayerData(getPlayerData(ProfileKey.createProfileKey(key, ProfileTypes.SURVIVAL)));
574-
}
578+
migrateForContainerType(worldFolders, ContainerType.WORLD, oldName, newName);
579+
migrateForContainerType(groupFolders, ContainerType.GROUP, oldName, newName);
580+
}
575581

576-
if (removeOldData) {
577-
for (File worldFolder : worldFolders) {
578-
removePlayerData(ContainerType.WORLD, worldFolder.getName(), ProfileTypes.ADVENTURE, oldName);
579-
removePlayerData(ContainerType.WORLD, worldFolder.getName(), ProfileTypes.CREATIVE, oldName);
580-
removePlayerData(ContainerType.WORLD, worldFolder.getName(), ProfileTypes.SURVIVAL, oldName);
582+
private void migrateForContainerType(File[] folders, ContainerType containerType, String oldName, String newName) throws IOException {
583+
for (File folder : folders) {
584+
File oldNameFile = getPlayerFile(containerType, folder.getName(), oldName, false);
585+
File newNameFile = getPlayerFile(containerType, folder.getName(), newName, false);
586+
if (!oldNameFile.exists()) {
587+
Logging.fine("No old data for player %s in %s %s to migrate.",
588+
oldName, containerType.name(), folder.getName());
589+
continue;
590+
}
591+
if (newNameFile.exists()) {
592+
Logging.warning("Data already exists for player %s in %s %s. Not migrating.",
593+
newName, containerType.name(), folder.getName());
594+
continue;
581595
}
582-
for (File groupFolder : groupFolders) {
583-
removePlayerData(ContainerType.GROUP, groupFolder.getName(), ProfileTypes.ADVENTURE, oldName);
584-
removePlayerData(ContainerType.GROUP, groupFolder.getName(), ProfileTypes.CREATIVE, oldName);
585-
removePlayerData(ContainerType.GROUP, groupFolder.getName(), ProfileTypes.SURVIVAL, oldName);
596+
if (!oldNameFile.renameTo(newNameFile)) {
597+
Logging.warning("Could not rename old data file for player %s in %s %s to %s.",
598+
oldName, containerType.name(), folder.getName(), newName);
599+
continue;
586600
}
601+
Logging.fine("Migrated data for player %s in %s %s to %s.",
602+
oldName, containerType.name(), folder.getName(), newName);
587603
}
588604
}
589605

606+
void clearPlayerCache(UUID playerUUID) {
607+
profileCache.invalidateAll(Sets.filter(
608+
profileCache.asMap().keySet(),
609+
key -> key.getPlayerUUID().equals(playerUUID)
610+
));
611+
}
612+
590613
@Override
591614
public void clearProfileCache(ProfileKey key) {
592615
profileCache.invalidate(key);

src/main/java/org/mvplugins/multiverse/inventories/profile/ProfileDataSource.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,9 @@ public sealed interface ProfileDataSource permits FlatFileProfileDataSource {
9393
* @param oldName the previous name of the player.
9494
* @param newName the new name of the player.
9595
* @param playerUUID the UUID of the player.
96-
* @param removeOldData whether or not to remove the data belonging to oldName.
9796
* @throws IOException Thrown if something goes wrong while migrating the files.
9897
*/
99-
void migratePlayerData(String oldName, String newName, UUID playerUUID, boolean removeOldData) throws IOException;
98+
void migratePlayerData(String oldName, String newName, UUID playerUUID) throws IOException;
10099

101100
/**
102101
* Clears a single profile in cache.

0 commit comments

Comments
 (0)