Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
eee82e4
Store username history inside userdata
JRoy Oct 14, 2021
c8a39da
Remove legacy uuidconvert and uuidtest subcommands
JRoy Oct 14, 2021
d963b25
Remove legacy code from UserMap and UUIDMap
JRoy Oct 15, 2021
1cedfb3
Start work on ModernUUIDCache
JRoy Oct 15, 2021
5887d7a
Also cache all uuids in seperate file
JRoy Oct 16, 2021
ea2b071
Complete first iteration of ModernUserMap
JRoy Oct 17, 2021
3d6962d
Replace uuid cache upgrade
JRoy Oct 17, 2021
1244f50
Replace all usages of UserMap with ModernUserMap
JRoy Oct 17, 2021
f2b6f4c
Backport some select methods to the old UserMap class
JRoy Oct 17, 2021
1131574
Forcefully save NPC names into uuid cache
JRoy Oct 17, 2021
614a0e6
Properly save the UUID/Name cache on shutdown
JRoy Oct 17, 2021
da79e8c
Actually read more than one user/uuid
JRoy Oct 17, 2021
65c2d08
Add /ess usermap command for information on the usermap
JRoy Oct 17, 2021
6e67a0a
Add usermap.bin and uuids.bin to .gitignore
JRoy Oct 17, 2021
79318a1
Make StringUtil#safeString null-safe
JRoy Oct 18, 2021
289fee4
Move config save hook to contructor
JRoy Oct 18, 2021
b6097e7
Initialize legacy user map
JRoy Oct 18, 2021
cfc1346
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Oct 20, 2021
4514831
Merge remote-tracking branch 'upstream/2.x' into refactor/usermap-rew…
JRoy Oct 24, 2021
904e664
Update Essentials/src/main/java/com/earth2me/essentials/userstorage/M…
JRoy Nov 4, 2021
3dcb9aa
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Nov 4, 2021
f751672
Merge remote-tracking branch 'upstream/2.x' into refactor/usermap-rew…
JRoy Nov 6, 2021
db434f5
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Nov 24, 2021
cd92113
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Nov 25, 2021
e28b04c
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Nov 30, 2021
6a47e01
Merge remote-tracking branch 'upstream/2.x' into refactor/usermap-rew…
JRoy Dec 5, 2021
966f22c
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Dec 16, 2021
1f6d823
Update Essentials/src/main/java/com/earth2me/essentials/userstorage/M…
JRoy Dec 16, 2021
a47d8ff
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Dec 23, 2021
44a09df
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Dec 26, 2021
5c2b23d
Merge branch '2.x' into refactor/usermap-rewrite
triagonal Jan 16, 2022
78cbde1
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Feb 1, 2022
6600174
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Feb 13, 2022
894156e
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Feb 13, 2022
0dfaa57
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Feb 22, 2022
c5a61e1
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Mar 5, 2022
9fbcb05
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Mar 23, 2022
54a4967
Merge branch '2.x' into refactor/usermap-rewrite
JRoy May 22, 2022
c1b7147
Fix compile error
JRoy May 23, 2022
3111a82
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jun 10, 2022
8cdfceb
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jun 23, 2022
035c87b
Add a few more debug commands
JRoy Jun 25, 2022
0627bda
Fix usermap not getting saved during new uuid insertions
JRoy Jun 25, 2022
2fc006f
Add some additional debug messages
JRoy Jun 25, 2022
169bed1
Prefer UUIDv4 during usermap initialization
JRoy Jun 27, 2022
71595d3
Add more usermap debug commands
JRoy Jun 27, 2022
a05668d
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jun 27, 2022
2d04796
joker moment
JRoy Jun 27, 2022
c7f3fba
...
JRoy Jun 27, 2022
4601b78
Fix a few typos in javadocs
JRoy Jun 27, 2022
37f26a6
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jul 4, 2022
02d0ed2
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jul 5, 2022
dd313e0
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jul 11, 2022
b9101af
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jul 22, 2022
963d92e
Compare logout timestamps when replacing same uuid version
JRoy Jul 23, 2022
32b6184
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Jul 23, 2022
d7a2834
Don't cache users into map for luckperms contexts
JRoy Jul 26, 2022
16c4ee8
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Aug 12, 2022
07a3980
Merge remote-tracking branch 'upstream/2.x' into refactor/usermap-rew…
JRoy Aug 13, 2022
42f52bf
Always update usernames on join
JRoy Aug 13, 2022
dcb6400
Add ModernUserMap#loadUncachedUser(Player)
JRoy Aug 13, 2022
eb5c42d
if i broke one more damn thing, i'm reverting everything
JRoy Aug 14, 2022
2f20b82
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Aug 17, 2022
9531e33
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Aug 18, 2022
0a5b4d6
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Aug 21, 2022
4685ac9
Merge branch '2.x' into refactor/usermap-rewrite
JRoy Aug 22, 2022
6fcd963
Use safe string for Economy and VaultEconomyProvider always
JRoy Aug 25, 2022
0dc9200
Change some method visibility, create IUserMap
JRoy Aug 25, 2022
1d86993
Misc review items
JRoy Aug 25, 2022
967678b
Merge branch 'dev/2.20' into refactor/usermap-rewrite
mdcfe Aug 31, 2022
988dd78
Restore checkstyle-idea.xml
JRoy Aug 31, 2022
09f864e
Add npc-name property for generated NPC accounts
JRoy Sep 2, 2022
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
/Essentials/kits.yml
/Essentials/userdata/testplayer1.yml
/Essentials/usermap.csv
/Essentials/usermap.bin
/Essentials/uuids.bin

# Build files
.gradle/
Expand Down
2 changes: 1 addition & 1 deletion .idea/checkstyle-idea.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public BalanceTopImpl(IEssentials ess) {
private void calculateBalanceTopMap() {
final List<Entry> entries = new LinkedList<>();
BigDecimal newTotal = BigDecimal.ZERO;
for (UUID u : ess.getUserMap().getAllUniqueUsers()) {
final User user = ess.getUserMap().getUser(u);
for (UUID u : ess.getUsers().getAllUserUUIDs()) {
final User user = ess.getUsers().loadUncachedUser(u);
if (user != null) {
if (!ess.getSettings().isNpcsInBalanceRanking() && user.isNPC()) {
// Don't list NPCs in output
Expand Down
26 changes: 19 additions & 7 deletions Essentials/src/main/java/com/earth2me/essentials/Essentials.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.updatecheck.UpdateChecker;
import com.earth2me.essentials.userstorage.ModernUserMap;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.VersionUtil;
import io.papermc.lib.PaperLib;
Expand Down Expand Up @@ -155,7 +156,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private transient CustomItemResolver customItemResolver;
private transient PermissionsHandler permissionsHandler;
private transient AlternativeCommandsHandler alternativeCommandsHandler;
private transient UserMap userMap;
@Deprecated
private transient UserMap legacyUserMap;
private transient ModernUserMap userMap;
private transient BalanceTopImpl balanceTop;
private transient ExecuteTimer execTimer;
private transient MailService mail;
Expand Down Expand Up @@ -222,7 +225,7 @@ public void setupForTesting(final Server server) throws IOException, InvalidDesc
LOGGER.log(Level.INFO, dataFolder.toString());
settings = new Settings(this);
mail = new MailServiceImpl(this);
userMap = new UserMap(this);
userMap = new ModernUserMap(this);
balanceTop = new BalanceTopImpl(this);
permissionsHandler = new PermissionsHandler(this, false);
Economy.setEss(this);
Expand Down Expand Up @@ -301,11 +304,14 @@ public void onEnable() {
confList.add(settings);
execTimer.mark("Settings");

upgrade.preModules();
execTimer.mark("Upgrade2");

mail = new MailServiceImpl(this);
execTimer.mark("Init(Mail)");

userMap = new UserMap(this);
confList.add(userMap);
userMap = new ModernUserMap(this);
legacyUserMap = new UserMap(userMap);
execTimer.mark("Init(Usermap)");

balanceTop = new BalanceTopImpl(this);
Expand All @@ -317,7 +323,7 @@ public void onEnable() {
execTimer.mark("Kits");

upgrade.afterSettings();
execTimer.mark("Upgrade2");
execTimer.mark("Upgrade3");

warps = new Warps(this.getDataFolder());
confList.add(warps);
Expand Down Expand Up @@ -588,7 +594,7 @@ public void onDisable() {

Economy.setEss(null);
Trade.closeLog();
getUserMap().getUUIDMap().shutdown();
getUsers().shutdown();

HandlerList.unregisterAll(this);
}
Expand Down Expand Up @@ -1067,7 +1073,7 @@ public User getUser(final Player base) {
if (getSettings().isDebug()) {
LOGGER.log(Level.INFO, "Constructing new userfile from base player " + base.getName());
}
user = new User(base, this);
user = userMap.loadUncachedUser(base);
} else {
user.update(base);
}
Expand Down Expand Up @@ -1203,7 +1209,13 @@ public IItemDb getItemDb() {
}

@Override
@Deprecated
public UserMap getUserMap() {
return legacyUserMap;
}

@Override
public ModernUserMap getUsers() {
return userMap;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ public void delayedJoin(final Player player, final String message) {

ess.getBackup().onPlayerJoin();
final User dUser = ess.getUser(player);
dUser.update(player);

dUser.startTransaction();
if (dUser.isNPC()) {
Expand Down Expand Up @@ -367,7 +368,7 @@ public void run() {
} else if (ess.getSettings().isCustomJoinMessage()) {
final String msg = (newUsername ? ess.getSettings().getCustomNewUsernameMessage() : ess.getSettings().getCustomJoinMessage())
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()))
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUsers().getUserCount()))
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()))
.replace("{PREFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(player)))
Expand Down Expand Up @@ -527,6 +528,7 @@ public void onPlayerLoginBanned(final PlayerLoginEvent event) {
public void onPlayerLogin(final PlayerLoginEvent event) {
if (event.getResult() == Result.KICK_FULL) {
final User kfuser = ess.getUser(event.getPlayer());
kfuser.update(event.getPlayer());
if (kfuser.isAuthorized("essentials.joinfullserver")) {
event.allow();
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import com.earth2me.essentials.config.EssentialsConfiguration;
import com.earth2me.essentials.config.EssentialsUserConfiguration;
import com.earth2me.essentials.craftbukkit.BanLookup;
import com.earth2me.essentials.userstorage.ModernUUIDCache;
import com.earth2me.essentials.utils.StringUtil;
import com.google.common.base.Charsets;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.google.gson.reflect.TypeToken;
import net.ess3.api.IEssentials;
Expand All @@ -31,10 +31,10 @@
import java.math.BigInteger;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
Expand All @@ -47,13 +47,12 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.earth2me.essentials.I18n.tl;

public class EssentialsUpgrade {
private static final FileFilter YML_FILTER = pathname -> pathname.isFile() && pathname.getName().endsWith(".yml");
public static final FileFilter YML_FILTER = pathname -> pathname.isFile() && pathname.getName().endsWith(".yml");
private static final String PATTERN_CONFIG_UUID_REGEX = "(?mi)^uuid:\\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\s*$";
private static final Pattern PATTERN_CONFIG_UUID = Pattern.compile(PATTERN_CONFIG_UUID_REGEX);
private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$";
Expand Down Expand Up @@ -93,7 +92,6 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF
final int showProgress = countFiles % 250;

if (showProgress == 0) {
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
ess.getLogger().info("Converted " + countFiles + "/" + userdir.list().length);
}

Expand All @@ -103,7 +101,8 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF
final EssentialsUserConfiguration config;
UUID uuid = null;
try {
uuid = UUID.fromString(name);
//noinspection ResultOfMethodCallIgnored
UUID.fromString(name);
} catch (final IllegalArgumentException ex) {
final File file = new File(userdir, string);
final EssentialsConfiguration conf = new EssentialsConfiguration(file);
Expand All @@ -115,38 +114,40 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF

final String uuidString = conf.getString(uuidConf, null);

//noinspection ConstantConditions
for (int i = 0; i < 4; i++) {
try {
uuid = UUID.fromString(uuidString);
countEssCache++;
break;
} catch (final Exception ex2) {
if (conf.getBoolean("npc", false)) {
uuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
uuid = UUID.nameUUIDFromBytes(("NPC:" + (ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name)).getBytes(Charsets.UTF_8));
break;
}

final org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
uuid = player.getUniqueId();
}

//noinspection ConstantConditions
if (uuid != null) {
countBukkit++;
break;
}
}

//noinspection ConstantConditions
if (uuid != null) {
conf.blockingSave();
config = new EssentialsUserConfiguration(name, uuid, new File(userdir, uuid + ".yml"));
config.convertLegacyFile();
ess.getUserMap().trackUUID(uuid, name, false);
ess.getUsers().loadUncachedUser(uuid);
continue;
}
countFails++;
}
}
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();

ess.getLogger().info("Converted " + countFiles + "/" + countFiles + ". Conversion complete.");
ess.getLogger().info("Converted via cache: " + countEssCache + " :: Converted via lookup: " + countBukkit + " :: Failed to convert: " + countFails);
Expand Down Expand Up @@ -913,74 +914,76 @@ private void updateBan(final String playerName, final String banReason, final Lo
Bukkit.getBanList(BanList.Type.NAME).addBan(playerName, banReason, banTimeout == 0 ? null : new Date(banTimeout), Console.NAME);
}

private void repairUserMap() {
if (doneFile.getBoolean("userMapRepaired", false)) {
public void generateUidCache() {
if (doneFile.getBoolean("newUidCacheBuilt", false)) {
return;
}
ess.getLogger().info("Starting usermap repair");

final File usermapFile = new File(ess.getDataFolder(), "usermap.bin");
final File uidsFile = new File(ess.getDataFolder(), "uuids.bin");
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
if (!userdataFolder.isDirectory()) {

if (!userdataFolder.isDirectory() || usermapFile.exists() || uidsFile.exists()) {
ess.getLogger().warning("Missing userdata folder, aborting");
doneFile.setProperty("newUidCacheBuilt", true);
doneFile.save();
return;
}
final File[] files = userdataFolder.listFiles(YML_FILTER);

final DecimalFormat format = new DecimalFormat("#0.00");
final Map<String, UUID> names = Maps.newHashMap();
try {
if (!usermapFile.createNewFile() || !uidsFile.createNewFile()) {
ess.getLogger().warning("Couldn't create usermap.bin or uuids.bin, aborting");
return;
}

for (int index = 0; index < files.length; index++) {
final File file = files[index];
try {
UUID uuid = null;
final String filename = file.getName();
final String configData = new String(java.nio.file.Files.readAllBytes(file.toPath()), Charsets.UTF_8);
final Map<UUID, Long> uuids = new HashMap<>();
final Map<String, UUID> nameToUuidMap = new HashMap<>();

if (filename.length() > 36) {
final File[] files = userdataFolder.listFiles(YML_FILTER);
if (files != null) {
for (final File file : files) {
try {
// ".yml" ending has 4 chars...
uuid = UUID.fromString(filename.substring(0, filename.length() - 4));
} catch (final IllegalArgumentException ignored) {
}
}

final Matcher uuidMatcher = PATTERN_CONFIG_UUID.matcher(configData);
if (uuidMatcher.find()) {
try {
uuid = UUID.fromString(uuidMatcher.group(1));
} catch (final IllegalArgumentException ignored) {
}
}

if (uuid == null) {
// Don't import
continue;
}

final Matcher nameMatcher = PATTERN_CONFIG_NAME.matcher(configData);
if (nameMatcher.find()) {
final String username = nameMatcher.group(1);
if (username != null && username.length() > 0) {
names.put(StringUtil.safeString(username), uuid);
final String fileName = file.getName();
final UUID uuid = UUID.fromString(fileName.substring(0, fileName.length() - 4));
final EssentialsConfiguration config = new EssentialsConfiguration(file);
config.load();
String name = config.getString("last-account-name", null);
name = ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name;
final long time = config.getLong("timestamps.logout", 0L);

if (name != null) {
if (nameToUuidMap.containsKey(name)) {
final UUID oldUuid = nameToUuidMap.get(name);
if (oldUuid.version() < uuid.version() || (oldUuid.version() == uuid.version() && uuids.get(oldUuid) < time)) {
ess.getLogger().warning("New UUID found for " + name + ": " + uuid + " (old: " + oldUuid + "). Replacing.");
uuids.remove(oldUuid);
} else {
ess.getLogger().warning("Found UUID for " + name + ": " + uuid + " (old: " + oldUuid + "). Skipping.");
continue;
}
}

uuids.put(uuid, config.getLong("timestamps.logout", 0L));
nameToUuidMap.put(name, uuid);
}
} catch (IllegalArgumentException | IndexOutOfBoundsException ignored) {
}
}
}

if (index % 1000 == 0) {
ess.getLogger().info("Reading: " + format.format((100d * (double) index) / files.length)
+ "%");
}
} catch (final IOException e) {
ess.getLogger().log(Level.SEVERE, "Error while reading file: ", e);
return;
if (!nameToUuidMap.isEmpty()) {
ModernUUIDCache.writeNameUuidMap(usermapFile, nameToUuidMap);
}
}

ess.getUserMap().getNames().putAll(names);
ess.getUserMap().reloadConfig();
if (!uuids.isEmpty()) {
ModernUUIDCache.writeUuidCache(uidsFile, uuids.keySet());
}

doneFile.setProperty("userMapRepaired", true);
doneFile.save();
ess.getLogger().info("Completed usermap repair.");
doneFile.setProperty("newUidCacheBuilt", true);
doneFile.save();
} catch (final IOException e) {
ess.getLogger().log(Level.SEVERE, "Error while generating initial uuids/names cache", e);
}
}

public void beforeSettings() {
Expand All @@ -991,6 +994,10 @@ public void beforeSettings() {
moveMotdRulesToFile("rules");
}

public void preModules() {
generateUidCache();
}

public void afterSettings() {
sanitizeAllUserFilenames();
updateUsersPowerToolsFormat();
Expand All @@ -1001,7 +1008,6 @@ public void afterSettings() {
uuidFileChange();
banFormatChange();
warnMetrics();
repairUserMap();
convertIgnoreList();
convertStupidCamelCaseUserdataKeys();
convertMailList();
Expand Down
Loading