Skip to content

Commit c91d340

Browse files
authored
Merge pull request #260 from TheNextLvl-net/ver/1.21.9
1.21.9/10 support
2 parents 846c536 + a4fab19 commit c91d340

File tree

9 files changed

+82
-124
lines changed

9 files changed

+82
-124
lines changed

api/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ repositories {
2525
}
2626

2727
dependencies {
28-
compileOnly("io.papermc.paper:paper-api:1.21.9-pre2-R0.1-SNAPSHOT")
28+
compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
2929
compileOnly("net.thenextlvl:per-worlds:1.2.1")
3030

31-
testImplementation("io.papermc.paper:paper-api:1.21.9-pre2-R0.1-SNAPSHOT")
31+
testImplementation("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
3232
testImplementation("net.thenextlvl:nbt:3.0.1")
3333
testImplementation("org.junit.jupiter:junit-jupiter")
3434
testImplementation(platform("org.junit:junit-bom:6.1.0-SNAPSHOT"))

api/src/main/java/net/thenextlvl/worlds/api/level/Level.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ public interface Level extends Keyed {
110110
*/
111111
@Contract(pure = true)
112112
@Deprecated(forRemoval = true, since = "3.3.1")
113-
int getSpawnChunkRadius();
113+
default int getSpawnChunkRadius() {
114+
return 0;
115+
}
114116

115117
/**
116118
* Retrieves the seed value associated with this Level.
@@ -167,6 +169,7 @@ default Optional<World> create() {
167169
* <li>IllegalStateException: If the overworld hasn't been initialized yet,
168170
* or another world with the same {@link #getDirectory() directory} already exists</li>
169171
* <li>IllegalArgumentException: If the world {@link #key() key} or {@link #getName() name} is already in use</li>
172+
* <li>IOException: If the world could not be read</li>
170173
* </ul>
171174
*
172175
* @return a {@code CompletableFuture} completing with the created {@link World}
@@ -383,7 +386,9 @@ interface Builder {
383386
@Nullable
384387
@Contract(pure = true)
385388
@Deprecated(forRemoval = true, since = "3.3.1")
386-
Integer spawnChunkRadius();
389+
default Integer spawnChunkRadius() {
390+
return 0;
391+
}
387392

388393
/**
389394
* Sets the radius of chunks around the spawn point that should remain loaded.
@@ -396,7 +401,9 @@ interface Builder {
396401
*/
397402
@Contract(mutates = "this")
398403
@Deprecated(forRemoval = true, since = "3.3.1")
399-
Builder spawnChunkRadius(@Nullable Integer radius);
404+
default Builder spawnChunkRadius(@Nullable Integer radius) {
405+
return this;
406+
}
400407

401408
/**
402409
* Retrieves the world seed used for generation, if available.

build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ tasks.compileJava {
1919
}
2020

2121
group = "net.thenextlvl.worlds"
22-
version = "3.8.1"
22+
version = "3.9.0"
2323

2424
repositories {
2525
mavenCentral()
@@ -29,7 +29,8 @@ repositories {
2929
}
3030

3131
dependencies {
32-
paperweight.foliaDevBundle("1.21.8-R0.1-SNAPSHOT")
32+
// paperweight.foliaDevBundle("1.21.10-R0.1-SNAPSHOT") // fixme: restore folia support once possible
33+
paperweight.paperDevBundle("1.21.10-R0.1-SNAPSHOT")
3334

3435
implementation(project(":api"))
3536

gradle.properties

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
gameVersions=1.21.5,1.21.6,1.21.7,1.21.8
2-
loaders=paper,folia
1+
gameVersions=1.21.9,1.21.10
2+
# loaders=paper,folia // fixme: restore folia support once possible
3+
loaders=paper

src/main/java/net/thenextlvl/worlds/WorldsPlugin.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import net.thenextlvl.worlds.view.PaperLevelView;
2727
import net.thenextlvl.worlds.view.PluginGeneratorView;
2828
import org.bstats.bukkit.Metrics;
29-
import org.bukkit.GameRule;
3029
import org.bukkit.World;
3130
import org.bukkit.plugin.ServicePriority;
3231
import org.bukkit.plugin.java.JavaPlugin;
@@ -143,7 +142,6 @@ public Level.Builder levelBuilder(World world) {
143142
.seed(world.getSeed())
144143
.biomeProvider(world.getBiomeProvider())
145144
.chunkGenerator(world.getGenerator())
146-
.spawnChunkRadius(world.getGameRuleValue(GameRule.SPAWN_RADIUS))
147145
.key(world.key())
148146
.levelStem(switch (world.getEnvironment()) {
149147
case NORMAL -> LevelStem.OVERWORLD;

src/main/java/net/thenextlvl/worlds/level/LevelData.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ public abstract class LevelData implements Level {
4949
protected final boolean worldKnown;
5050
protected final boolean structures;
5151
protected final boolean bonusChest;
52-
protected final int spawnChunkRadius;
5352
protected final long seed;
5453

5554
protected LevelData(WorldsPlugin plugin, Builder builder) {
@@ -71,7 +70,6 @@ protected LevelData(WorldsPlugin plugin, Builder builder) {
7170
this.worldKnown = builder.worldKnown != null ? builder.worldKnown : false;
7271
this.structures = builder.structures != null ? builder.structures : plugin.getServer().getGenerateStructures();
7372
this.bonusChest = builder.bonusChest != null ? builder.bonusChest : false;
74-
this.spawnChunkRadius = builder.spawnChunkRadius != null ? builder.spawnChunkRadius : plugin.getServer().getSpawnRadius();
7573
this.seed = builder.seed != null ? builder.seed : ThreadLocalRandom.current().nextLong();
7674
}
7775

@@ -145,11 +143,6 @@ public boolean hasBonusChest() {
145143
return bonusChest;
146144
}
147145

148-
@Override
149-
public int getSpawnChunkRadius() {
150-
return spawnChunkRadius;
151-
}
152-
153146
@Override
154147
public long getSeed() {
155148
return seed;
@@ -171,8 +164,7 @@ public Level.Builder toBuilder() {
171164
.worldKnown(worldKnown)
172165
.structures(structures)
173166
.bonusChest(bonusChest)
174-
.seed(seed)
175-
.spawnChunkRadius(spawnChunkRadius);
167+
.seed(seed);
176168
}
177169

178170
public static class Builder implements Level.Builder {
@@ -186,7 +178,6 @@ public static class Builder implements Level.Builder {
186178
private @Nullable ChunkGenerator chunkGenerator;
187179
private @Nullable Generator generator;
188180
private @Nullable GeneratorType generatorType;
189-
private @Nullable Integer spawnChunkRadius;
190181
private @Nullable Key key;
191182
private @Nullable LevelStem levelStem;
192183
private @Nullable Long seed;
@@ -360,17 +351,6 @@ public Level.Builder worldKnown(@Nullable Boolean worldKnown) {
360351
return this;
361352
}
362353

363-
@Override
364-
public @Nullable Integer spawnChunkRadius() {
365-
return spawnChunkRadius;
366-
}
367-
368-
@Override
369-
public Level.Builder spawnChunkRadius(@Nullable Integer radius) {
370-
this.spawnChunkRadius = radius;
371-
return this;
372-
}
373-
374354
@Override
375355
public @Nullable Long seed() {
376356
return seed;
@@ -403,7 +383,6 @@ public String toString() {
403383
", worldKnown=" + worldKnown +
404384
", structures=" + structures +
405385
", bonusChest=" + bonusChest +
406-
", spawnChunkRadius=" + spawnChunkRadius +
407386
", seed=" + seed +
408387
'}';
409388
}

src/main/java/net/thenextlvl/worlds/level/PaperLevel.java

Lines changed: 42 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
import com.mojang.serialization.Dynamic;
66
import com.mojang.serialization.Lifecycle;
77
import io.papermc.paper.FeatureHooks;
8+
import io.papermc.paper.world.PaperWorldLoader;
89
import net.minecraft.core.Registry;
910
import net.minecraft.core.RegistryAccess;
1011
import net.minecraft.core.registries.Registries;
11-
import net.minecraft.nbt.NbtException;
12-
import net.minecraft.nbt.ReportedNbtException;
1312
import net.minecraft.resources.ResourceKey;
1413
import net.minecraft.resources.ResourceLocation;
1514
import net.minecraft.server.Main;
@@ -22,7 +21,6 @@
2221
import net.minecraft.world.entity.ai.village.VillageSiege;
2322
import net.minecraft.world.entity.npc.CatSpawner;
2423
import net.minecraft.world.entity.npc.WanderingTraderSpawner;
25-
import net.minecraft.world.level.ChunkPos;
2624
import net.minecraft.world.level.CustomSpawner;
2725
import net.minecraft.world.level.GameRules;
2826
import net.minecraft.world.level.GameType;
@@ -36,7 +34,6 @@
3634
import net.minecraft.world.level.levelgen.WorldOptions;
3735
import net.minecraft.world.level.storage.LevelDataAndDimensions;
3836
import net.minecraft.world.level.storage.LevelStorageSource;
39-
import net.minecraft.world.level.storage.LevelSummary;
4037
import net.minecraft.world.level.storage.PrimaryLevelData;
4138
import net.minecraft.world.level.validation.ContentValidationException;
4239
import net.thenextlvl.worlds.WorldsPlugin;
@@ -47,7 +44,6 @@
4744
import org.bukkit.World;
4845
import org.bukkit.craftbukkit.CraftServer;
4946
import org.bukkit.craftbukkit.generator.CraftWorldInfo;
50-
import org.bukkit.event.world.WorldLoadEvent;
5147
import org.bukkit.generator.WorldInfo;
5248
import org.jspecify.annotations.NullMarked;
5349

@@ -72,6 +68,7 @@ public CompletableFuture<World> createAsync() {
7268
}
7369

7470
/**
71+
* @see MinecraftServer#createLevel(LevelStem, PaperWorldLoader.WorldLoadingInfo, LevelStorageSource.LevelStorageAccess, PrimaryLevelData)
7572
* @see CraftServer#createWorld(org.bukkit.WorldCreator)
7673
*/
7774
private CompletableFuture<World> createInternal() {
@@ -94,6 +91,7 @@ private CompletableFuture<World> createInternal() {
9491
return CompletableFuture.failedFuture(e);
9592
}
9693

94+
/// Worlds start - find generator and biome provider
9795
var chunkGenerator = Optional.ofNullable(super.chunkGenerator)
9896
.orElseGet(() -> Optional.ofNullable(generator)
9997
.map(generator -> generator.generator(name))
@@ -102,6 +100,7 @@ private CompletableFuture<World> createInternal() {
102100
.orElseGet(() -> Optional.ofNullable(generator)
103101
.map(generator -> generator.biomeProvider(name))
104102
.orElseGet(() -> server.getBiomeProvider(name)));
103+
/// Worlds end
105104

106105
var dimensionType = resolveDimensionKey();
107106

@@ -113,51 +112,16 @@ private CompletableFuture<World> createInternal() {
113112
return CompletableFuture.failedFuture(ex);
114113
}
115114

116-
Dynamic<?> dataTag;
117-
if (levelStorageAccess.hasWorldData()) {
118-
LevelSummary summary;
119-
try {
120-
dataTag = levelStorageAccess.getDataTag();
121-
summary = levelStorageAccess.getSummary(dataTag);
122-
} catch (NbtException | ReportedNbtException | IOException e) {
123-
LevelStorageSource.LevelDirectory levelDirectory = levelStorageAccess.getLevelDirectory();
124-
plugin.getComponentLogger().warn("Failed to load world data from {}, attempting to use fallback", levelDirectory.dataFile(), e);
125-
126-
try {
127-
dataTag = levelStorageAccess.getDataTagFallback();
128-
summary = levelStorageAccess.getSummary(dataTag);
129-
} catch (NbtException | ReportedNbtException | IOException e1) {
130-
plugin.getComponentLogger().error("Failed to load world data from {}", levelDirectory.oldDataFile(), e1);
131-
plugin.getComponentLogger().error(
132-
"Failed to load world data from {} and {}. World files may be corrupted.",
133-
levelDirectory.dataFile(),
134-
levelDirectory.oldDataFile()
135-
);
136-
return CompletableFuture.failedFuture(e1);
137-
}
138-
139-
levelStorageAccess.restoreLevelDataFromOld();
140-
}
141-
142-
if (summary.requiresManualConversion()) {
143-
plugin.getComponentLogger().warn("This world must be opened in an older version (like 1.6.4) to be safely converted");
144-
return CompletableFuture.failedFuture(new IllegalStateException("World requires manual conversion"));
145-
}
146-
147-
if (!summary.isCompatible()) {
148-
plugin.getComponentLogger().warn("This world was created by an incompatible version.");
149-
return CompletableFuture.failedFuture(new IllegalStateException("World is incompatible"));
150-
}
151-
} else {
152-
dataTag = null;
153-
}
154-
155-
var generatorSettings = Optional.ofNullable(preset).orElse(Presets.CLASSIC_FLAT).serialize();
156-
157115
PrimaryLevelData primaryLevelData;
158-
WorldLoader.DataLoadContext context = console.worldLoader;
116+
WorldLoader.DataLoadContext context = console.worldLoaderContext;
159117
RegistryAccess.Frozen registryAccess = context.datapackDimensions();
160118
Registry<LevelStem> contextLevelStemRegistry = registryAccess.lookupOrThrow(Registries.LEVEL_STEM);
119+
/// Worlds start - fail if dimension could not be read
120+
var levelData = PaperWorldLoader.getLevelData(levelStorageAccess);
121+
if (levelData.fatalError()) return CompletableFuture.failedFuture(new IOException("Failed to read level data"));
122+
/// Worlds end
123+
Dynamic<?> dataTag = levelData.dataTag();
124+
161125
if (dataTag != null) {
162126
LevelDataAndDimensions levelDataAndDimensions = LevelStorageSource.getLevelDataAndDimensions(
163127
dataTag, context.dataConfiguration(), contextLevelStemRegistry, context.datapackWorldgen()
@@ -169,6 +133,7 @@ private CompletableFuture<World> createInternal() {
169133
WorldOptions worldOptions = new WorldOptions(seed, structures, bonusChest);
170134
WorldDimensions worldDimensions;
171135

136+
var generatorSettings = Optional.ofNullable(preset).orElse(Presets.CLASSIC_FLAT).serialize(); /// Worlds - serialize preset
172137
DedicatedServerProperties.WorldDimensionData properties = new DedicatedServerProperties.WorldDimensionData(generatorSettings, generatorType.presetName().asString());
173138
levelSettings = new LevelSettings(
174139
name,
@@ -217,58 +182,64 @@ private CompletableFuture<World> createInternal() {
217182
dimensionKey = ResourceKey.create(Registries.DIMENSION, ResourceLocation.fromNamespaceAndPath(key.namespace(), key.value()));
218183
}
219184

220-
primaryLevelData.getGameRules().getRule(GameRules.RULE_SPAWN_CHUNK_RADIUS).set(spawnChunkRadius, null);
221-
222185
ServerLevel serverLevel = new ServerLevel(
223186
console,
224187
console.executor,
225188
levelStorageAccess,
226189
primaryLevelData,
227190
dimensionKey,
228191
customStem,
229-
MinecraftServer.getServer().progressListenerFactory.create(primaryLevelData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS)),
230192
primaryLevelData.isDebugWorld(),
231193
seed,
232-
levelStem == net.thenextlvl.worlds.api.generator.LevelStem.OVERWORLD ? list : ImmutableList.of(),
194+
levelStem == net.thenextlvl.worlds.api.generator.LevelStem.OVERWORLD ? list : ImmutableList.of(), /// Worlds
233195
true,
234196
console.overworld().getRandomSequences(),
235197
toBukkit(levelStem.dimensionType()),
236198
chunkGenerator, biomeProvider
237199
);
238200

201+
/// Worlds start - ensure world is memoized before adding to server
239202
if (server.getWorld(name) == null) return CompletableFuture.failedFuture(
240203
new IllegalStateException("World with name " + name + " was not properly memoized")
241204
);
205+
/// Worlds end
242206

243207
console.addLevel(serverLevel);
244208

209+
/// Worlds start - initialize world for folia
245210
var future = new CompletableFuture<World>();
246211
if (WorldsPlugin.RUNNING_FOLIA) {
247-
serverLevel.randomSpawnSelection = new ChunkPos(serverLevel.getChunkSource().randomState().sampler().findSpawnPosition());
212+
// fixme: restore folia support once possible
213+
// serverLevel.randomSpawnSelection = new ChunkPos(serverLevel.getChunkSource().randomState().sampler().findSpawnPosition());
248214

249-
var x = serverLevel.randomSpawnSelection.x;
250-
var z = serverLevel.randomSpawnSelection.z;
215+
// var x = serverLevel.randomSpawnSelection.x;
216+
// var z = serverLevel.randomSpawnSelection.z;
251217

252-
plugin.getServer().getRegionScheduler().run(plugin, serverLevel.getWorld(), x, z, scheduledTask -> {
253-
console.initWorld(serverLevel, primaryLevelData, primaryLevelData, primaryLevelData.worldGenOptions());
254-
future.complete(serverLevel.getWorld());
255-
});
256-
} else {
257-
console.initWorld(serverLevel, primaryLevelData, primaryLevelData, primaryLevelData.worldGenOptions());
258-
future.complete(serverLevel.getWorld());
259-
}
218+
// plugin.getServer().getRegionScheduler().run(plugin, serverLevel.getWorld(), x, z, scheduledTask -> {
219+
// console.initWorld(serverLevel, primaryLevelData, primaryLevelData.worldGenOptions());
220+
// future.complete(serverLevel.getWorld());
221+
// });
222+
/// Worlds end
223+
} else console.initWorld(serverLevel, primaryLevelData, primaryLevelData.worldGenOptions());
260224

261225
serverLevel.setSpawnSettings(true);
262226

263-
console.prepareLevels(serverLevel.getChunkSource().chunkMap.progressListener, serverLevel);
264-
if (WorldsPlugin.RUNNING_FOLIA)
265-
io.papermc.paper.threadedregions.RegionizedServer.getInstance().addWorld(serverLevel);
266-
FeatureHooks.tickEntityManager(serverLevel);
267-
227+
/// Worlds start - persist world extra data
268228
persistWorld(serverLevel.getWorld(), levelStem, enabled.toBooleanOrElse(true));
269229
if (generator != null) persistGenerator(serverLevel.getWorld(), generator);
230+
/// Worlds end
231+
232+
/// Worlds start - start entity and region ticking for folia
233+
// fixme: restore folia support once possible
234+
// if (WorldsPlugin.RUNNING_FOLIA)
235+
// io.papermc.paper.threadedregions.RegionizedServer.getInstance().addWorld(serverLevel);
236+
FeatureHooks.tickEntityManager(serverLevel);
237+
/// Worlds end
270238

271-
new WorldLoadEvent(serverLevel.getWorld()).callEvent();
239+
console.prepareLevel(serverLevel);
240+
241+
/// Worlds - complete future immediately if not folia
242+
if (!WorldsPlugin.RUNNING_FOLIA) future.complete(serverLevel.getWorld());
272243
return future;
273244
}
274245

@@ -293,8 +264,9 @@ private ResourceKey<LevelStem> resolveDimensionKey() {
293264
}
294265

295266
private World.Environment toBukkit(DimensionType type) {
296-
if (type.equals(DimensionType.THE_END)) return World.Environment.THE_END;
267+
if (type.equals(DimensionType.OVERWORLD)) return World.Environment.NORMAL;
297268
if (type.equals(DimensionType.THE_NETHER)) return World.Environment.NETHER;
298-
return World.Environment.NORMAL;
269+
if (type.equals(DimensionType.THE_END)) return World.Environment.THE_END;
270+
return World.Environment.CUSTOM;
299271
}
300272
}

0 commit comments

Comments
 (0)