Skip to content

world: type ChunkProviderServer.chunksToUnload as java.util.Set again - #215

Open
EverNife wants to merge 1 commit into
stagingfrom
fix/chunks-to-unload-set
Open

EverNife wants to merge 1 commit into
stagingfrom
fix/chunks-to-unload-set

Conversation

@EverNife

Copy link
Copy Markdown
Member

Problem

Fixes #189. Crucible's ChunkProviderServer patch changed chunksToUnload (field_73248_b) from java.util.Set to CraftBukkit's LongHashSet. Any mod that expects Forge's type breaks. Lumi, for example, crashes at boot with InvalidMixinException: @Shadow field field_73248_b was not located, because a mixin @Shadow matches the field by name and descriptor (Ljava/util/Set;).

LongHashSet can't just implement Set: its toArray() returns long[], which clashes with Set.toArray(). Its keys are also different. Forge keys the set by ChunkCoordIntPair.chunkXZ2Int(x, z), while LongHashSet uses LongHash.toLong(x, z). So a mod calling contains(chunkXZ2Int(x, z)) would get the wrong answer even if the type matched.

Change

  • New io.github.crucible.util.ChunkKeySet, an AbstractSet<Long> backed by the same LongHashSet as before. The Set<Long> methods (add, contains, remove, iterator, including Iterator.remove) take and return vanilla chunkXZ2Int keys and convert them to LongHash internally. Objects that aren't a Long are ignored, like any Set<Long> does.
  • The (x, z) overloads and popFirst() stay unboxed and in LongHash encoding. That's the path Crucible's own code uses, so the unload loop performs the same as before.
  • ChunkProviderServer declares public Set chunksToUnload again. A new public final ChunkKeySet unloadQueue field points at the same object, and Crucible's callers (ChunkProviderServer, WorldServer, CauldronHooks, CraftWorld) use it.

Code compiled against the old LongHashSet chunksToUnload field needs to switch to unloadQueue. Nothing in this repo still references the old type.

Testing

A minimal coremod with a mixin in Lumi's shape (@Shadow private Set chunksToUnload), loaded through UniMixins 0.3.1. On the first unloadQueuedChunks it queues a far chunk through unloadChunksIfNotNearSpawn and then exercises the field only through java.util.Set with vanilla keys:

Build Result
before this PR crash: InvalidMixinException: @Shadow field field_73248_b was not located in the target class, the same as the issue's report
this PR boots; all checks pass: a chunk queued by the server is visible via contains, the iterator yields the vanilla key, remove/add by key, Iterator.remove, size, and a non-Long argument is ignored

Lumi itself was not run.

Mixins that shadow the field (Lumi) need the Forge descriptor. The
Set view speaks vanilla chunkXZ2Int keys; Crucible keeps the unboxed
LongHash path through the new unloadQueue field, the same object.

Fixes #189
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.

[BUG] Patch field type modification causing an incompatibility with code expecting the java.util.Set type

1 participant