58
58
import net .minecraft .world .level .storage .WorldData ;
59
59
import org .apache .commons .io .FileUtils ;
60
60
import org .jetbrains .annotations .NotNull ;
61
- import org .jetbrains .annotations .Nullable ;
62
61
import org .spongepowered .asm .mixin .Final ;
63
62
import org .spongepowered .asm .mixin .Mixin ;
64
63
import org .spongepowered .asm .mixin .Shadow ;
@@ -221,21 +220,19 @@ private void removeWorlds(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
221
220
}
222
221
223
222
@ Override
224
- public void addDynamicLevel (ResourceLocation id , @ NotNull LevelStem stem , DimensionType type ) {
225
- if (!this .canCreateLevel (id )) {
226
- throw new IllegalArgumentException ("World already exists!?" );
227
- }
223
+ public boolean addDynamicLevel (@ NotNull ResourceLocation id , @ NotNull LevelStem stem , @ NotNull DimensionType type ) {
224
+ if (!this .canCreateLevel (id )) return false ;
228
225
((WritableRegistry <LevelStem >) this .getWorldData ().worldGenSettings ().dimensions ()).register (ResourceKey .create (Registry .LEVEL_STEM_REGISTRY , id ), stem , Lifecycle .stable ());
229
226
((ImmutableRegistryAccessAccessor ) this .registryAccess ()).unfreezeTypes (reg -> reg .register (ResourceKey .create (Registry .DIMENSION_TYPE_REGISTRY , id ), type , Lifecycle .stable ()));
230
227
231
- ResourceKey <Level > worldKey = ResourceKey .create (Registry .DIMENSION_REGISTRY , id );
232
- DerivedLevelData properties = new DerivedLevelData (this .getWorldData (), this .getWorldData ().overworldData ());
233
- ServerLevel world = new ServerLevel (
228
+ ResourceKey <Level > key = ResourceKey .create (Registry .DIMENSION_REGISTRY , id );
229
+ DerivedLevelData data = new DerivedLevelData (this .getWorldData (), this .getWorldData ().overworldData ());
230
+ ServerLevel level = new ServerLevel (
234
231
(MinecraftServer ) (Object ) this ,
235
232
this .executor ,
236
233
this .storageSource ,
237
- properties ,
238
- worldKey ,
234
+ data ,
235
+ key ,
239
236
stem .typeHolder (),
240
237
progressListenerFactory .create (10 ),
241
238
stem .generator (),
@@ -246,71 +243,74 @@ public void addDynamicLevel(ResourceLocation id, @NotNull LevelStem stem, Dimens
246
243
);
247
244
ServerLevel overworld = this .overworld ();
248
245
assert overworld != null ;
249
- overworld .getWorldBorder ().addListener (new BorderChangeListener .DelegateBorderChangeListener (world .getWorldBorder ()));
250
- world .getChunkSource ().setSimulationDistance (((DistanceManagerAccessor ) ((ServerChunkCacheAccessor ) overworld .getChunkSource ()).getDistanceManager ()).getSimulationDistance ());
251
- world .getChunkSource ().setViewDistance (((ChunkMapAccessor ) overworld .getChunkSource ().chunkMap ).getViewDistance ());
246
+ overworld .getWorldBorder ().addListener (new BorderChangeListener .DelegateBorderChangeListener (level .getWorldBorder ()));
247
+ level .getChunkSource ().setSimulationDistance (((DistanceManagerAccessor ) ((ServerChunkCacheAccessor ) overworld .getChunkSource ()).getDistanceManager ()).getSimulationDistance ());
248
+ level .getChunkSource ().setViewDistance (((ChunkMapAccessor ) overworld .getChunkSource ().chunkMap ).getViewDistance ());
252
249
if (stem .typeHolder () instanceof Holder .Reference <DimensionType >
253
250
&& (stem .typeHolder ().unwrap ().right ().isEmpty ()
254
251
|| stem .typeHolder ().value () != type )) {
255
252
((HolderReferenceInvoker <DimensionType >) stem .typeHolder ()).callBind (stem .typeHolder ().unwrapKey ().get (), type );
256
253
}
257
254
((PrimaryLevelDataAccessor ) this .getWorldData ()).addDynamicLevel (id , stem );
258
- this .enqueuedCreatedWorlds .put (worldKey , world ); //prevent comodification
255
+ this .enqueuedCreatedWorlds .put (key , level ); //prevent comodification
259
256
260
257
FriendlyByteBuf packetByteBuf = PacketByteBufs .create ();
261
258
packetByteBuf .writeResourceLocation (id );
262
259
packetByteBuf .writeInt (this .registryAccess ().registryOrThrow (Registry .DIMENSION_TYPE_REGISTRY ).getId (type ));
263
260
packetByteBuf .writeNbt ((CompoundTag ) DimensionType .DIRECT_CODEC .encode (type , NbtOps .INSTANCE , new CompoundTag ()).get ().orThrow ());
264
261
this .getPlayerList ().broadcastAll (new ClientboundCustomPayloadPacket (Constant .id ("create_world" ), packetByteBuf ));
265
262
this .reloadTags ();
263
+ return true ;
266
264
}
267
265
268
266
@ Override
269
- public boolean levelExists (ResourceLocation id ) {
267
+ public boolean levelExists (@ NotNull ResourceLocation id ) {
270
268
return this .levels .containsKey (ResourceKey .create (Registry .DIMENSION_REGISTRY , id ))
271
269
&& this .registryAccess ().registryOrThrow (Registry .DIMENSION_TYPE_REGISTRY ).containsKey (id )
272
270
|| this .getWorldData ().worldGenSettings ().dimensions ().containsKey (id )
273
271
|| ((PrimaryLevelDataAccessor ) this .getWorldData ()).getDynamicWorlds ().containsKey (id );
274
272
}
275
273
276
274
@ Override
277
- public boolean canCreateLevel (ResourceLocation id ) {
275
+ public boolean canCreateLevel (@ NotNull ResourceLocation id ) {
278
276
return Constant .CONFIG .allowWorldCreation () && !this .levelExists (id );
279
277
}
280
278
281
279
@ Override
282
- public boolean canDestroyLevel (ResourceLocation id ) {
280
+ public boolean canDestroyLevel (@ NotNull ResourceLocation id ) {
283
281
return this .levelExists (id ) && (Constant .CONFIG .deleteWorldsWithPlayers () || this .levels .get (ResourceKey .create (Registry .DIMENSION_REGISTRY , id )).players ().size () == 0 );
284
282
}
285
283
286
284
@ Override
287
- public void removeDynamicLevel (ResourceLocation id , @ Nullable PlayerRemover remover ) {
288
- if (!this .canDestroyLevel (id )) {
289
- throw new IllegalArgumentException ("Cannot destroy world!" );
290
- }
285
+ public boolean removeDynamicLevel (@ NotNull ResourceLocation id , @ NotNull PlayerRemover remover ) {
286
+ if (!this .canDestroyLevel (id )) return false ;
291
287
292
- (( PrimaryLevelDataAccessor ) this . getWorldData ()). removeDynamicLevel ( id ); //worst case, it'll just be gone on reload
293
- ResourceKey < Level > of = ResourceKey . create ( Registry . DIMENSION_REGISTRY , id );
294
- for ( ServerPlayer serverPlayerEntity : this . getPlayerList (). getPlayers ()) {
295
- if (serverPlayerEntity . level . dimension (). equals ( of )) {
296
- if ( remover == null ) {
297
- throw new IllegalArgumentException ( "Cannot remove world as it is currently loaded by a player!" );
298
- } else {
299
- remover . removePlayer (( MinecraftServer ) ( Object ) this , serverPlayerEntity );
288
+ ResourceKey < Level > key = ResourceKey . create ( Registry . DIMENSION_REGISTRY , id );
289
+ List < ServerPlayer > players = new ArrayList <>( this . levels . get ( key ). players ()); // prevent comod
290
+ if (! players . isEmpty ()) {
291
+ if (Constant . CONFIG . deleteWorldsWithPlayers ( )) {
292
+ for ( ServerPlayer player : players ) {
293
+ if ( player . level . dimension (). equals ( key )) {
294
+ remover . removePlayer (( MinecraftServer ) ( Object ) this , player );
295
+ }
300
296
}
297
+ } else {
298
+ return false ;
301
299
}
302
300
}
303
301
304
- this .enqueuedDestroyedWorlds .add (of );
302
+ ((PrimaryLevelDataAccessor ) this .getWorldData ()).removeDynamicLevel (id );
303
+ this .enqueuedDestroyedWorlds .add (key );
304
+ return true ;
305
305
}
306
306
307
307
private void reloadTags () {
308
- for (TagManager .LoadResult <?> registryTag : ((ReloadableServerResourcesAccessor ) this .resources .managers ()).getTagManager ().getResult ()) {
309
- if (registryTag .key () == Registry .DIMENSION_TYPE_REGISTRY ) {
310
- Registry <DimensionType > dimensionTypes = this .registryAccess ().registryOrThrow (Registry .DIMENSION_TYPE_REGISTRY );
311
- dimensionTypes .resetTags ();
308
+ for (TagManager .LoadResult <?> result : ((ReloadableServerResourcesAccessor ) this .resources .managers ()).getTagManager ().getResult ()) {
309
+ if (result .key () == Registry .DIMENSION_TYPE_REGISTRY ) {
310
+ Registry <DimensionType > types = this .registryAccess ().registryOrThrow (Registry .DIMENSION_TYPE_REGISTRY );
311
+ types .resetTags ();
312
312
//noinspection unchecked - we know that the registry is a registry of dimension types as the key is correct
313
- dimensionTypes .bindTags (((TagManager .LoadResult <DimensionType >) registryTag ).tags ().entrySet ()
313
+ types .bindTags (((TagManager .LoadResult <DimensionType >) result ).tags ().entrySet ()
314
314
.stream ()
315
315
.collect (Collectors .toUnmodifiableMap (entry -> TagKey .create (Registry .DIMENSION_TYPE_REGISTRY , entry .getKey ()), entry -> (entry .getValue ()).getValues ())));
316
316
break ;
0 commit comments