use of org.spongepowered.common.config.inheritable.WorldConfig in project SpongeCommon by SpongePowered.
the class MinecraftServerMixin method saveAllChunks.
/**
* @author Zidane - November, 24th 2020 - Minecraft 1.15
* @reason To allow per-world auto-save tick intervals or disable auto-saving entirely
*/
@Overwrite
public boolean saveAllChunks(final boolean suppressLog, final boolean flush, final boolean isForced) {
boolean var0 = false;
for (final ServerLevel world : this.shadow$getAllLevels()) {
final SerializationBehavior serializationBehavior = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$serializationBehavior().orElse(SerializationBehavior.AUTOMATIC);
final InheritableConfigHandle<WorldConfig> adapter = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$configAdapter();
// Sponge start - use our own config
boolean log = adapter.get().world.logAutoSave;
// by a command, save our configs
if (!this.shadow$isRunning() || this.tickCount % 6000 == 0 || isForced) {
((PrimaryLevelDataBridge) world.getLevelData()).bridge$configAdapter().save();
}
final boolean canSaveAtAll = serializationBehavior != SerializationBehavior.NONE;
// This world is set to not save of any time, no reason to check the auto-save/etc, skip it
if (!canSaveAtAll) {
continue;
}
// Only run auto-save skipping if the server is still running and the save is not forced
if (this.bridge$performAutosaveChecks() && !isForced) {
final int autoSaveInterval = adapter.get().world.autoSaveInterval;
// Do not process properties or chunks if the world is not set to do so unless the server is shutting down
if (autoSaveInterval <= 0 || serializationBehavior != SerializationBehavior.AUTOMATIC) {
continue;
}
// Now check the interval vs the tick counter and skip it
if (this.tickCount % autoSaveInterval != 0) {
continue;
}
}
if (log) {
LOGGER.info("Saving chunks for level '{}'/{}", world, world.dimension().location());
}
world.save((ProgressListener) null, flush, world.noSave && !isForced);
var0 = true;
}
// Save the usercache.json file every 10 minutes or if forced to
if (isForced || this.tickCount % 6000 == 0) {
// We want to save the username cache json, as we normally bypass it.
((GameProfileCacheBridge) this.profileCache).bridge$setCanSave(true);
this.profileCache.save();
((GameProfileCacheBridge) this.profileCache).bridge$setCanSave(false);
}
return var0;
}
use of org.spongepowered.common.config.inheritable.WorldConfig in project SpongeCommon by SpongePowered.
the class EntityMixin_EntityCollision method collision$initializeCollisionState.
@Override
public void collision$initializeCollisionState(final net.minecraft.world.level.Level world) {
final InheritableConfigHandle<WorldConfig> worldConfigAdapter = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$configAdapter();
final ConfigHandle<CommonConfig> globalConfigAdapter = SpongeConfigs.getCommon();
final EntityCollisionCategory.ModSubCategory worldCollMod = worldConfigAdapter.getOrCreateValue(s -> s.entityCollision.mods.get(this.entityCollision$key.namespace()), c -> {
// TODO: save after populating?
final EntityCollisionCategory.ModSubCategory globalCollision = new EntityCollisionCategory.ModSubCategory(this.entityCollision$key.namespace());
c.entityCollision.mods.put(this.entityCollision$key.namespace(), globalCollision);
globalCollision.entities.put(this.entityCollision$key.namespace(), this.collision$getMaxCollisions());
}, worldConfigAdapter.get().entityCollision.autoPopulate);
final EntityCollisionCategory worldCollCat = worldConfigAdapter.get().entityCollision;
this.collision$setMaxCollisions(worldCollCat.maxEntitiesWithinAABB);
boolean requiresSave = false;
if (worldCollMod != null) {
if (!worldCollMod.enabled) {
this.collision$setMaxCollisions(-1);
return;
}
// check mod overrides
final Integer modCollisionMax = worldCollMod.entityDefault;
if (modCollisionMax != null) {
this.collision$setMaxCollisions(modCollisionMax);
}
Integer entityMaxCollision = null;
if ((net.minecraft.world.entity.Entity) (Object) this instanceof ItemEntity) {
// check if all items are overridden
entityMaxCollision = worldCollMod.entities.get(this.entityCollision$key.value());
}
if (entityMaxCollision == null) {
entityMaxCollision = worldCollMod.entities.get(this.entityCollision$key.value());
}
// entity overrides
if (entityMaxCollision == null && worldCollCat.autoPopulate) {
// TODO(zml): Populate better
// globalCollMod.getEntityList().put(this.entityCollision$key.getValue(), this.collision$getMaxCollisions());
requiresSave = true;
} else if (entityMaxCollision != null) {
this.collision$setMaxCollisions(entityMaxCollision);
}
}
// don't bother saving for negative values
if (this.collision$getMaxCollisions() <= 0) {
return;
}
if (requiresSave) {
globalConfigAdapter.save();
}
}
use of org.spongepowered.common.config.inheritable.WorldConfig in project SpongeCommon by SpongePowered.
the class BlockMixin_EntityCollision method collision$initializeCollisionState.
@Override
public void collision$initializeCollisionState(final net.minecraft.world.level.Level world) {
final InheritableConfigHandle<WorldConfig> worldConfigAdapter = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$configAdapter();
final ConfigHandle<CommonConfig> globalConfigAdapter = SpongeConfigs.getCommon();
final EntityCollisionCategory worldCollCat = worldConfigAdapter.get().entityCollision;
this.collision$setMaxCollisions(worldCollCat.maxEntitiesWithinAABB);
boolean requiresSave = false;
String[] ids = Sponge.game().registry(RegistryTypes.BLOCK_TYPE).valueKey((BlockType) this).toString().split(":");
String modId = ids[0];
String name = ids[1];
final EntityCollisionCategory.ModSubCategory worldCollMod = worldConfigAdapter.getOrCreateValue(s -> s.entityCollision.mods.get(modId), c -> {
// TODO: finish after populating?
final EntityCollisionCategory.ModSubCategory globalCollision = new EntityCollisionCategory.ModSubCategory(modId);
c.entityCollision.mods.put(modId, globalCollision);
globalCollision.blocks.put(name, this.collision$getMaxCollisions());
}, worldCollCat.autoPopulate);
if (worldCollMod != null) {
if (!worldCollMod.enabled) {
this.collision$setMaxCollisions(-1);
return;
}
// check mod overrides
Integer modCollisionMax = worldCollMod.blockDefault;
if (modCollisionMax != null) {
this.collision$setMaxCollisions(modCollisionMax);
}
// entity overrides
Integer blockMaxCollision = worldCollMod.blocks.get(name);
if (blockMaxCollision == null && worldCollCat.autoPopulate) {
worldCollMod.blocks.put(name, this.collision$getMaxCollisions());
requiresSave = true;
} else if (blockMaxCollision != null) {
this.collision$setMaxCollisions(blockMaxCollision);
}
}
// don't bother saving for negative values
if (this.collision$getMaxCollisions() <= 0) {
return;
}
if (requiresSave) {
globalConfigAdapter.save();
}
}
use of org.spongepowered.common.config.inheritable.WorldConfig in project SpongeCommon by SpongePowered.
the class SpongeGameConfigs method createWorld.
public static InheritableConfigHandle<WorldConfig> createWorld(@Nullable final ResourceKey dimensionTypeKey, final ResourceKey world) {
// Path format: config/sponge/worlds/<world-namespace>/<world-value>.conf
final Path configPath = SpongeConfigs.getDirectory().resolve(Paths.get("worlds", world.namespace(), world.value() + ".conf"));
if (dimensionTypeKey != null) {
// Legacy config path: config/sponge/worlds/<dim-namespace>/<dim-value>/<world-name>/world.conf
final String legacyName = SpongeGameConfigs.getLegacyWorldName(world);
if (legacyName != null) {
final Path legacyPath = SpongeConfigs.getDirectory().resolve(Paths.get("worlds", dimensionTypeKey.namespace(), SpongeGameConfigs.getLegacyValue(dimensionTypeKey), legacyName, "world.conf"));
if (legacyPath.toFile().isFile() && !configPath.toFile().isFile()) {
try {
Files.createDirectories(configPath.getParent());
Files.move(legacyPath, configPath);
final Path legacyParent = legacyPath.getParent();
try (final DirectoryStream<Path> str = Files.newDirectoryStream(legacyParent)) {
if (!str.iterator().hasNext()) {
Files.delete(legacyParent);
}
}
} catch (final IOException ex) {
SpongeGameConfigs.LOGGER.error("Unable to migrate config for world {} from legacy location {}", world, legacyPath, ex);
}
}
}
}
try {
final InheritableConfigHandle<WorldConfig> config = new InheritableConfigHandle<>(WorldConfig.class, BaseConfig::transformation, SpongeConfigs.createLoader(configPath), SpongeGameConfigs.getGlobalInheritable());
config.load();
return config;
} catch (final IOException ex) {
SpongeGameConfigs.LOGGER.error("Unable to load configuration for world {}. Sponge will use a " + "fallback configuration with default values that will not save.", world, ex);
return SpongeGameConfigs.createDetached();
}
}
use of org.spongepowered.common.config.inheritable.WorldConfig in project SpongeCommon by SpongePowered.
the class SpongeWorldManager method loadWorld0.
private CompletableFuture<org.spongepowered.api.world.server.ServerWorld> loadWorld0(final net.minecraft.resources.ResourceKey<Level> registryKey, final LevelStem template, final WorldGenSettings generatorSettings) {
final PrimaryLevelData defaultLevelData = (PrimaryLevelData) this.server.getWorldData();
final LevelSettings defaultLevelSettings = ((PrimaryLevelDataAccessor) defaultLevelData).accessor$settings();
final LevelStemBridge templateBridge = (LevelStemBridge) (Object) template;
final ResourceKey worldKey = ((ResourceKeyBridge) templateBridge).bridge$getKey();
final WorldType worldType = (WorldType) template.type();
final ResourceKey worldTypeKey = RegistryTypes.WORLD_TYPE.get().valueKey((WorldType) template.type());
MinecraftServerAccessor.accessor$LOGGER().info("Loading world '{}' ({})", worldKey, worldTypeKey);
final String directoryName = this.getDirectoryName(worldKey);
final boolean isVanillaSubLevel = this.isVanillaSubWorld(directoryName);
final LevelStorageSource.LevelStorageAccess storageSource;
try {
if (isVanillaSubLevel) {
storageSource = LevelStorageSource.createDefault(this.defaultWorldDirectory).createAccess(directoryName);
} else {
storageSource = LevelStorageSource.createDefault(this.customWorldsDirectory).createAccess(worldKey.namespace() + File.separator + worldKey.value());
}
} catch (final IOException e) {
e.printStackTrace();
return FutureUtil.completedWithException(new RuntimeException(String.format("Failed to create level data for world '%s'!", worldKey), e));
}
PrimaryLevelData levelData;
levelData = (PrimaryLevelData) storageSource.getDataTag((DynamicOps<Tag>) BootstrapProperties.worldSettingsAdapter, defaultLevelSettings.getDataPackConfig());
if (levelData == null) {
final LevelSettings levelSettings;
final WorldGenSettings generationSettings;
if (this.server.isDemo()) {
levelSettings = MinecraftServer.DEMO_SETTINGS;
generationSettings = WorldGenSettings.demoSettings(BootstrapProperties.registries);
} else {
levelSettings = new LevelSettings(directoryName, (GameType) (Object) BootstrapProperties.gameMode.get(Sponge.game()), templateBridge.bridge$hardcore().orElse(BootstrapProperties.hardcore), (Difficulty) (Object) BootstrapProperties.difficulty.get(Sponge.game()), templateBridge.bridge$commands().orElse(BootstrapProperties.commands), new GameRules(), defaultLevelData.getDataPackConfig());
generationSettings = generatorSettings;
}
levelData = new PrimaryLevelData(levelSettings, generationSettings, Lifecycle.stable());
}
((PrimaryLevelDataBridge) levelData).bridge$populateFromDimension(template);
final InheritableConfigHandle<WorldConfig> configAdapter = SpongeGameConfigs.createWorld(worldTypeKey, worldKey);
((PrimaryLevelDataBridge) levelData).bridge$configAdapter(configAdapter);
levelData.setModdedInfo(this.server.getServerModName(), this.server.getModdedStatus().isPresent());
final boolean isDebugGeneration = levelData.worldGenSettings().isDebug();
final long seed = BiomeManager.obfuscateSeed(levelData.worldGenSettings().seed());
final ChunkProgressListener chunkStatusListener = ((MinecraftServerAccessor) this.server).accessor$progressListenerFactory().create(11);
final ServerLevel world = new ServerLevel(this.server, ((MinecraftServerAccessor) this.server).accessor$executor(), storageSource, levelData, registryKey, (DimensionType) worldType, chunkStatusListener, template.generator(), isDebugGeneration, seed, ImmutableList.of(), true);
this.worlds.put(registryKey, world);
return SpongeCommon.asyncScheduler().submit(() -> this.prepareWorld(world, isDebugGeneration)).thenApply(w -> {
((MinecraftServerAccessor) this.server).invoker$forceDifficulty();
return w;
}).thenCompose(w -> this.postWorldLoad(w, false)).thenApply(w -> (org.spongepowered.api.world.server.ServerWorld) w);
}
Aggregations