package net.minecraft.server.players; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.io.Files; import com.mojang.authlib.GameProfile; import com.mojang.authlib.ProfileLookupCallback; import com.mojang.authlib.yggdrasil.ProfileNotFoundException; import com.mojang.logging.LogUtils; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.UUID; import javax.annotation.Nullable; import net.minecraft.core.UUIDUtil; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.util.StringUtil; import net.minecraft.world.level.storage.LevelResource; import org.slf4j.Logger; public class OldUsersConverter { static final Logger LOGGER = LogUtils.getLogger(); public static final File OLD_IPBANLIST = new File("banned-ips.txt"); public static final File OLD_USERBANLIST = new File("banned-players.txt"); public static final File OLD_OPLIST = new File("ops.txt"); public static final File OLD_WHITELIST = new File("white-list.txt"); static List readOldListFormat(File p_11074_, Map p_11075_) throws IOException { List list = Files.readLines(p_11074_, StandardCharsets.UTF_8); for (String s : list) { s = s.trim(); if (!s.startsWith("#") && s.length() >= 1) { String[] astring = s.split("\\|"); p_11075_.put(astring[0].toLowerCase(Locale.ROOT), astring); } } return list; } private static void lookupPlayers(MinecraftServer p_11087_, Collection p_11088_, ProfileLookupCallback p_11089_) { String[] astring = p_11088_.stream().filter(p_11077_ -> !StringUtil.isNullOrEmpty(p_11077_)).toArray(String[]::new); if (p_11087_.usesAuthentication()) { p_11087_.getProfileRepository().findProfilesByNames(astring, p_11089_); } else { for (String s : astring) { p_11089_.onProfileLookupSucceeded(UUIDUtil.createOfflineProfile(s)); } } } public static boolean convertUserBanlist(final MinecraftServer p_11082_) { final UserBanList userbanlist = new UserBanList(PlayerList.USERBANLIST_FILE); if (OLD_USERBANLIST.exists() && OLD_USERBANLIST.isFile()) { if (userbanlist.getFile().exists()) { try { userbanlist.load(); } catch (IOException ioexception1) { LOGGER.warn("Could not load existing file {}", userbanlist.getFile().getName(), ioexception1); } } try { final Map map = Maps.newHashMap(); readOldListFormat(OLD_USERBANLIST, map); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { @Override public void onProfileLookupSucceeded(GameProfile p_11123_) { p_11082_.getProfileCache().add(p_11123_); String[] astring = map.get(p_11123_.getName().toLowerCase(Locale.ROOT)); if (astring == null) { OldUsersConverter.LOGGER.warn("Could not convert user banlist entry for {}", p_11123_.getName()); throw new OldUsersConverter.ConversionError("Profile not in the conversionlist"); } else { Date date = astring.length > 1 ? OldUsersConverter.parseDate(astring[1], null) : null; String s = astring.length > 2 ? astring[2] : null; Date date1 = astring.length > 3 ? OldUsersConverter.parseDate(astring[3], null) : null; String s1 = astring.length > 4 ? astring[4] : null; userbanlist.add(new UserBanListEntry(p_11123_, date, s, date1, s1)); } } @Override public void onProfileLookupFailed(String p_300345_, Exception p_11121_) { OldUsersConverter.LOGGER.warn("Could not lookup user banlist entry for {}", p_300345_, p_11121_); if (!(p_11121_ instanceof ProfileNotFoundException)) { throw new OldUsersConverter.ConversionError("Could not request user " + p_300345_ + " from backend systems", p_11121_); } } }; lookupPlayers(p_11082_, map.keySet(), profilelookupcallback); userbanlist.save(); renameOldFile(OLD_USERBANLIST); return true; } catch (IOException ioexception) { LOGGER.warn("Could not read old user banlist to convert it!", (Throwable)ioexception); return false; } catch (OldUsersConverter.ConversionError oldusersconverter$conversionerror) { LOGGER.error("Conversion failed, please try again later", (Throwable)oldusersconverter$conversionerror); return false; } } else { return true; } } public static boolean convertIpBanlist(MinecraftServer p_11099_) { IpBanList ipbanlist = new IpBanList(PlayerList.IPBANLIST_FILE); if (OLD_IPBANLIST.exists() && OLD_IPBANLIST.isFile()) { if (ipbanlist.getFile().exists()) { try { ipbanlist.load(); } catch (IOException ioexception1) { LOGGER.warn("Could not load existing file {}", ipbanlist.getFile().getName(), ioexception1); } } try { Map map = Maps.newHashMap(); readOldListFormat(OLD_IPBANLIST, map); for (String s : map.keySet()) { String[] astring = map.get(s); Date date = astring.length > 1 ? parseDate(astring[1], null) : null; String s1 = astring.length > 2 ? astring[2] : null; Date date1 = astring.length > 3 ? parseDate(astring[3], null) : null; String s2 = astring.length > 4 ? astring[4] : null; ipbanlist.add(new IpBanListEntry(s, date, s1, date1, s2)); } ipbanlist.save(); renameOldFile(OLD_IPBANLIST); return true; } catch (IOException ioexception) { LOGGER.warn("Could not parse old ip banlist to convert it!", (Throwable)ioexception); return false; } } else { return true; } } public static boolean convertOpsList(final MinecraftServer p_11103_) { final ServerOpList serveroplist = new ServerOpList(PlayerList.OPLIST_FILE); if (OLD_OPLIST.exists() && OLD_OPLIST.isFile()) { if (serveroplist.getFile().exists()) { try { serveroplist.load(); } catch (IOException ioexception1) { LOGGER.warn("Could not load existing file {}", serveroplist.getFile().getName(), ioexception1); } } try { List list = Files.readLines(OLD_OPLIST, StandardCharsets.UTF_8); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { @Override public void onProfileLookupSucceeded(GameProfile p_11133_) { p_11103_.getProfileCache().add(p_11133_); serveroplist.add(new ServerOpListEntry(p_11133_, p_11103_.getOperatorUserPermissionLevel(), false)); } @Override public void onProfileLookupFailed(String p_300384_, Exception p_11131_) { OldUsersConverter.LOGGER.warn("Could not lookup oplist entry for {}", p_300384_, p_11131_); if (!(p_11131_ instanceof ProfileNotFoundException)) { throw new OldUsersConverter.ConversionError("Could not request user " + p_300384_ + " from backend systems", p_11131_); } } }; lookupPlayers(p_11103_, list, profilelookupcallback); serveroplist.save(); renameOldFile(OLD_OPLIST); return true; } catch (IOException ioexception) { LOGGER.warn("Could not read old oplist to convert it!", (Throwable)ioexception); return false; } catch (OldUsersConverter.ConversionError oldusersconverter$conversionerror) { LOGGER.error("Conversion failed, please try again later", (Throwable)oldusersconverter$conversionerror); return false; } } else { return true; } } public static boolean convertWhiteList(final MinecraftServer p_11105_) { final UserWhiteList userwhitelist = new UserWhiteList(PlayerList.WHITELIST_FILE); if (OLD_WHITELIST.exists() && OLD_WHITELIST.isFile()) { if (userwhitelist.getFile().exists()) { try { userwhitelist.load(); } catch (IOException ioexception1) { LOGGER.warn("Could not load existing file {}", userwhitelist.getFile().getName(), ioexception1); } } try { List list = Files.readLines(OLD_WHITELIST, StandardCharsets.UTF_8); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { @Override public void onProfileLookupSucceeded(GameProfile p_11143_) { p_11105_.getProfileCache().add(p_11143_); userwhitelist.add(new UserWhiteListEntry(p_11143_)); } @Override public void onProfileLookupFailed(String p_301126_, Exception p_11141_) { OldUsersConverter.LOGGER.warn("Could not lookup user whitelist entry for {}", p_301126_, p_11141_); if (!(p_11141_ instanceof ProfileNotFoundException)) { throw new OldUsersConverter.ConversionError("Could not request user " + p_301126_ + " from backend systems", p_11141_); } } }; lookupPlayers(p_11105_, list, profilelookupcallback); userwhitelist.save(); renameOldFile(OLD_WHITELIST); return true; } catch (IOException ioexception) { LOGGER.warn("Could not read old whitelist to convert it!", (Throwable)ioexception); return false; } catch (OldUsersConverter.ConversionError oldusersconverter$conversionerror) { LOGGER.error("Conversion failed, please try again later", (Throwable)oldusersconverter$conversionerror); return false; } } else { return true; } } @Nullable public static UUID convertMobOwnerIfNecessary(final MinecraftServer p_11084_, String p_11085_) { if (!StringUtil.isNullOrEmpty(p_11085_) && p_11085_.length() <= 16) { Optional optional = p_11084_.getProfileCache().get(p_11085_).map(GameProfile::getId); if (optional.isPresent()) { return optional.get(); } else if (!p_11084_.isSingleplayer() && p_11084_.usesAuthentication()) { final List list = Lists.newArrayList(); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { @Override public void onProfileLookupSucceeded(GameProfile p_11153_) { p_11084_.getProfileCache().add(p_11153_); list.add(p_11153_); } @Override public void onProfileLookupFailed(String p_297583_, Exception p_11151_) { OldUsersConverter.LOGGER.warn("Could not lookup user whitelist entry for {}", p_297583_, p_11151_); } }; lookupPlayers(p_11084_, Lists.newArrayList(p_11085_), profilelookupcallback); return !list.isEmpty() ? list.get(0).getId() : null; } else { return UUIDUtil.createOfflinePlayerUUID(p_11085_); } } else { try { return UUID.fromString(p_11085_); } catch (IllegalArgumentException illegalargumentexception) { return null; } } } public static boolean convertPlayers(final DedicatedServer p_11091_) { final File file1 = getWorldPlayersDirectory(p_11091_); final File file2 = new File(file1.getParentFile(), "playerdata"); final File file3 = new File(file1.getParentFile(), "unknownplayers"); if (file1.exists() && file1.isDirectory()) { File[] afile = file1.listFiles(); List list = Lists.newArrayList(); for (File file4 : afile) { String s = file4.getName(); if (s.toLowerCase(Locale.ROOT).endsWith(".dat")) { String s1 = s.substring(0, s.length() - ".dat".length()); if (!s1.isEmpty()) { list.add(s1); } } } try { final String[] astring = list.toArray(new String[list.size()]); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { @Override public void onProfileLookupSucceeded(GameProfile p_11175_) { p_11091_.getProfileCache().add(p_11175_); UUID uuid = p_11175_.getId(); this.movePlayerFile(file2, this.getFileNameForProfile(p_11175_.getName()), uuid.toString()); } @Override public void onProfileLookupFailed(String p_297890_, Exception p_11173_) { OldUsersConverter.LOGGER.warn("Could not lookup user uuid for {}", p_297890_, p_11173_); if (p_11173_ instanceof ProfileNotFoundException) { String s2 = this.getFileNameForProfile(p_297890_); this.movePlayerFile(file3, s2, s2); } else { throw new OldUsersConverter.ConversionError("Could not request user " + p_297890_ + " from backend systems", p_11173_); } } private void movePlayerFile(File p_11168_, String p_11169_, String p_11170_) { File file5 = new File(file1, p_11169_ + ".dat"); File file6 = new File(p_11168_, p_11170_ + ".dat"); OldUsersConverter.ensureDirectoryExists(p_11168_); if (!file5.renameTo(file6)) { throw new OldUsersConverter.ConversionError("Could not convert file for " + p_11169_); } } private String getFileNameForProfile(String p_299270_) { String s2 = null; for (String s3 : astring) { if (s3 != null && s3.equalsIgnoreCase(p_299270_)) { s2 = s3; break; } } if (s2 == null) { throw new OldUsersConverter.ConversionError("Could not find the filename for " + p_299270_ + " anymore"); } else { return s2; } } }; lookupPlayers(p_11091_, Lists.newArrayList(astring), profilelookupcallback); return true; } catch (OldUsersConverter.ConversionError oldusersconverter$conversionerror) { LOGGER.error("Conversion failed, please try again later", (Throwable)oldusersconverter$conversionerror); return false; } } else { return true; } } static void ensureDirectoryExists(File p_11094_) { if (p_11094_.exists()) { if (!p_11094_.isDirectory()) { throw new OldUsersConverter.ConversionError("Can't create directory " + p_11094_.getName() + " in world save directory."); } } else if (!p_11094_.mkdirs()) { throw new OldUsersConverter.ConversionError("Can't create directory " + p_11094_.getName() + " in world save directory."); } } public static boolean serverReadyAfterUserconversion(MinecraftServer p_11107_) { boolean flag = areOldUserlistsRemoved(); return flag && areOldPlayersConverted(p_11107_); } private static boolean areOldUserlistsRemoved() { boolean flag = false; if (OLD_USERBANLIST.exists() && OLD_USERBANLIST.isFile()) { flag = true; } boolean flag1 = false; if (OLD_IPBANLIST.exists() && OLD_IPBANLIST.isFile()) { flag1 = true; } boolean flag2 = false; if (OLD_OPLIST.exists() && OLD_OPLIST.isFile()) { flag2 = true; } boolean flag3 = false; if (OLD_WHITELIST.exists() && OLD_WHITELIST.isFile()) { flag3 = true; } if (!flag && !flag1 && !flag2 && !flag3) { return true; } else { LOGGER.warn("**** FAILED TO START THE SERVER AFTER ACCOUNT CONVERSION!"); LOGGER.warn("** please remove the following files and restart the server:"); if (flag) { LOGGER.warn("* {}", OLD_USERBANLIST.getName()); } if (flag1) { LOGGER.warn("* {}", OLD_IPBANLIST.getName()); } if (flag2) { LOGGER.warn("* {}", OLD_OPLIST.getName()); } if (flag3) { LOGGER.warn("* {}", OLD_WHITELIST.getName()); } return false; } } private static boolean areOldPlayersConverted(MinecraftServer p_11109_) { File file1 = getWorldPlayersDirectory(p_11109_); if (!file1.exists() || !file1.isDirectory() || file1.list().length <= 0 && file1.delete()) { return true; } else { LOGGER.warn("**** DETECTED OLD PLAYER DIRECTORY IN THE WORLD SAVE"); LOGGER.warn("**** THIS USUALLY HAPPENS WHEN THE AUTOMATIC CONVERSION FAILED IN SOME WAY"); LOGGER.warn("** please restart the server and if the problem persists, remove the directory '{}'", file1.getPath()); return false; } } private static File getWorldPlayersDirectory(MinecraftServer p_11111_) { return p_11111_.getWorldPath(LevelResource.PLAYER_OLD_DATA_DIR).toFile(); } private static void renameOldFile(File p_11101_) { File file1 = new File(p_11101_.getName() + ".converted"); p_11101_.renameTo(file1); } static Date parseDate(String p_11096_, Date p_11097_) { Date date; try { date = BanListEntry.DATE_FORMAT.parse(p_11096_); } catch (ParseException parseexception) { date = p_11097_; } return date; } static class ConversionError extends RuntimeException { ConversionError(String p_11182_, Throwable p_11183_) { super(p_11182_, p_11183_); } ConversionError(String p_11177_) { super(p_11177_); } } }