Skip to content

MfFactionMapCommand reads sender.world off the main thread inside its async task #2020

Description

@dmccoystephenson

Summary

MfFactionMapCommand reads sender.world from inside the Runnable handed to runTaskAsynchronously, at src/main/kotlin/com/dansplugins/factionsystem/command/faction/map/MfFactionMapCommand.kt:65:

val map = renderMap(faction, mapType, sender.world, senderChunkX - 10, senderChunkZ - 4, senderChunkX + 10, senderChunkZ + 4)

The chunk coordinates immediately above it are handled correctly — sender.location.chunk is read at line 46, on the main thread, before dispatching, and only the resulting x/z ints cross into the task. The world reference was not given the same treatment.

Why it matters

Two consequences follow, mirroring the ones described in #2006:

  • The world is sampled at task time, not at command time. A player who changes world between issuing /faction map and the task running is rendered a map of claims in the world they arrived in, indexed by chunk coordinates taken from the world they left. The rendered grid is then a mix of two worlds and shows claims that are not where the player is standing.
  • The read itself is off-main-thread Bukkit API access. Player.getWorld() is not documented as thread-safe, and the returned World is passed straight into claimService.getClaim(world, x, z) for every cell of a 21x9 grid.

Suggested fix

Snapshot the world alongside the chunk coordinates that are already snapshotted, and have the task use the snapshotted reference:

val senderChunk = sender.location.chunk
val senderWorld = senderChunk.world
val senderChunkX = senderChunk.x
val senderChunkZ = senderChunk.z

That keeps the world and the coordinates consistent with one another, since both are then taken from the same Location read.

Provenance

This was noticed while surveying the command package for PR #2019, which closes #2006. It is not covered by that issue's inventory, so it was filed separately rather than folded into that changeset.


This issue was filed during a Gardener session (https://github.com/Stephenson-Software/gardener).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions