Skip to content

fix: support new world / dimension directory structure and fix per-world plots - #4874

Open
PierreSchwang wants to merge 16 commits into
mainfrom
fix/tinyTakeoverDimensions
Open

fix: support new world / dimension directory structure and fix per-world plots#4874
PierreSchwang wants to merge 16 commits into
mainfrom
fix/tinyTakeoverDimensions

Conversation

@PierreSchwang

Copy link
Copy Markdown
Member

Overview

Fixes #4872

Description

MC 26 changed the world /dimension / level folder structure quite drastically, which this PR attempts to implement. Trim works in the latest version. I also updated all other usages of I/O world access. download of world files should also work now (even though it's been deprecated for quite a while).

I've not tested the changes on older versions yet. Feel free to.

Submitter Checklist

  • Make sure you are opening from a topic branch (/feature/fix/docs/ branch (right side)) and not your main branch.
  • Ensure that the pull request title represents the desired changelog entry.
  • New public fields and methods are annotated with @since TODO.
  • I read and followed the contribution guidelines.

@PierreSchwang
PierreSchwang requested a review from a team as a code owner May 24, 2026 13:36
@PierreSchwang
PierreSchwang force-pushed the fix/tinyTakeoverDimensions branch from 70d3cb1 to eac6a4f Compare May 24, 2026 14:13
@NotMyFault NotMyFault added the Bugfix This PR fixes a bug label Jun 4, 2026
@NotMyFault

Copy link
Copy Markdown
Member

@NO-UUID can you verify this resolves your issue?

@NO-UUID

NO-UUID commented Jun 4, 2026

Copy link
Copy Markdown
> p trim world
[17:41:51 ERROR]: [PlotSquared/MainCommand] A error occurred while executing plot command
java.lang.RuntimeException: Could not find regions folder: ./worlds/world/dimensions/minecraft/world/region ? (no read access?)
        at PlotSquared-Bukkit.jar//com.plotsquared.core.util.WorldUtil.getChunkChunks(WorldUtil.java:370) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.bukkit.util.BukkitUtil.getChunkChunks(BukkitUtil.java:566) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.core.command.Trim.getTrimRegions(Trim.java:97) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.core.command.Trim.onCommand(Trim.java:142) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.core.command.SubCommand.execute(SubCommand.java:50) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.core.command.Command.execute(Command.java:374) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.core.command.MainCommand.lambda$execute$1(MainCommand.java:250) ~[?:?]
        at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1208) ~[?:?]
        at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2368) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.core.command.MainCommand.execute(MainCommand.java:244) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.core.command.MainCommand.onCommand(MainCommand.java:184) ~[?:?]
        at PlotSquared-Bukkit.jar//com.plotsquared.bukkit.BukkitCommand.onCommand(BukkitCommand.java:54) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[paper-api-26.1.2.build.69-stable.jar:?]
        at io.papermc.paper.command.brigadier.bukkit.BukkitCommandNode$BukkitBrigCommand.run(BukkitCommandNode.java:83) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at com.mojang.brigadier.context.ContextChain.runExecutable(ContextChain.java:73) ~[brigadier-1.3.10.jar:?]
        at net.minecraft.commands.execution.tasks.ExecuteCommand.execute(ExecuteCommand.java:30) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.execution.tasks.ExecuteCommand.execute(ExecuteCommand.java:13) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.execution.UnboundEntryAction.lambda$bind$0(UnboundEntryAction.java:8) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.execution.CommandQueueEntry.execute(CommandQueueEntry.java:5) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.execution.ExecutionContext.runCommandQueue(ExecutionContext.java:104) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.Commands.executeCommandInContext(Commands.java:468) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.Commands.performCommand(Commands.java:376) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.Commands.performCommand(Commands.java:364) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.commands.Commands.performPrefixedCommand(Commands.java:355) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.dedicated.DedicatedServer.handleConsoleInputs(DedicatedServer.java:622) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.dedicated.DedicatedServer.tickConnection(DedicatedServer.java:578) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1862) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1645) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.dedicated.DedicatedServer.tickServer(DedicatedServer.java:444) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.MinecraftServer.processPacketsAndTick(MinecraftServer.java:1703) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1373) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:304) ~[paper-26.1.2.jar:26.1.2-69-76d2ac7]
        at java.base/java.lang.Thread.run(Thread.java:1474) ~[?:?]
[17:41:51 INFO]: [P2] An error occurred: Could not find regions folder: ./worlds/world/dimensions/minecraft/world/region ? (no read access?)

while the actual folder p2 is looking for is:

/home/minecraft/creative/worlds/buildtest/dimensions/minecraft/world/region

server.properties:

level-name=buildtest
level-seed=
level-type=minecraft\:normal

bukkit.yml

# This is the Bukkit configuration file in Paper.
# As you can see, there's actually not that much to configure without any plugins.
#
# If you need help with the configuration or have any questions related to Paper,
# join us in our Discord or check the docs page.
#
# File Reference: https://docs.papermc.io/paper/reference/bukkit-configuration/
# Docs: https://docs.papermc.io/
# Discord: https://discord.gg/papermc
# Website: https://papermc.io/

settings:
  use-map-color-cache: true
  allow-end: false
  warn-on-overload: true
  permissions-file: permissions.yml
  update-folder: update
  plugin-profiling: false
  connection-throttle: 4000
  query-plugins: false
  deprecated-verbose: default
  shutdown-message: Server closed for few minutes for a maintenance.
  minimum-api: none
  world-container: ./worlds/
spawn-limits:
  axolotls: 0
  water-underground-creature: 0
  water-ambient: 0
  monsters: 0
  animals: 0
  water-animals: 0
  ambient: 0
chunk-gc:
  period-in-ticks: 600
ticks-per:
  axolotl-spawns: 1
  water-underground-creature-spawns: 1
  water-ambient-spawns: 50
  animal-spawns: 300
  monster-spawns: 50
  water-spawns: 50
  ambient-spawns: 50
  autosave: 6000
aliases: now-in-commands.yml
worlds:
  world:
    generator: PlotSquared
  buildtest:
    generator: PlotSquared
  test:
    generator: PlotSquared
  'true':
    generator: PlotSquared
  scbuilds:
    generator: PlotSquared

@NO-UUID

NO-UUID commented Jun 4, 2026

Copy link
Copy Markdown

So I guess it would work with just world-container: ./worlds/ but not with level-name=buildtest ?

@NO-UUID

NO-UUID commented Jun 5, 2026

Copy link
Copy Markdown

Actually no, even after changing level-name to world in server.properties, it would still error:

[09:03:01 INFO]: [P2] An error occurred: Could not find regions folder: ./worlds/world/dimensions/minecraft/world/region ? (no read access?)

and in this case
/worlds/world/dimensions/minecraft/world/region

should be
/worlds/world/dimensions/minecraft/overworld/region

> mv info world
[09:07:49 INFO]: ---- World Info: world ----
[09:07:49 INFO]: World Key: minecraft:overworld
[09:07:49 INFO]: World Name: world
[09:07:49 INFO]: World Alias: empty

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates PlotSquared’ world file I/O to support Minecraft 26.1’s changed world/dimension directory layout (fixing trim failures like “could not find region folder”), and migrates several code paths from java.io.File to java.nio.file.Path.

Changes:

  • Add platform APIs for resolving dimension/world paths (getWorldContainer, getWorldPath) and update Bukkit implementation.
  • Update world/region file discovery and deletion to use NIO (Files.*) and the new directory structure.
  • Adjust legacy world upload/import/conversion utilities to operate on the new paths.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
Core/src/main/java/com/plotsquared/core/util/WorldUtil.java Updates region traversal and world download zip creation to use NIO + new layout.
Core/src/main/java/com/plotsquared/core/util/RegionManager.java Updates region file deletion to use Path/Files.
Core/src/main/java/com/plotsquared/core/util/CloseShieldOutputStream.java Adds output stream wrapper to prevent closing an underlying stream.
Core/src/main/java/com/plotsquared/core/PlotPlatform.java Introduces new platform APIs to resolve dimension/world paths.
Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java Changes single-plot world deletion to NIO.
Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotArea.java Updates single-plot world migration/copy logic to NIO.
Core/src/main/java/com/plotsquared/core/command/DebugImportWorlds.java Updates debug import to walk the world container via NIO.
Core/src/main/java/com/plotsquared/core/command/DatabaseCommand.java Updates single-plot world rename during DB import to Files.move.
Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java Implements the new platform path resolution methods for Bukkit.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Core/src/main/java/com/plotsquared/core/util/WorldUtil.java Outdated
Comment thread Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java Outdated
Comment thread Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/command/DebugImportWorlds.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/util/RegionManager.java
@PierreSchwang

Copy link
Copy Markdown
Member Author

No clue how I should get the actual level key by the world name (as those are two co-existing things now???), given I don't have any world reference at many places. The underlying platform world would return a NamespacedKey / Key / whatever API definition exists, but I only have the user inputted name or plot world string, which might not be loaded in bukkit at the point of usage...

@NonSwag

NonSwag commented Jun 6, 2026

Copy link
Copy Markdown

Technically there is no need to get the key from the loaded world as it will always be that of the dimension folder names
Example: /world/dimension/custom/farmworld would always have the key custom:farmworld
But be aware that worlds can also have paths inside the namespace value e.g. custom:farmworld/nether which would be located at /world/dimension/custom/farmworld/nether

@NO-UUID

NO-UUID commented Jul 6, 2026

Copy link
Copy Markdown

I think both will exist at least for some time?

If word is defined (with generator) in bukkit.yml it should be available right away? I think?

@NO-UUID

NO-UUID commented Jul 6, 2026

Copy link
Copy Markdown

Also I think this affects more than just trim? Road regen and stuff like that too?

Comment thread Core/src/main/java/com/plotsquared/core/util/WorldUtil.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/PlotPlatform.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/PlotPlatform.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/PlotPlatform.java Outdated
Comment thread Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/util/WorldUtil.java Outdated
Comment thread Core/src/main/java/com/plotsquared/core/util/WorldUtil.java Outdated
@PierreSchwang
PierreSchwang force-pushed the fix/tinyTakeoverDimensions branch from e441942 to d678c86 Compare July 26, 2026 12:11
@PierreSchwang

Copy link
Copy Markdown
Member Author

@NO-UUID Feel free to test with the recent updates. I haven't tested everything but my first tests were fine so far. Haven't yet tested pre-26.1 either, but I'll do that when it works for the newer version ig.

@PierreSchwang PierreSchwang changed the title fix: support new world / dimension directory structure fix: support new world / dimension directory structure and fix per-world plots Jul 26, 2026
@NO-UUID

NO-UUID commented Jul 26, 2026

Copy link
Copy Markdown

So far so good, this fixed:

/p debugroadregen plot
/p trim <world>

Tested on:

> ver
[23:25:58 INFO]: Checking version, please wait...
[23:25:58 INFO]: This server is running Paper version 26.1.2-74-ver/26.1.2@e4e17fc (2026-07-06T16:51:09Z) (Implementing API version 26.1.2.build.74-stable)
You are running the latest version
Previous version: 26.1.2-72-1a6b910 (MC: 26.1.2)

@NO-UUID

NO-UUID commented Jul 31, 2026

Copy link
Copy Markdown

So far so good, been running it on 4 different Paper instances (with different configs) and everything appears to be working.

Edit: All running Paper 26.1.2

@PierreSchwang

Copy link
Copy Markdown
Member Author

So far so good, been running it on 4 different Paper instances (with different configs) and everything appears to be working.

Edit: All running Paper 26.1.2

Thank you for the extensive testing!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java:85

  • Files.walkFileTree(path, …) will throw (and log an error) if the plot world folder doesn't exist (e.g., already deleted or never created). Adding an existence check avoids noisy error logs for a non-fatal condition.
            try {
                Files.walkFileTree(path, RecursiveDirectoryRemovalWalker.INSTANCE);
            } catch (IOException e) {
                LOGGER.error("Failed to delete plot world for single plot area", e);

Comment thread Core/src/main/java/com/plotsquared/core/util/WorldUtil.java Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@PierreSchwang

Copy link
Copy Markdown
Member Author

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Suppressed comments (1)
Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java:85

  • Files.walkFileTree(path, …) will throw (and log an error) if the plot world folder doesn't exist (e.g., already deleted or never created). Adding an existence check avoids noisy error logs for a non-fatal condition.
            try {
                Files.walkFileTree(path, RecursiveDirectoryRemovalWalker.INSTANCE);
            } catch (IOException e) {
                LOGGER.error("Failed to delete plot world for single plot area", e);

the method would throw much earlier given accessing the platform world and unloading the world would fail. Also, administrators shouldn't touch plot worlds themselves (especially during runtime).

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

Labels

Bugfix This PR fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Trimming still not working

6 participants