Skip to content

Commit adf77dc

Browse files
authored
Fix exception during first time joins (#6327)
Fixes an issue during first join with the player configuration events on Paper. The usermap will refuse to implicitly store new users into the usermap unless it can get a Bukkit player object for it, which is only created during the PlayerJoinEvent. So for new users, we must defer to then. The code that was being run (activity/mute checks) was probably incorrect to be placed inside of configure event anyway. Also force loads the locale bundle into memory to ensure it's ready for servers with slow i/o. Fixes #6315
1 parent 321c911 commit adf77dc

File tree

2 files changed

+49
-25
lines changed

2 files changed

+49
-25
lines changed

Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import java.util.Iterator;
8282
import java.util.List;
8383
import java.util.Locale;
84+
import java.util.Map;
8485
import java.util.Map.Entry;
8586
import java.util.Set;
8687
import java.util.UUID;
@@ -343,36 +344,54 @@ public void onPlayerQuit(final PlayerQuitEvent event) {
343344

344345
@SuppressWarnings("UnstableApiUsage")
345346
private final class JoinListener1_21 implements Listener {
347+
private final Map<UUID, String> newUserLocales = new ConcurrentHashMap<>();
348+
346349
@EventHandler
347350
public void onPlayerConfigure(final AsyncPlayerConnectionConfigureEvent event) {
348351
ess.getBackup().onPlayerJoin();
349352
final User dUser = ess.getUser(event.getConnection().getProfile().getId());
350353

351-
dUser.startTransaction();
352-
if (dUser.isNPC()) {
353-
dUser.setNPC(false);
354-
}
354+
// Force loading of the locale bundle while we are async to ensure it's ready when the player joins.
355+
final String locale = event.getConnection().getClientOption(ClientOption.LOCALE);
356+
ess.getI18n().blockingLoadBundle(I18n.getLocale(locale));
355357

356-
final long currentTime = System.currentTimeMillis();
357-
dUser.checkMuteTimeout(currentTime);
358-
dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN);
359-
dUser.stopTransaction();
358+
// This is a first time join, we have to wait until the bukkit Player object is created to create the User object.
359+
// So we store the locale here and apply it when the PlayerJoinEvent is fired.
360+
if (dUser == null) {
361+
newUserLocales.put(event.getConnection().getProfile().getId(), locale);
362+
return;
363+
}
360364

361365
// Set the locale for player to preload the language bundle.
362-
final String locale = event.getConnection().getClientOption(ClientOption.LOCALE);
363366
dUser.getPlayerLocale(locale);
364367
}
365368

366369
@EventHandler(priority = EventPriority.HIGHEST)
367370
public void onPlayerJoin(final PlayerJoinEvent event) {
368-
if (!ess.getUsers().isCached(event.getPlayer().getUniqueId())) {
371+
final User user = ess.getUser(event.getPlayer());
372+
if (user == null) {
369373
legacyJoinFlow(event);
370374
return;
371375
}
372376

373-
final User user = ess.getUser(event.getPlayer());
374377
user.update(event.getPlayer());
378+
379+
// If this is a new user, we set their locale that we stored earlier.
380+
final String locale = newUserLocales.remove(user.getUUID());
381+
if (locale != null) {
382+
user.getPlayerLocale(locale);
383+
}
384+
375385
final long currentTime = System.currentTimeMillis();
386+
user.startTransaction();
387+
if (user.isNPC()) {
388+
user.setNPC(false);
389+
}
390+
391+
user.checkMuteTimeout(currentTime);
392+
user.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN);
393+
user.stopTransaction();
394+
376395
joinFlow(user, currentTime, event.getJoinMessage(), event::setJoinMessage);
377396
}
378397
}
@@ -636,8 +655,7 @@ public void onPlayerLogin(final PlayerLoginEvent event) {
636655
private final class LoginListener1_21 implements Listener {
637656
@EventHandler(priority = EventPriority.HIGH)
638657
public void onPlayerListFull(final PlayerServerFullCheckEvent event) {
639-
final User user = ess.getUser(event.getPlayerProfile().getId());
640-
if (user.isAuthorized("essentials.joinfullserver")) {
658+
if (ess.getPermissionsHandler().isOfflinePermissionSet(event.getPlayerProfile().getId(), "essentials.joinfullserver")) {
641659
event.allow(true);
642660
return;
643661
}

Essentials/src/main/java/com/earth2me/essentials/I18n.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,7 @@ private ResourceBundle getBundle(final Locale locale) {
125125
if (!loadingBundles.contains(locale)) {
126126
loadingBundles.add(locale);
127127
BUNDLE_LOADER_EXECUTOR.submit(() -> {
128-
ResourceBundle bundle;
129-
try {
130-
bundle = ResourceBundle.getBundle(MESSAGES, locale, new FileResClassLoader(I18n.class.getClassLoader(), ess), new UTF8PropertiesControl());
131-
} catch (MissingResourceException ex) {
132-
try {
133-
bundle = ResourceBundle.getBundle(MESSAGES, locale, new UTF8PropertiesControl());
134-
} catch (MissingResourceException ex2) {
135-
bundle = NULL_BUNDLE;
136-
}
137-
}
138-
139-
loadedBundles.put(locale, bundle);
128+
blockingLoadBundle(locale);
140129
synchronized (loadingBundles) {
141130
loadingBundles.remove(locale);
142131
}
@@ -147,6 +136,23 @@ private ResourceBundle getBundle(final Locale locale) {
147136
}
148137
}
149138

139+
public void blockingLoadBundle(final Locale locale) {
140+
if (!loadedBundles.containsKey(locale)) {
141+
ResourceBundle bundle;
142+
try {
143+
bundle = ResourceBundle.getBundle(MESSAGES, locale, new FileResClassLoader(I18n.class.getClassLoader(), ess), new UTF8PropertiesControl());
144+
} catch (MissingResourceException ex) {
145+
try {
146+
bundle = ResourceBundle.getBundle(MESSAGES, locale, new UTF8PropertiesControl());
147+
} catch (MissingResourceException ex2) {
148+
bundle = NULL_BUNDLE;
149+
}
150+
}
151+
152+
loadedBundles.put(locale, bundle);
153+
}
154+
}
155+
150156
private String translate(final Locale locale, final String string) {
151157
try {
152158
try {

0 commit comments

Comments
 (0)