Skip to content

Commit 28afc6a

Browse files
authored
Merge branch '2.x' into mc/26.2
2 parents 4d0b847 + 15ec9a2 commit 28afc6a

10 files changed

Lines changed: 85 additions & 15 deletions

File tree

.github/workflows/mirror-dump.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121

2222
steps:
2323
- name: Mirror dump to a private Gist
24+
id: mirror
2425
uses: actions/github-script@v7
2526
with:
2627
github-token: ${{ secrets.GIST_TOKEN }}
@@ -46,13 +47,19 @@ jobs:
4647
public: false
4748
});
4849
49-
const link = `${process.env.GIST_LINK_FMT}${gist.id}`;
50+
core.setOutput('link', `${process.env.GIST_LINK_FMT}${gist.id}`);
51+
core.setOutput('issue_number', issue.number);
5052
53+
- name: Comment gist link on issue
54+
if: steps.mirror.outputs.link != ''
55+
uses: actions/github-script@v7
56+
with:
57+
script: |
5158
await github.rest.issues.createComment({
5259
owner: context.repo.owner,
5360
repo: context.repo.repo,
54-
issue_number: issue.number,
55-
body: `📋 Essentials Dump Backup → ${link}`
61+
issue_number: ${{ steps.mirror.outputs.issue_number }},
62+
body: `📋 Essentials Dump Backup → ${{ steps.mirror.outputs.link }}`
5663
});
5764
5865
cleanup-gist:

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.earth2me.essentials.updatecheck.UpdateChecker;
4747
import com.earth2me.essentials.userstorage.ModernUserMap;
4848
import com.earth2me.essentials.utils.FormatUtil;
49+
import com.earth2me.essentials.utils.PasteUtil;
4950
import com.earth2me.essentials.utils.VersionUtil;
5051
import io.papermc.lib.PaperLib;
5152
import net.ess3.api.Economy;
@@ -587,6 +588,8 @@ public void onDisable() {
587588
getUsers().shutdown();
588589

589590
EssentialsConfiguration.shutdownExecutor();
591+
PasteUtil.shutdownExecutor();
592+
getServer().getScheduler().cancelTasks(this);
590593

591594
HandlerList.unregisterAll(this);
592595
}
@@ -620,7 +623,9 @@ private void initAdventureFacet() {
620623
adventureFacet.close();
621624
}
622625

623-
if (VersionUtil.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_5_R01)) {
626+
// Paper only started bundling a modern enough native Adventure (with the MiniMessage TagResolver API)
627+
// in 1.18.2, so older versions must continue using our bundled Adventure via the Spigot facet.
628+
if (VersionUtil.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_18_2_R01)) {
624629
adventureFacet = new PaperAdventureFacet(getSettings() != null ? getSettings().getPrimaryColor() : null, getSettings() != null ? getSettings().getSecondaryColor() : null);
625630
} else {
626631
adventureFacet = new SpigotAdventureFacet(this);

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@
2828
import java.util.concurrent.ConcurrentHashMap;
2929
import java.util.concurrent.ExecutorService;
3030
import java.util.concurrent.Executors;
31+
import java.util.concurrent.TimeUnit;
3132
import java.util.function.Function;
3233
import java.util.logging.Level;
3334
import java.util.regex.Pattern;
3435

3536
public class I18n implements net.ess3.api.II18n {
3637
private static final String MESSAGES = "messages";
3738
private static final Pattern NODOUBLEMARK = Pattern.compile("''");
38-
private static final ExecutorService BUNDLE_LOADER_EXECUTOR = Executors.newFixedThreadPool(2);
39+
private static volatile ExecutorService BUNDLE_LOADER_EXECUTOR = Executors.newFixedThreadPool(2);
3940
private static final ResourceBundle NULL_BUNDLE = new ResourceBundle() {
4041
@SuppressWarnings("NullableProblems")
4142
public Enumeration<String> getKeys() {
@@ -106,6 +107,29 @@ public void onEnable() {
106107

107108
public void onDisable() {
108109
instance = null;
110+
shutdownExecutor();
111+
}
112+
113+
private static synchronized ExecutorService getExecutor() {
114+
if (BUNDLE_LOADER_EXECUTOR == null || BUNDLE_LOADER_EXECUTOR.isShutdown() || BUNDLE_LOADER_EXECUTOR.isTerminated()) {
115+
BUNDLE_LOADER_EXECUTOR = Executors.newFixedThreadPool(2);
116+
}
117+
return BUNDLE_LOADER_EXECUTOR;
118+
}
119+
120+
private static synchronized void shutdownExecutor() {
121+
final ExecutorService exec = BUNDLE_LOADER_EXECUTOR;
122+
if (exec == null) {
123+
return;
124+
}
125+
exec.shutdown();
126+
try {
127+
if (!exec.awaitTermination(5, TimeUnit.SECONDS)) {
128+
exec.shutdownNow();
129+
}
130+
} catch (final InterruptedException ignored) {
131+
exec.shutdownNow();
132+
}
109133
}
110134

111135
@Override
@@ -124,7 +148,7 @@ private ResourceBundle getBundle(final Locale locale) {
124148
synchronized (loadingBundles) {
125149
if (!loadingBundles.contains(locale)) {
126150
loadingBundles.add(locale);
127-
BUNDLE_LOADER_EXECUTOR.submit(() -> {
151+
getExecutor().submit(() -> {
128152
blockingLoadBundle(locale);
129153
synchronized (loadingBundles) {
130154
loadingBundles.remove(locale);

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,13 @@ public void parseStringMeta(final CommandSource sender, final boolean allowUnsaf
208208

209209
try {
210210
final String components = Joiner.on(' ').join(Arrays.asList(string).subList(fromArg, string.length));
211-
// modifyItemStack requires that the item namespaced key is prepended to the components for some reason
212-
stack = ess.getServer().getUnsafe().modifyItemStack(stack, stack.getType().getKey() + components);
211+
// From 1.20.6 through 1.21.11, modifyItemStack parses its argument as a full item string, so the item's
212+
// namespaced key must be prepended to the components. As of 26.1, the implementation prepends the item
213+
// key itself, so prepending it here would produce a malformed (double-namespaced) item string.
214+
final String itemString = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v26_1_R01)
215+
? components
216+
: stack.getType().getKey() + components;
217+
stack = ess.getServer().getUnsafe().modifyItemStack(stack, itemString);
213218
} catch (final NullPointerException npe) {
214219
if (ess.getSettings().isDebug()) {
215220
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);

Essentials/src/main/java/com/earth2me/essentials/adventure/SpigotAdventureFacet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public ComponentHolder deserializeMiniMessage(String message) {
7676

7777
@Override
7878
public String legacyToMini(String message) {
79-
return legacyToMini(message, true);
79+
return legacyToMini(message, false);
8080
}
8181

8282
@Override

Essentials/src/main/java/com/earth2me/essentials/commands/Commandtp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void run(final Server server, final User user, final String commandLabel,
5656
throw new NotEnoughArgumentsException(user.playerTl("teleportInvalidLocation"));
5757
}
5858
final Location locpos = new Location(user.getWorld(), x2, y2, z2, user.getLocation().getYaw(), user.getLocation().getPitch());
59-
user.getAsyncTeleport().now(locpos, false, TeleportCause.COMMAND, future);
59+
user.getAsyncTeleport().now(locpos, true, TeleportCause.COMMAND, future);
6060
future.thenAccept(success -> {
6161
if (success) {
6262
user.sendTl("teleporting", locpos.getWorld().getName(), locpos.getBlockX(), locpos.getBlockY(), locpos.getBlockZ());

Essentials/src/main/java/com/earth2me/essentials/perm/impl/LuckPermsHandler.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,13 @@ public List<String> getGroups() {
9393

9494
@Override
9595
public boolean isOfflinePermissionSet(UUID uuid, String node) {
96-
final net.luckperms.api.model.user.User user = this.luckPerms.getUserManager().loadUser(uuid).join();
96+
// Try to get the user from LuckPerms' cache first to avoid blocking the main
97+
// thread with a database lookup. In the context of a player join (e.g.
98+
// PlayerServerFullCheckEvent), the user should already be loaded.
99+
net.luckperms.api.model.user.User user = this.luckPerms.getUserManager().getUser(uuid);
100+
if (user == null) {
101+
user = this.luckPerms.getUserManager().loadUser(uuid).join();
102+
}
97103
if (user == null) {
98104
return false;
99105
}

Essentials/src/main/java/com/earth2me/essentials/utils/PasteUtil.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
import java.util.concurrent.CompletableFuture;
1717
import java.util.concurrent.ExecutorService;
1818
import java.util.concurrent.Executors;
19+
import java.util.concurrent.TimeUnit;
1920
import java.util.zip.GZIPOutputStream;
2021

2122
public final class PasteUtil {
2223
private static final String PASTE_URL = "https://pastes.dev/";
2324
private static final String PASTE_UPLOAD_URL = "https://api.pastes.dev/post";
24-
private static final ExecutorService PASTE_EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
25+
private static volatile ExecutorService PASTE_EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
2526
private static final Gson GSON = new Gson();
2627

2728
private PasteUtil() {
@@ -35,7 +36,7 @@ private PasteUtil() {
3536
*/
3637
public static CompletableFuture<PasteResult> createPaste(List<PasteFile> pages) {
3738
final CompletableFuture<PasteResult> future = new CompletableFuture<>();
38-
PASTE_EXECUTOR_SERVICE.submit(() -> {
39+
getExecutor().submit(() -> {
3940
try {
4041
final HttpURLConnection connection = (HttpURLConnection) new URL(PASTE_UPLOAD_URL).openConnection();
4142
connection.setRequestMethod("POST");
@@ -81,6 +82,28 @@ public static CompletableFuture<PasteResult> createPaste(List<PasteFile> pages)
8182
return future;
8283
}
8384

85+
private static synchronized ExecutorService getExecutor() {
86+
if (PASTE_EXECUTOR_SERVICE == null || PASTE_EXECUTOR_SERVICE.isShutdown() || PASTE_EXECUTOR_SERVICE.isTerminated()) {
87+
PASTE_EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
88+
}
89+
return PASTE_EXECUTOR_SERVICE;
90+
}
91+
92+
public static synchronized void shutdownExecutor() {
93+
final ExecutorService exec = PASTE_EXECUTOR_SERVICE;
94+
if (exec == null) {
95+
return;
96+
}
97+
exec.shutdown();
98+
try {
99+
if (!exec.awaitTermination(5, TimeUnit.SECONDS)) {
100+
exec.shutdownNow();
101+
}
102+
} catch (final InterruptedException ignored) {
103+
exec.shutdownNow();
104+
}
105+
}
106+
84107
public static class PasteFile {
85108
private final String name;
86109
private final String contents;

EssentialsChat/src/main/java/com/earth2me/essentials/chat/processing/AbstractChatHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ protected void handleChatRecipients(AbstractChatEvent event) {
225225
if (!spyEvent.isCancelled()) {
226226
final String legacyString = ess.getAdventureFacet().miniToLegacy(
227227
String.format(spyEvent.getFormat(),
228-
ess.getAdventureFacet().legacyToMini(user.getDisplayName()) + "<reset>",
228+
ess.getAdventureFacet().legacyToMini(user.getDisplayName()),
229229
ess.getAdventureFacet().legacyToMiniWithUrls(ess.getAdventureFacet().escapeTags(spyEvent.getMessage()))));
230230

231231
for (final Player onlinePlayer : spyEvent.getRecipients()) {

providers/PaperProvider/src/main/java/com/earth2me/essentials/adventure/PaperAdventureFacet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public void send(Player player, ComponentHolder component) {
7676

7777
@Override
7878
public String legacyToMini(String message) {
79-
return legacyToMini(message, true);
79+
return legacyToMini(message, false);
8080
}
8181

8282
@Override

0 commit comments

Comments
 (0)