/* * This file is part of Applied Energistics 2. * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. * * Applied Energistics 2 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Applied Energistics 2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Applied Energistics 2. If not, see . */ package appeng.core.worlddata; import java.io.File; import java.util.List; import java.util.concurrent.ThreadFactory; import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.config.Configuration; import appeng.core.AEConfig; import appeng.services.CompassService; import appeng.services.compass.CompassThreadFactory; /** * Singleton access to anything related to world-based data. * * Data will change depending which world is loaded. Will probably not affect SMP at all since only one world is loaded, * but SSP more, cause they play on * different worlds. * * @author thatsIch * @version rv3 - 02.11.2015 * @since rv3 30.05.2015 */ public final class WorldData implements IWorldData { private static final String AE2_DIRECTORY_NAME = "AE2"; private static final String SETTING_FILE_NAME = "settings.cfg"; private static final String SPAWNDATA_DIR_NAME = "spawndata"; private static final String COMPASS_DIR_NAME = "compass"; @Nullable private static IWorldData instance; private final IWorldPlayerData playerData; private final IWorldDimensionData dimensionData; private final IWorldGridStorageData storageData; private final IWorldCompassData compassData; private final IWorldSpawnData spawnData; private final List startables; private final List stoppables; private final File ae2directory; private final File spawnDirectory; private final File compassDirectory; private final Configuration sharedConfig; private WorldData( @Nonnull final File worldDirectory ) { Preconditions.checkNotNull( worldDirectory ); Preconditions.checkArgument( worldDirectory.isDirectory() ); this.ae2directory = new File( worldDirectory, AE2_DIRECTORY_NAME ); this.spawnDirectory = new File( this.ae2directory, SPAWNDATA_DIR_NAME ); this.compassDirectory = new File( this.ae2directory, COMPASS_DIR_NAME ); final File settingsFile = new File( this.ae2directory, SETTING_FILE_NAME ); this.sharedConfig = new Configuration( settingsFile, AEConfig.VERSION ); final PlayerData playerData = new PlayerData( this.sharedConfig ); final DimensionData dimensionData = new DimensionData( this.sharedConfig ); final StorageData storageData = new StorageData( this.sharedConfig ); final ThreadFactory compassThreadFactory = new CompassThreadFactory(); final CompassService compassService = new CompassService( this.compassDirectory, compassThreadFactory ); final CompassData compassData = new CompassData( this.compassDirectory, compassService ); final IWorldSpawnData spawnData = new SpawnData( this.spawnDirectory ); this.playerData = playerData; this.dimensionData = dimensionData; this.storageData = storageData; this.compassData = compassData; this.spawnData = spawnData; this.startables = Lists.newArrayList( playerData, dimensionData, storageData ); this.stoppables = Lists.newArrayList( playerData, dimensionData, storageData, compassData ); } /** * @return ae2 data related to a specific world * * @deprecated do not use singletons which are dependent on specific world state */ @Deprecated @Nonnull public static IWorldData instance() { return instance; } /** * Requires to start up from external from here * * drawback of the singleton build style */ public static void onServerAboutToStart() { final File worldDirectory = DimensionManager.getCurrentSaveRootDirectory(); final WorldData newInstance = new WorldData( worldDirectory ); instance = newInstance; newInstance.onServerStarting(); } private void onServerStarting() { // check if ae2 folder already exists, else create if( !this.ae2directory.isDirectory() && !this.ae2directory.mkdir() ) { throw new IllegalStateException( "Failed to create " + this.ae2directory.getAbsolutePath() ); } // check if compass folder already exists, else create if( !this.compassDirectory.isDirectory() && !this.compassDirectory.mkdir() ) { throw new IllegalStateException( "Failed to create " + this.compassDirectory.getAbsolutePath() ); } // check if spawn data dir already exists, else create if( !this.spawnDirectory.isDirectory() && !this.spawnDirectory.mkdir() ) { throw new IllegalStateException( "Failed to create " + this.spawnDirectory.getAbsolutePath() ); } for( final IOnWorldStartable startable : this.startables ) { startable.onWorldStart(); } this.startables.clear(); } @Override public void onServerStopping() { for( final IOnWorldStoppable stoppable : this.stoppables ) { stoppable.onWorldStop(); } } @Override public void onServerStoppped() { Preconditions.checkNotNull( instance ); this.stoppables.clear(); instance = null; } @Nonnull @Override public IWorldGridStorageData storageData() { return this.storageData; } @Nonnull @Override public IWorldPlayerData playerData() { return this.playerData; } @Nonnull @Override public IWorldDimensionData dimensionData() { return this.dimensionData; } @Nonnull @Override public IWorldCompassData compassData() { return this.compassData; } @Nonnull @Override public IWorldSpawnData spawnData() { return this.spawnData; } }