Skip to content

Paper 26: async spawn rescue, Paper API build, DummyChunk, and WorldEdit-safe command init#373

Open
rkfsociety wants to merge 3 commits intoJikoo:masterfrom
rkfsociety:master
Open

Paper 26: async spawn rescue, Paper API build, DummyChunk, and WorldEdit-safe command init#373
rkfsociety wants to merge 3 commits intoJikoo:masterfrom
rkfsociety:master

Conversation

@rkfsociety
Copy link
Copy Markdown

This branch contains two logical changes (two commits).

1) Paper 26 spawn / rescue + build + DummyChunk

  • Replace deprecated PlayerSpawnLocationEvent with AsyncPlayerSpawnLocationEvent in RescueListener.
  • Run world/chunk work on the main thread using BukkitScheduler#callSyncMethod.
  • Feature marker on disk: read via offline player PDC view; write deferred with runTask after the Player exists (same intent as before).
  • Use OfflinePlayer#getRespawnLocation(true) for respawn-based rescue.
  • Compile against io.papermc.paper:paper-api 26.1.2.build.60-stable (the 26.1.2-R0.1-SNAPSHOT coordinate is not on Paper’s Maven).
  • Update DummyChunk for the current Chunk API (getLoadLevel, isGenerated, getStructures, getPlayersSeeingChunk, four-arg getChunkSnapshot, getTileEntities overloads) and fix isLoaded() (chunkX / chunkZ).

2) WorldEdit classpath / load order

  • FlagHandler pulls in WorldEdit types. Creating it from RegioneratorExecutor during onEnable could run before WorldEdit finished enabling and triggered NoClassDefFoundError for com.sk89q.worldedit.session.SessionOwner.
  • Fix: lazy FlagHandler creation on first /regionerator flag or unflag, and add WorldEdit to plugin.yml softdepend.

rkfsociety added 2 commits May 4, 2026 19:26
Replace deprecated PlayerSpawnLocationEvent; run world access on the main
thread via callSyncMethod. Compile against paper-api 26.1.2.build.60-stable.
Update DummyChunk for current Chunk API (load level, structures, tile
entities, four-arg chunk snapshot).
Defer FlagHandler construction until first flag/unflag command so WorldEdit
classes (e.g. SessionOwner) are on the classpath. Add WorldEdit to plugin
softdepend for ordering when Bukkit resolves dependencies.
Copy link
Copy Markdown
Owner

@Jikoo Jikoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: WorldEdit - WG depends on WE, so this should not be an issue unless you have dependency loops entirely breaking load order. You should probably check your other plugins if you're having problems.
If you are interested in fixing the problems with it, please submit it as a separate PR.

Re: AsyncPlayerSpawnLocationEvent: I'm not interested in dropping Spigot compatibility. I would be fine with a Spigot and Paper module, but I am not interested in an AI PR doing the required modularization because I would probably go insane wasting the time reviewing that much weird code.

In general, please try to actually look at what your AI did.

Comment on lines +57 to +67
FlagHandler local = this.flagHandler;
if (local == null) {
synchronized (this) {
local = this.flagHandler;
if (local == null) {
local = new FlagHandler(this.plugin);
this.flagHandler = local;
}
}
}
return local;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locking is not really necessary here. Commands are processed on the main thread. Even if they weren't (i.e. maybe Folia, which also isn't supported because we use the regular Bukkit scheduler), the odds of two players just so happening to execute commands both requiring a flag handler at the same exact time are incredibly small.

I'm way more concerned with the fact that AI thinks using a publicly-accessible instance for a lock is a good idea. Good lord.

Comment on lines +43 to +47
/**
* Lazily created: {@link FlagHandler} touches WorldEdit types. If we construct it from
* {@link Regionerator#onEnable()} before WorldEdit has enabled, {@code SessionOwner} etc. are not
* visible yet and the plugin fails with {@link NoClassDefFoundError}.
*/
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer docs on the method to the field.

* {@link Regionerator#onEnable()} before WorldEdit has enabled, {@code SessionOwner} etc. are not
* visible yet and the plugin fails with {@link NoClassDefFoundError}.
*/
private volatile @Nullable FlagHandler flagHandler;
Copy link
Copy Markdown
Owner

@Jikoo Jikoo May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Volatile and a lock? Unnecessary, I would drop the keyword.
/e: Ah, it is necessary due to how the AI set it up. Eugh.

Comment on lines -55 to -59
Player player = event.getPlayer();
// Check if the player has logged in since this feature was added.
PersistentDataContainer playerPdc = player.getPersistentDataContainer();
if (!playerPdc.has(loggedInSinceFeature, PersistentDataType.BYTE)) {
playerPdc.set(loggedInSinceFeature, PersistentDataType.BYTE, (byte) 1);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick returns before incurring a scheduler hit should be re-added. PDC logic does not need to wait for main thread.

Chunk chunk = spawnLoc.getChunk();
PersistentDataContainer chunkPdc = chunk.getPersistentDataContainer();
NamespacedKey logoutKey = getLogoutKey(player.getUniqueId());
// If the key is set, the chunk has not been deleted since the player last logged out.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't delete existing comments.

…aper-only API

Restore spigot-api build, revert Chunk API changes, and remove WorldEdit load-order workaround from this PR. Register Paper AsyncPlayerSpawnLocationEvent handler via reflection when available while keeping PlayerSpawnLocationEvent for Spigot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants