From d1e4ea657976885a3c000366547f13de85d4b0bc Mon Sep 17 00:00:00 2001 From: thatsIch Date: Thu, 28 May 2015 20:01:21 +0200 Subject: [PATCH] Improves the message generated when generating the folder for the compass data. Outsources the encoding of the compass data into the file name Written tests for the encoding Did some internal cleaning of the class --- .../appeng/api/features/IPlayerRegistry.java | 7 +- .../appeng/block/solids/BlockSkyStone.java | 8 +- src/main/java/appeng/core/AppEng.java | 11 +- src/main/java/appeng/core/WorldSettings.java | 490 ------------------ .../features/registries/PlayerRegistry.java | 13 +- .../core/sync/network/NetworkHandler.java | 8 +- .../sync/packets/PacketCompassRequest.java | 6 +- .../appeng/core/worlddata/CompassData.java | 66 +++ .../appeng/core/worlddata/DimensionData.java | 174 +++++++ .../core/worlddata/IOnWorldStartable.java | 30 ++ .../core/worlddata/IOnWorldStoppable.java | 30 ++ .../core/worlddata/IWorldCompassData.java | 33 ++ .../appeng/core/worlddata/IWorldData.java | 48 ++ .../core/worlddata/IWorldDimensionData.java | 43 ++ .../core/worlddata/IWorldGridStorageData.java | 46 ++ .../core/worlddata/IWorldPlayerData.java | 40 ++ .../core/worlddata/IWorldPlayerMapping.java | 54 ++ .../core/worlddata/IWorldSpawnData.java | 41 ++ .../core/worlddata/MeteorDataNameEncoder.java | 82 +++ .../appeng/core/worlddata/PlayerData.java | 148 ++++++ .../PlayerMapping.java} | 32 +- .../PlayerMappingsInitializer.java | 13 +- .../java/appeng/core/worlddata/SpawnData.java | 227 ++++++++ .../appeng/core/worlddata/StorageData.java | 166 ++++++ .../java/appeng/core/worlddata/WorldData.java | 204 ++++++++ .../items/storage/ItemSpatialStorageCell.java | 10 +- src/main/java/appeng/me/Grid.java | 8 +- src/main/java/appeng/me/GridNode.java | 9 +- src/main/java/appeng/me/GridStorage.java | 6 +- .../java/appeng/me/cache/SecurityCache.java | 15 +- .../appeng/me/helpers/AENetworkProxy.java | 11 +- .../java/appeng/services/CompassService.java | 38 +- .../services/compass/CompassReader.java | 21 +- .../services/compass/CompassRegion.java | 66 ++- .../compass/CompassThreadFactory.java | 42 ++ src/main/java/appeng/spatial/CachedPlane.java | 4 +- .../java/appeng/worldgen/MeteoritePlacer.java | 8 +- .../appeng/worldgen/MeteoriteWorldGen.java | 17 +- .../worlddata/MeteorDataNameEncoderTest.java | 65 +++ 39 files changed, 1704 insertions(+), 636 deletions(-) delete mode 100644 src/main/java/appeng/core/WorldSettings.java create mode 100644 src/main/java/appeng/core/worlddata/CompassData.java create mode 100644 src/main/java/appeng/core/worlddata/DimensionData.java create mode 100644 src/main/java/appeng/core/worlddata/IOnWorldStartable.java create mode 100644 src/main/java/appeng/core/worlddata/IOnWorldStoppable.java create mode 100644 src/main/java/appeng/core/worlddata/IWorldCompassData.java create mode 100644 src/main/java/appeng/core/worlddata/IWorldData.java create mode 100644 src/main/java/appeng/core/worlddata/IWorldDimensionData.java create mode 100644 src/main/java/appeng/core/worlddata/IWorldGridStorageData.java create mode 100644 src/main/java/appeng/core/worlddata/IWorldPlayerData.java create mode 100644 src/main/java/appeng/core/worlddata/IWorldPlayerMapping.java create mode 100644 src/main/java/appeng/core/worlddata/IWorldSpawnData.java create mode 100644 src/main/java/appeng/core/worlddata/MeteorDataNameEncoder.java create mode 100644 src/main/java/appeng/core/worlddata/PlayerData.java rename src/main/java/appeng/core/{PlayerMappings.java => worlddata/PlayerMapping.java} (73%) rename src/main/java/appeng/core/{ => worlddata}/PlayerMappingsInitializer.java (88%) create mode 100644 src/main/java/appeng/core/worlddata/SpawnData.java create mode 100644 src/main/java/appeng/core/worlddata/StorageData.java create mode 100644 src/main/java/appeng/core/worlddata/WorldData.java create mode 100644 src/main/java/appeng/services/compass/CompassThreadFactory.java create mode 100644 src/test/java/appeng/core/worlddata/MeteorDataNameEncoderTest.java diff --git a/src/api/java/appeng/api/features/IPlayerRegistry.java b/src/api/java/appeng/api/features/IPlayerRegistry.java index 54cbc8f5..d63cef9c 100644 --- a/src/api/java/appeng/api/features/IPlayerRegistry.java +++ b/src/api/java/appeng/api/features/IPlayerRegistry.java @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2013 AlgorithmX2 + * Copyright (c) 2013 - 2015 AlgorithmX2 * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in @@ -24,10 +24,12 @@ package appeng.api.features; -import net.minecraft.entity.player.EntityPlayer; +import javax.annotation.Nullable; import com.mojang.authlib.GameProfile; +import net.minecraft.entity.player.EntityPlayer; + /** * Maintains a save specific list of userids and username combinations this greatly simplifies storage internally and @@ -55,5 +57,6 @@ public interface IPlayerRegistry * * @return PlayerEntity, or null if the player could not be found. */ + @Nullable EntityPlayer findPlayer( int playerID ); } diff --git a/src/main/java/appeng/block/solids/BlockSkyStone.java b/src/main/java/appeng/block/solids/BlockSkyStone.java index adcdd18a..da6d34c1 100644 --- a/src/main/java/appeng/block/solids/BlockSkyStone.java +++ b/src/main/java/appeng/block/solids/BlockSkyStone.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -43,8 +43,8 @@ import cpw.mods.fml.relauncher.SideOnly; import appeng.api.util.IOrientable; import appeng.api.util.IOrientableBlock; import appeng.block.AEBaseBlock; -import appeng.core.WorldSettings; import appeng.core.features.AEFeature; +import appeng.core.worlddata.WorldData; import appeng.helpers.LocationRotation; import appeng.helpers.NullRotation; import appeng.util.Platform; @@ -118,7 +118,7 @@ public class BlockSkyStone extends AEBaseBlock implements IOrientableBlock super.onBlockAdded( w, x, y, z ); if( Platform.isServer() ) { - WorldSettings.getInstance().getCompass().updateArea( w, x, y, z ); + WorldData.instance().compassData().service().updateArea( w, x, y, z ); } } @@ -212,7 +212,7 @@ public class BlockSkyStone extends AEBaseBlock implements IOrientableBlock super.breakBlock( w, x, y, z, b, metadata ); if( Platform.isServer() ) { - WorldSettings.getInstance().getCompass().updateArea( w, x, y, z ); + WorldData.instance().compassData().service().updateArea( w, x, y, z ); } } } diff --git a/src/main/java/appeng/core/AppEng.java b/src/main/java/appeng/core/AppEng.java index c6f72291..b9009861 100644 --- a/src/main/java/appeng/core/AppEng.java +++ b/src/main/java/appeng/core/AppEng.java @@ -44,6 +44,7 @@ import appeng.core.crash.ModCrashEnhancement; import appeng.core.features.AEFeature; import appeng.core.sync.GuiBridge; import appeng.core.sync.network.NetworkHandler; +import appeng.core.worlddata.WorldData; import appeng.hooks.TickHandler; import appeng.integration.IntegrationRegistry; import appeng.server.AECommand; @@ -187,16 +188,16 @@ public final class AppEng } @EventHandler - private void serverStopping( FMLServerStoppingEvent event ) + private void serverAboutToStart( FMLServerAboutToStartEvent evt ) { - WorldSettings.getInstance().shutdown(); - TickHandler.INSTANCE.shutdown(); + WorldData.onServerAboutToStart(); } @EventHandler - private void serverAboutToStart( FMLServerAboutToStartEvent evt ) + private void serverStopping( FMLServerStoppingEvent event ) { - WorldSettings.getInstance().init(); + WorldData.instance().onServerStopping(); + TickHandler.INSTANCE.shutdown(); } @EventHandler diff --git a/src/main/java/appeng/core/WorldSettings.java b/src/main/java/appeng/core/WorldSettings.java deleted file mode 100644 index 71079de4..00000000 --- a/src/main/java/appeng/core/WorldSettings.java +++ /dev/null @@ -1,490 +0,0 @@ -/* - * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, 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; - - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.WeakHashMap; - -import com.google.common.base.Optional; -import com.mojang.authlib.GameProfile; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.NetworkManager; -import net.minecraftforge.common.DimensionManager; -import net.minecraftforge.common.config.ConfigCategory; -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.common.config.Property; - -import appeng.api.util.WorldCoord; -import appeng.core.sync.network.NetworkHandler; -import appeng.core.sync.packets.PacketNewStorageDimension; -import appeng.hooks.TickHandler; -import appeng.hooks.TickHandler.PlayerColor; -import appeng.me.GridStorage; -import appeng.me.GridStorageSearch; -import appeng.services.CompassService; - - -public class WorldSettings extends Configuration -{ - private static final String SPAWNDATA_FOLDER = "spawndata"; - private static final String COMPASS_FOLDER = "compass"; - - private static WorldSettings instance; - private final List storageCellDims = new ArrayList(); - private final File spawnDataFolder; - private final CompassService compass; - private final PlayerMappings mappings; - private final Map> loadedStorage = new WeakHashMap>(); - private long lastGridStorage; - private int lastPlayer; - - public WorldSettings( File aeFolder ) - { - super( new File( aeFolder.getPath(), "settings.cfg" ) ); - this.spawnDataFolder = new File( aeFolder, SPAWNDATA_FOLDER ); - this.compass = new CompassService( aeFolder ); - - for( int dimID : this.get( "DimensionManager", "StorageCells", new int[0] ).getIntList() ) - { - this.storageCellDims.add( dimID ); - DimensionManager.registerDimension( dimID, AEConfig.instance.storageProviderID ); - } - - try - { - this.lastGridStorage = Long.parseLong( this.get( "Counters", "lastGridStorage", 0 ).getString() ); - this.lastPlayer = this.get( "Counters", "lastPlayer", 0 ).getInt(); - } - catch( NumberFormatException err ) - { - this.lastGridStorage = 0; - this.lastPlayer = 0; - } - - final ConfigCategory playerList = this.getCategory( "players" ); - this.mappings = new PlayerMappings( playerList, AELog.INSTANCE ); - } - - public static WorldSettings getInstance() - { - if( instance == null ) - { - File world = DimensionManager.getCurrentSaveRootDirectory(); - - File aeBaseFolder = new File( world.getPath(), "AE2" ); - - if( !aeBaseFolder.isDirectory() && !aeBaseFolder.mkdir() ) - { - throw new IllegalStateException( "Failed to create " + aeBaseFolder.getAbsolutePath() ); - } - - File compass = new File( aeBaseFolder, COMPASS_FOLDER ); - if( !compass.isDirectory() && !compass.mkdir() ) - { - throw new IllegalStateException( "Failed to create " + compass.getAbsolutePath() ); - } - - File spawnData = new File( aeBaseFolder, SPAWNDATA_FOLDER ); - if( !spawnData.isDirectory() && !spawnData.mkdir() ) - { - throw new IllegalStateException( "Failed to create " + spawnData.getAbsolutePath() ); - } - - instance = new WorldSettings( aeBaseFolder ); - } - - return instance; - } - - public Collection getNearByMeteorites( int dim, int chunkX, int chunkZ ) - { - Collection ll = new LinkedList(); - - synchronized( WorldSettings.class ) - { - for( int x = -1; x <= 1; x++ ) - { - for( int z = -1; z <= 1; z++ ) - { - int cx = x + ( chunkX >> 4 ); - int cz = z + ( chunkZ >> 4 ); - - NBTTagCompound data = this.loadSpawnData( dim, cx << 4, cz << 4 ); - - if( data != null ) - { - // edit. - int size = data.getInteger( "num" ); - for( int s = 0; s < size; s++ ) - { - ll.add( data.getCompoundTag( String.valueOf( s ) ) ); - } - } - } - } - } - - return ll; - } - - NBTTagCompound loadSpawnData( int dim, int chunkX, int chunkZ ) - { - if( !Thread.holdsLock( WorldSettings.class ) ) - { - throw new IllegalStateException( "Invalid Request" ); - } - - NBTTagCompound data = null; - File file = new File( this.spawnDataFolder, dim + '_' + ( chunkX >> 4 ) + '_' + ( chunkZ >> 4 ) + ".dat" ); - - if( file.isFile() ) - { - FileInputStream fileInputStream = null; - - try - { - fileInputStream = new FileInputStream( file ); - data = CompressedStreamTools.readCompressed( fileInputStream ); - } - catch( Throwable e ) - { - data = new NBTTagCompound(); - AELog.error( e ); - } - finally - { - if( fileInputStream != null ) - { - try - { - fileInputStream.close(); - } - catch( IOException e ) - { - AELog.error( e ); - } - } - } - } - else - { - data = new NBTTagCompound(); - } - - return data; - } - - public boolean hasGenerated( int dim, int chunkX, int chunkZ ) - { - synchronized( WorldSettings.class ) - { - NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ ); - return data.getBoolean( chunkX + "," + chunkZ ); - } - } - - public void setGenerated( int dim, int chunkX, int chunkZ ) - { - synchronized( WorldSettings.class ) - { - NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ ); - - // edit. - data.setBoolean( chunkX + "," + chunkZ, true ); - - this.writeSpawnData( dim, chunkX, chunkZ, data ); - } - } - - void writeSpawnData( int dim, int chunkX, int chunkZ, NBTTagCompound data ) - { - if( !Thread.holdsLock( WorldSettings.class ) ) - { - throw new IllegalStateException( "Invalid Request" ); - } - - File file = new File( this.spawnDataFolder, dim + '_' + ( chunkX >> 4 ) + '_' + ( chunkZ >> 4 ) + ".dat" ); - FileOutputStream fileOutputStream = null; - - try - { - fileOutputStream = new FileOutputStream( file ); - CompressedStreamTools.writeCompressed( data, fileOutputStream ); - } - catch( Throwable e ) - { - AELog.error( e ); - } - finally - { - if( fileOutputStream != null ) - { - try - { - fileOutputStream.close(); - } - catch( IOException e ) - { - AELog.error( e ); - } - } - } - } - - public boolean addNearByMeteorites( int dim, int chunkX, int chunkZ, NBTTagCompound newData ) - { - synchronized( WorldSettings.class ) - { - NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ ); - - // edit. - int size = data.getInteger( "num" ); - data.setTag( String.valueOf( size ), newData ); - data.setInteger( "num", size + 1 ); - - this.writeSpawnData( dim, chunkX, chunkZ, data ); - - return true; - } - } - - public void shutdown() - { - this.save(); - - for( Integer dimID : this.storageCellDims ) - { - DimensionManager.unregisterDimension( dimID ); - } - - this.storageCellDims.clear(); - - this.compass.kill(); - instance = null; - } - - @Override - public void save() - { - // populate new data - for( GridStorageSearch gs : this.loadedStorage.keySet() ) - { - GridStorage thisStorage = gs.gridStorage.get(); - if( thisStorage != null && thisStorage.getGrid() != null && !thisStorage.getGrid().isEmpty() ) - { - String value = thisStorage.getValue(); - this.get( "gridstorage", String.valueOf( thisStorage.getID() ), value ).set( value ); - } - } - - // save to files - if( this.hasChanged() ) - { - super.save(); - } - } - - public void addStorageCellDim( int newDim ) - { - this.storageCellDims.add( newDim ); - DimensionManager.registerDimension( newDim, AEConfig.instance.storageProviderID ); - - NetworkHandler.instance.sendToAll( new PacketNewStorageDimension( newDim ) ); - - String[] values = new String[this.storageCellDims.size()]; - - for( int x = 0; x < values.length; x++ ) - { - values[x] = String.valueOf( this.storageCellDims.get( x ) ); - } - - this.get( "DimensionManager", "StorageCells", new int[0] ).set( values ); - this.save(); - } - - public CompassService getCompass() - { - return this.compass; - } - - public void sendToPlayer( NetworkManager manager ) - { - if( manager != null ) - { - for( int newDim : this.get( "DimensionManager", "StorageCells", new int[0] ).getIntList() ) - { - manager.scheduleOutboundPacket( ( new PacketNewStorageDimension( newDim ) ).getProxy() ); - } - } - else - { - for( PlayerColor pc : TickHandler.INSTANCE.getPlayerColors().values() ) - { - NetworkHandler.instance.sendToAll( pc.getPacket() ); - } - } - } - - public void init() - { - this.save(); - } - - public WorldCoord getStoredSize( int dim ) - { - int x = this.get( "StorageCell" + dim, "scaleX", 0 ).getInt(); - int y = this.get( "StorageCell" + dim, "scaleY", 0 ).getInt(); - int z = this.get( "StorageCell" + dim, "scaleZ", 0 ).getInt(); - return new WorldCoord( x, y, z ); - } - - public void setStoredSize( int dim, int targetX, int targetY, int targetZ ) - { - this.get( "StorageCell" + dim, "scaleX", 0 ).set( targetX ); - this.get( "StorageCell" + dim, "scaleY", 0 ).set( targetY ); - this.get( "StorageCell" + dim, "scaleZ", 0 ).set( targetZ ); - this.save(); - } - - /** - * lazy loading, can load any id, even ones that don't exist anymore. - * - * @param storageID ID of grid storage - * - * @return corresponding grid storage - */ - public GridStorage getGridStorage( long storageID ) - { - GridStorageSearch gss = new GridStorageSearch( storageID ); - WeakReference result = this.loadedStorage.get( gss ); - - if( result == null || result.get() == null ) - { - String id = String.valueOf( storageID ); - String Data = this.get( "gridstorage", id, "" ).getString(); - GridStorage thisStorage = new GridStorage( Data, storageID, gss ); - gss.gridStorage = new WeakReference( thisStorage ); - this.loadedStorage.put( gss, new WeakReference( gss ) ); - return thisStorage; - } - - return result.get().gridStorage.get(); - } - - /** - * create a new storage - */ - public GridStorage getNewGridStorage() - { - long storageID = this.nextGridStorage(); - GridStorageSearch gss = new GridStorageSearch( storageID ); - GridStorage newStorage = new GridStorage( storageID, gss ); - gss.gridStorage = new WeakReference( newStorage ); - this.loadedStorage.put( gss, new WeakReference( gss ) ); - return newStorage; - } - - private long nextGridStorage() - { - long r = this.lastGridStorage; - this.lastGridStorage++; - this.get( "Counters", "lastGridStorage", this.lastGridStorage ).set( Long.toString( this.lastGridStorage ) ); - return r; - } - - public void destroyGridStorage( long id ) - { - String stringID = String.valueOf( id ); - this.getCategory( "gridstorage" ).remove( stringID ); - } - - public int getNextOrderedValue( String name ) - { - Property p = this.get( "orderedValues", name, 0 ); - int myValue = p.getInt(); - p.set( myValue + 1 ); - return myValue; - } - - public int getPlayerID( GameProfile profile ) - { - ConfigCategory playerList = this.getCategory( "players" ); - - if( playerList == null || profile == null || !profile.isComplete() ) - { - return -1; - } - - String uuid = profile.getId().toString(); - - Property prop = playerList.get( uuid ); - if( prop != null && prop.isIntValue() ) - { - return prop.getInt(); - } - else - { - playerList.put( uuid, prop = new Property( uuid, String.valueOf( this.nextPlayer() ), Property.Type.INTEGER ) ); - this.mappings.put( prop.getInt(), profile.getId() ); // add to reverse map - this.save(); - return prop.getInt(); - } - } - - private long nextPlayer() - { - long r = this.lastPlayer; - this.lastPlayer++; - this.get( "Counters", "lastPlayer", this.lastPlayer ).set( this.lastPlayer ); - return r; - } - - public EntityPlayer getPlayerFromID( int playerID ) - { - Optional maybe = this.mappings.get( playerID ); - - if( maybe.isPresent() ) - { - final UUID uuid = maybe.get(); - for( EntityPlayer player : CommonHelper.proxy.getPlayers() ) - { - if( player.getUniqueID().equals( uuid ) ) - { - return player; - } - } - } - - return null; - } -} diff --git a/src/main/java/appeng/core/features/registries/PlayerRegistry.java b/src/main/java/appeng/core/features/registries/PlayerRegistry.java index eda915f3..b6827f08 100644 --- a/src/main/java/appeng/core/features/registries/PlayerRegistry.java +++ b/src/main/java/appeng/core/features/registries/PlayerRegistry.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -19,12 +19,14 @@ package appeng.core.features.registries; +import javax.annotation.Nullable; + import com.mojang.authlib.GameProfile; import net.minecraft.entity.player.EntityPlayer; import appeng.api.features.IPlayerRegistry; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; public class PlayerRegistry implements IPlayerRegistry @@ -33,18 +35,19 @@ public class PlayerRegistry implements IPlayerRegistry @Override public int getID( GameProfile username ) { - return WorldSettings.getInstance().getPlayerID( username ); + return WorldData.instance().playerData().getPlayerID( username ); } @Override public int getID( EntityPlayer player ) { - return WorldSettings.getInstance().getPlayerID( player.getGameProfile() ); + return WorldData.instance().playerData().getPlayerID( player.getGameProfile() ); } + @Nullable @Override public EntityPlayer findPlayer( int playerID ) { - return WorldSettings.getInstance().getPlayerFromID( playerID ); + return WorldData.instance().playerData().getPlayerFromID( playerID ); } } diff --git a/src/main/java/appeng/core/sync/network/NetworkHandler.java b/src/main/java/appeng/core/sync/network/NetworkHandler.java index d5c775e2..16069d57 100644 --- a/src/main/java/appeng/core/sync/network/NetworkHandler.java +++ b/src/main/java/appeng/core/sync/network/NetworkHandler.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -31,8 +31,8 @@ import cpw.mods.fml.common.network.FMLNetworkEvent.ServerConnectionFromClientEve import cpw.mods.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent; import cpw.mods.fml.common.network.NetworkRegistry; -import appeng.core.WorldSettings; import appeng.core.sync.AppEngPacket; +import appeng.core.worlddata.WorldData; public class NetworkHandler @@ -83,7 +83,7 @@ public class NetworkHandler @SubscribeEvent public void newConnection( ServerConnectionFromClientEvent ev ) { - WorldSettings.getInstance().sendToPlayer( ev.manager ); + WorldData.instance().dimensionData().sendToPlayer( ev.manager ); } @SubscribeEvent @@ -91,7 +91,7 @@ public class NetworkHandler { if( loginEvent.player instanceof EntityPlayerMP ) { - WorldSettings.getInstance().sendToPlayer( null ); + WorldData.instance().dimensionData().sendToPlayer( null ); } } diff --git a/src/main/java/appeng/core/sync/packets/PacketCompassRequest.java b/src/main/java/appeng/core/sync/packets/PacketCompassRequest.java index f90cad6a..6208ca26 100644 --- a/src/main/java/appeng/core/sync/packets/PacketCompassRequest.java +++ b/src/main/java/appeng/core/sync/packets/PacketCompassRequest.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -26,10 +26,10 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import appeng.api.util.DimensionalCoord; -import appeng.core.WorldSettings; import appeng.core.sync.AppEngPacket; import appeng.core.sync.network.INetworkInfo; import appeng.core.sync.network.NetworkHandler; +import appeng.core.worlddata.WorldData; import appeng.services.compass.ICompassCallback; @@ -79,6 +79,6 @@ public class PacketCompassRequest extends AppEngPacket implements ICompassCallba this.talkBackTo = player; DimensionalCoord loc = new DimensionalCoord( player.worldObj, this.cx << 4, this.cdy << 5, this.cz << 4 ); - WorldSettings.getInstance().getCompass().getCompassDirection( loc, 174, this ); + WorldData.instance().compassData().service().getCompassDirection( loc, 174, this ); } } diff --git a/src/main/java/appeng/core/worlddata/CompassData.java b/src/main/java/appeng/core/worlddata/CompassData.java new file mode 100644 index 00000000..547c59ff --- /dev/null +++ b/src/main/java/appeng/core/worlddata/CompassData.java @@ -0,0 +1,66 @@ +/* + * 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 javax.annotation.Nonnull; + +import com.google.common.base.Preconditions; + +import appeng.services.CompassService; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +final class CompassData implements IWorldCompassData, IOnWorldStartable, IOnWorldStoppable +{ + @Nonnull + private final CompassService service; + + public CompassData( @Nonnull final File compassDirectory, @Nonnull final CompassService service ) + { + Preconditions.checkNotNull( compassDirectory ); + Preconditions.checkArgument( compassDirectory.isDirectory() ); + Preconditions.checkNotNull( service ); + + this.service = service; + } + + @Override + public CompassService service() + { + return this.service; + } + + @Override + public void onWorldStart() + { + + } + + @Override + public void onWorldStop() + { + this.service.kill(); + } +} diff --git a/src/main/java/appeng/core/worlddata/DimensionData.java b/src/main/java/appeng/core/worlddata/DimensionData.java new file mode 100644 index 00000000..72afd0c4 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/DimensionData.java @@ -0,0 +1,174 @@ +/* + * 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 javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; + +import net.minecraft.network.NetworkManager; +import net.minecraftforge.common.DimensionManager; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import appeng.api.util.WorldCoord; +import appeng.core.AEConfig; +import appeng.core.sync.network.NetworkHandler; +import appeng.core.sync.packets.PacketNewStorageDimension; +import appeng.hooks.TickHandler; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +final class DimensionData implements IWorldDimensionData, IOnWorldStartable, IOnWorldStoppable +{ + private static final String CONFIG_CATEGORY = "DimensionManager"; + private static final String CONFIG_KEY = "StorageCells"; + private static final int[] STORAGE_CELLS_DEFAULT = new int[0]; + + private static final String STORAGE_CELL_CATEGORY = "StorageCell"; + + private static final String STORAGE_CELL_SCALE_X_KEY = "scaleX"; + private static final String STORAGE_CELL_SCALE_Y_KEY = "scaleY"; + private static final String STORAGE_CELL_SCALE_Z_KEY = "scaleZ"; + + private static final String PACKAGE_DEST_CATEGORY = "DimensionManager"; + private static final String PACKAGE_KEY_CATEGORY = "StorageCells"; + private static final int[] PACKAGE_DEF_CATEGORY = new int[0]; + + private final Configuration config; + private final List storageCellDimensionIDs; + + DimensionData( @Nonnull final File parentFile, @Nonnull final String configVersion ) + { + Preconditions.checkNotNull( parentFile ); + Preconditions.checkArgument( parentFile.isFile() ); + Preconditions.checkNotNull( configVersion ); + Preconditions.checkArgument( !configVersion.isEmpty() ); + + this.config = new Configuration( parentFile, configVersion ); + + final int[] storageCellIDs = this.storageCellIDsProperty().getIntList(); + + this.storageCellDimensionIDs = Lists.newArrayList(); + for( int storageCellID : storageCellIDs ) + { + this.storageCellDimensionIDs.add( storageCellID ); + } + } + + private Property storageCellIDsProperty() + { + return this.config.get( CONFIG_CATEGORY, CONFIG_KEY, STORAGE_CELLS_DEFAULT ); + } + + @Override + public void onWorldStart() + { + for( Integer storageCellDimID : this.storageCellDimensionIDs ) + { + DimensionManager.registerDimension( storageCellDimID, AEConfig.instance.storageProviderID ); + } + + this.config.save(); + } + + @Override + public void onWorldStop() + { + this.config.save(); + + for( Integer storageCellDimID : this.storageCellDimensionIDs ) + { + DimensionManager.unregisterDimension( storageCellDimID ); + } + + this.storageCellDimensionIDs.clear(); + } + + @Override + public void addStorageCell( int newStorageCellID ) + { + this.storageCellDimensionIDs.add( newStorageCellID ); + DimensionManager.registerDimension( newStorageCellID, AEConfig.instance.storageProviderID ); + + NetworkHandler.instance.sendToAll( new PacketNewStorageDimension( newStorageCellID ) ); + + String[] values = new String[this.storageCellDimensionIDs.size()]; + + for( int x = 0; x < values.length; x++ ) + { + values[x] = String.valueOf( this.storageCellDimensionIDs.get( x ) ); + } + + this.storageCellIDsProperty().set( values ); + this.config.save(); + } + + @Override + public WorldCoord getStoredSize( int dim ) + { + final String category = STORAGE_CELL_CATEGORY + dim; + + final int x = this.config.get( category, STORAGE_CELL_SCALE_X_KEY, 0 ).getInt(); + final int y = this.config.get( category, STORAGE_CELL_SCALE_Y_KEY, 0 ).getInt(); + final int z = this.config.get( category, STORAGE_CELL_SCALE_Z_KEY, 0 ).getInt(); + + return new WorldCoord( x, y, z ); + } + + @Override + public void setStoredSize( int dim, int targetX, int targetY, int targetZ ) + { + final String category = STORAGE_CELL_CATEGORY + dim; + + this.config.get( category, STORAGE_CELL_SCALE_X_KEY, 0 ).set( targetX ); + this.config.get( category, STORAGE_CELL_SCALE_Y_KEY, 0 ).set( targetY ); + this.config.get( category, STORAGE_CELL_SCALE_Z_KEY, 0 ).set( targetZ ); + + this.config.save(); + } + + @Override + public void sendToPlayer( @Nullable final NetworkManager manager ) + { + if( manager != null ) + { + for( int newDim : this.config.get( PACKAGE_DEST_CATEGORY, PACKAGE_KEY_CATEGORY, PACKAGE_DEF_CATEGORY ).getIntList() ) + { + manager.scheduleOutboundPacket( ( new PacketNewStorageDimension( newDim ) ).getProxy() ); + } + } + else + { + for( TickHandler.PlayerColor pc : TickHandler.INSTANCE.getPlayerColors().values() ) + { + NetworkHandler.instance.sendToAll( pc.getPacket() ); + } + } + } +} diff --git a/src/main/java/appeng/core/worlddata/IOnWorldStartable.java b/src/main/java/appeng/core/worlddata/IOnWorldStartable.java new file mode 100644 index 00000000..b6c5c325 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IOnWorldStartable.java @@ -0,0 +1,30 @@ +/* + * 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; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IOnWorldStartable +{ + void onWorldStart(); +} diff --git a/src/main/java/appeng/core/worlddata/IOnWorldStoppable.java b/src/main/java/appeng/core/worlddata/IOnWorldStoppable.java new file mode 100644 index 00000000..7a36e771 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IOnWorldStoppable.java @@ -0,0 +1,30 @@ +/* + * 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; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IOnWorldStoppable +{ + void onWorldStop(); +} diff --git a/src/main/java/appeng/core/worlddata/IWorldCompassData.java b/src/main/java/appeng/core/worlddata/IWorldCompassData.java new file mode 100644 index 00000000..c4b74b85 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IWorldCompassData.java @@ -0,0 +1,33 @@ +/* + * 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 appeng.services.CompassService; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldCompassData +{ + CompassService service(); +} diff --git a/src/main/java/appeng/core/worlddata/IWorldData.java b/src/main/java/appeng/core/worlddata/IWorldData.java new file mode 100644 index 00000000..361b9a0f --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IWorldData.java @@ -0,0 +1,48 @@ +/* + * 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 javax.annotation.Nonnull; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldData +{ + void onServerStopping(); + + @Nonnull + IWorldGridStorageData storageData(); + + @Nonnull + IWorldPlayerData playerData(); + + @Nonnull + IWorldDimensionData dimensionData(); + + @Nonnull + IWorldCompassData compassData(); + + @Nonnull + IWorldSpawnData spawnData(); +} diff --git a/src/main/java/appeng/core/worlddata/IWorldDimensionData.java b/src/main/java/appeng/core/worlddata/IWorldDimensionData.java new file mode 100644 index 00000000..cc2319b0 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IWorldDimensionData.java @@ -0,0 +1,43 @@ +/* + * 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 javax.annotation.Nullable; + +import net.minecraft.network.NetworkManager; + +import appeng.api.util.WorldCoord; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldDimensionData +{ + void addStorageCell( int newStorageCellID ); + + WorldCoord getStoredSize( int dim ); + + void setStoredSize( int dim, int targetX, int targetY, int targetZ ); + + void sendToPlayer( @Nullable NetworkManager manager ); +} diff --git a/src/main/java/appeng/core/worlddata/IWorldGridStorageData.java b/src/main/java/appeng/core/worlddata/IWorldGridStorageData.java new file mode 100644 index 00000000..c579a324 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IWorldGridStorageData.java @@ -0,0 +1,46 @@ +/* + * 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 javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import appeng.me.GridStorage; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldGridStorageData +{ + @Nullable + GridStorage getGridStorage( long storageID ); + + @Nonnull + GridStorage getNewGridStorage(); + + long nextGridStorage(); + + void destroyGridStorage( long id ); + + int getNextOrderedValue( String name ); +} diff --git a/src/main/java/appeng/core/worlddata/IWorldPlayerData.java b/src/main/java/appeng/core/worlddata/IWorldPlayerData.java new file mode 100644 index 00000000..7d0f09bc --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IWorldPlayerData.java @@ -0,0 +1,40 @@ +/* + * 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 javax.annotation.Nullable; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.entity.player.EntityPlayer; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldPlayerData +{ + @Nullable + EntityPlayer getPlayerFromID( int playerID ); + + int getPlayerID( GameProfile profile ); +} diff --git a/src/main/java/appeng/core/worlddata/IWorldPlayerMapping.java b/src/main/java/appeng/core/worlddata/IWorldPlayerMapping.java new file mode 100644 index 00000000..73c70583 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IWorldPlayerMapping.java @@ -0,0 +1,54 @@ +/* + * 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.util.UUID; +import javax.annotation.Nonnull; + +import com.google.common.base.Optional; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldPlayerMapping +{ + /** + * Tries to retrieve the UUID of a player. + * Might not be stored inside of the map. + * Should not happen though. + * + * @param id ID of the to be searched player + * + * @return maybe the UUID of the searched player + */ + @Nonnull + Optional get( int id ); + + /** + * Put in new players when they join the server + * + * @param id id of new player + * @param uuid UUID of new player + */ + void put( int id, @Nonnull UUID uuid ); +} diff --git a/src/main/java/appeng/core/worlddata/IWorldSpawnData.java b/src/main/java/appeng/core/worlddata/IWorldSpawnData.java new file mode 100644 index 00000000..adfd6724 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/IWorldSpawnData.java @@ -0,0 +1,41 @@ +/* + * 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.util.Collection; + +import net.minecraft.nbt.NBTTagCompound; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +public interface IWorldSpawnData +{ + void setGenerated( int dim, int chunkX, int chunkZ ); + + boolean hasGenerated( int dim, int chunkX, int chunkZ ); + + boolean addNearByMeteorites( int dim, int chunkX, int chunkZ, NBTTagCompound newData ); + + Collection getNearByMeteorites( int dim, int chunkX, int chunkZ ); +} diff --git a/src/main/java/appeng/core/worlddata/MeteorDataNameEncoder.java b/src/main/java/appeng/core/worlddata/MeteorDataNameEncoder.java new file mode 100644 index 00000000..f5aa6d74 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/MeteorDataNameEncoder.java @@ -0,0 +1,82 @@ +/* + * 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 javax.annotation.Nonnull; + +import com.google.common.base.Preconditions; + + +/** + * encodes data into a common name + * + * @author thatsIch + * @version rv3 - 05.06.2015 + * @since rv3 05.06.2015 + */ +public class MeteorDataNameEncoder +{ + private static final char DATA_SEPARATOR = '_'; + private static final char BASE_EXTENSION_SEPARATOR = '.'; + private static final String FILE_EXTENSION = "dat"; + + private final char dataSeparator; + @Nonnull + private final String fileExtension; + private final char baseExtSeparator; + private final int bitScale; + + /** + * @param bitScale how often the coordinates will be shifted right (will scale coordinates down) + */ + public MeteorDataNameEncoder( final int bitScale ) + { + this( DATA_SEPARATOR, BASE_EXTENSION_SEPARATOR, FILE_EXTENSION, bitScale ); + } + + private MeteorDataNameEncoder( char dataSeparator, char baseExtSeparator, @Nonnull final String fileExtension, final int bitScale ) + { + Preconditions.checkNotNull( fileExtension ); + Preconditions.checkArgument( !fileExtension.isEmpty() ); + Preconditions.checkArgument( bitScale >= 0 ); + + this.dataSeparator = dataSeparator; + this.baseExtSeparator = baseExtSeparator; + this.fileExtension = fileExtension; + this.bitScale = bitScale; + } + + /** + * @param dimension ID of the processed dimension. Can be any integer + * @param chunkX X coordinate of the chunk. Can be any integer + * @param chunkZ Z coordinate of the chunk. Can be any integer + * + * @return encoded file name suggestion in form of dim_x_y.dat where x and y will be shifted to stay conform with the vanilla chunk system + * + * @since rv3 05.06.2015 + */ + public String encode( int dimension, int chunkX, int chunkZ ) + { + final int shiftedX = chunkX >> this.bitScale; + final int shiftedZ = chunkZ >> this.bitScale; + + return String.format( "%d%c%d%c%d%c%s", dimension, this.dataSeparator, shiftedX, this.dataSeparator, shiftedZ, this.baseExtSeparator, this.fileExtension ); + } +} diff --git a/src/main/java/appeng/core/worlddata/PlayerData.java b/src/main/java/appeng/core/worlddata/PlayerData.java new file mode 100644 index 00000000..46ed7ccb --- /dev/null +++ b/src/main/java/appeng/core/worlddata/PlayerData.java @@ -0,0 +1,148 @@ +/* + * 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.UUID; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.mojang.authlib.GameProfile; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import appeng.core.AELog; +import appeng.core.CommonHelper; + + +/** + * Handles the matching between UUIDs and internal IDs for security systems. + * This whole system could be replaced by storing directly the UUID, + * using a lot more traffic though + * + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +final class PlayerData implements IWorldPlayerData, IOnWorldStartable, IOnWorldStoppable +{ + private static final String LAST_PLAYER_CATEGORY = "Counters"; + private static final String LAST_PLAYER_KEY = "lastPlayer"; + private static final int LAST_PLAYER_DEFAULT = 0; + + private final Configuration config; + private final IWorldPlayerMapping playerMapping; + + private int lastPlayerID; + + public PlayerData( @Nonnull final File configFile, @Nonnull final String configVersion ) + { + Preconditions.checkNotNull( configFile ); + Preconditions.checkArgument( configFile.isFile() ); + Preconditions.checkNotNull( configVersion ); + Preconditions.checkArgument( !configVersion.isEmpty() ); + + this.config = new Configuration( configFile, configVersion ); + + final ConfigCategory playerList = this.config.getCategory( "players" ); + this.playerMapping = new PlayerMapping( playerList, AELog.INSTANCE ); + } + + @Nullable + @Override + public EntityPlayer getPlayerFromID( int playerID ) + { + final Optional maybe = this.playerMapping.get( playerID ); + + if( maybe.isPresent() ) + { + final UUID uuid = maybe.get(); + for( EntityPlayer player : CommonHelper.proxy.getPlayers() ) + { + if( player.getUniqueID().equals( uuid ) ) + { + return player; + } + } + } + + return null; + } + + @Override + public int getPlayerID( @Nonnull final GameProfile profile ) + { + Preconditions.checkNotNull( profile ); + + final ConfigCategory players = this.config.getCategory( "players" ); + + if( players == null || !profile.isComplete() ) + { + return -1; + } + + final String uuid = profile.getId().toString(); + + final Property maybePlayerID = players.get( uuid ); + if( maybePlayerID != null && maybePlayerID.isIntValue() ) + { + return maybePlayerID.getInt(); + } + else + { + final int newPlayerID = this.nextPlayer(); + final Property newPlayer = new Property( uuid, String.valueOf( newPlayerID ), Property.Type.INTEGER ); + players.put( uuid, newPlayer ); + this.playerMapping.put( newPlayerID, profile.getId() ); // add to reverse map + this.config.save(); + + return newPlayerID; + } + } + + private int nextPlayer() + { + final int r = this.lastPlayerID; + this.lastPlayerID++; + this.config.get( LAST_PLAYER_CATEGORY, LAST_PLAYER_KEY, this.lastPlayerID ).set( this.lastPlayerID ); + return r; + } + + @Override + public void onWorldStart() + { + this.lastPlayerID = this.config.get( LAST_PLAYER_CATEGORY, LAST_PLAYER_KEY, LAST_PLAYER_DEFAULT ).getInt( LAST_PLAYER_DEFAULT ); + + this.config.save(); + } + + @Override + public void onWorldStop() + { + this.config.save(); + + this.lastPlayerID = 0; + } +} diff --git a/src/main/java/appeng/core/PlayerMappings.java b/src/main/java/appeng/core/worlddata/PlayerMapping.java similarity index 73% rename from src/main/java/appeng/core/PlayerMappings.java rename to src/main/java/appeng/core/worlddata/PlayerMapping.java index 9dc96bd0..8756718d 100644 --- a/src/main/java/appeng/core/PlayerMappings.java +++ b/src/main/java/appeng/core/worlddata/PlayerMapping.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -16,13 +16,15 @@ * along with Applied Energistics 2. If not, see . */ -package appeng.core; +package appeng.core.worlddata; import java.util.Map; import java.util.UUID; +import javax.annotation.Nonnull; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; import net.minecraftforge.common.config.ConfigCategory; @@ -34,7 +36,7 @@ import cpw.mods.fml.relauncher.FMLRelaunchLog; * Will grant access to a pre initialized player map * based on the "players" category in the settings.cfg */ -public class PlayerMappings +final class PlayerMapping implements IWorldPlayerMapping { /** * View of player mappings, is not immutable, @@ -43,22 +45,15 @@ public class PlayerMappings */ private final Map mappings; - public PlayerMappings( ConfigCategory category, FMLRelaunchLog log ) + public PlayerMapping( ConfigCategory category, FMLRelaunchLog log ) { final PlayerMappingsInitializer init = new PlayerMappingsInitializer( category, log ); this.mappings = init.getPlayerMappings(); } - /** - * Tries to retrieve the UUID of a player. - * Might not be stored inside of the map. - * Should not happen though. - * - * @param id ID of the to be searched player - * - * @return maybe the UUID of the searched player - */ + @Nonnull + @Override public Optional get( int id ) { final UUID maybe = this.mappings.get( id ); @@ -66,14 +61,11 @@ public class PlayerMappings return Optional.fromNullable( maybe ); } - /** - * Put in new players when they join the server - * - * @param id id of new player - * @param uuid UUID of new player - */ - public void put( int id, UUID uuid ) + @Override + public void put( int id, @Nonnull UUID uuid ) { + Preconditions.checkNotNull( uuid ); + this.mappings.put( id, uuid ); } } diff --git a/src/main/java/appeng/core/PlayerMappingsInitializer.java b/src/main/java/appeng/core/worlddata/PlayerMappingsInitializer.java similarity index 88% rename from src/main/java/appeng/core/PlayerMappingsInitializer.java rename to src/main/java/appeng/core/worlddata/PlayerMappingsInitializer.java index 97cbf8f5..16e8d145 100644 --- a/src/main/java/appeng/core/PlayerMappingsInitializer.java +++ b/src/main/java/appeng/core/worlddata/PlayerMappingsInitializer.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -16,7 +16,7 @@ * along with Applied Energistics 2. If not, see . */ -package appeng.core; +package appeng.core.worlddata; import java.util.HashMap; @@ -28,13 +28,14 @@ import net.minecraftforge.common.config.Property; import cpw.mods.fml.relauncher.FMLRelaunchLog; +import appeng.core.AELog; import appeng.util.UUIDMatcher; /** * Initializes a map of ID to UUID from the player list in the settings.cfg */ -public class PlayerMappingsInitializer +class PlayerMappingsInitializer { /** * Internal immutable mapping @@ -52,7 +53,7 @@ public class PlayerMappingsInitializer * @param playerList the category for the player list, generally extracted using the "players" tag * @param log the logger used to warn the server or user of faulty entries */ - public PlayerMappingsInitializer( ConfigCategory playerList, FMLRelaunchLog log ) + PlayerMappingsInitializer( ConfigCategory playerList, FMLRelaunchLog log ) { // Matcher for UUIDs final UUIDMatcher matcher = new UUIDMatcher(); @@ -71,9 +72,9 @@ public class PlayerMappingsInitializer if( matcher.isUUID( maybeUUID ) ) { - final UUID UUIDString = UUID.fromString( maybeUUID ); + final UUID uuidString = UUID.fromString( maybeUUID ); - this.playerMappings.put( id, UUIDString ); + this.playerMappings.put( id, uuidString ); } else { diff --git a/src/main/java/appeng/core/worlddata/SpawnData.java b/src/main/java/appeng/core/worlddata/SpawnData.java new file mode 100644 index 00000000..79b2a733 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/SpawnData.java @@ -0,0 +1,227 @@ +/* + * 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.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedList; +import javax.annotation.Nonnull; + +import com.google.common.base.Preconditions; + +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; + +import appeng.core.AELog; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +final class SpawnData implements IWorldSpawnData, IOnWorldStartable, IOnWorldStoppable +{ + @Nonnull + private final File spawnDirectory; + @Nonnull + private final MeteorDataNameEncoder encoder; + + public SpawnData( @Nonnull final File spawnDirectory ) + { + Preconditions.checkNotNull( spawnDirectory ); + Preconditions.checkArgument( spawnDirectory.isDirectory() ); + + this.spawnDirectory = spawnDirectory; + this.encoder = new MeteorDataNameEncoder( 4 ); + } + + @Override + public void onWorldStart() + { + + } + + @Override + public void setGenerated( int dim, int chunkX, int chunkZ ) { + synchronized( SpawnData.class ) + { + NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ ); + + // edit. + data.setBoolean( chunkX + "," + chunkZ, true ); + + this.writeSpawnData( dim, chunkX, chunkZ, data ); + } + } + + @Override + public boolean hasGenerated( int dim, int chunkX, int chunkZ ) + { + synchronized( SpawnData.class ) + { + NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ ); + return data.getBoolean( chunkX + "," + chunkZ ); + } + } + + @Override + public boolean addNearByMeteorites( int dim, int chunkX, int chunkZ, NBTTagCompound newData ) + { + synchronized( SpawnData.class ) + { + NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ ); + + // edit. + int size = data.getInteger( "num" ); + data.setTag( String.valueOf( size ), newData ); + data.setInteger( "num", size + 1 ); + + this.writeSpawnData( dim, chunkX, chunkZ, data ); + + return true; + } + } + + @Override + public Collection getNearByMeteorites( int dim, int chunkX, int chunkZ ) + { + Collection ll = new LinkedList(); + + synchronized( SpawnData.class ) + { + for( int x = -1; x <= 1; x++ ) + { + for( int z = -1; z <= 1; z++ ) + { + int cx = x + ( chunkX >> 4 ); + int cz = z + ( chunkZ >> 4 ); + + NBTTagCompound data = this.loadSpawnData( dim, cx << 4, cz << 4 ); + + if( data != null ) + { + // edit. + int size = data.getInteger( "num" ); + for( int s = 0; s < size; s++ ) + { + ll.add( data.getCompoundTag( String.valueOf( s ) ) ); + } + } + } + } + } + + return ll; + } + + @Override + public void onWorldStop() + { + + } + + private NBTTagCompound loadSpawnData( int dim, int chunkX, int chunkZ ) + { + if( !Thread.holdsLock( SpawnData.class ) ) + { + throw new IllegalStateException( "Invalid Request" ); + } + + NBTTagCompound data = null; + final String fileName = this.encoder.encode( dim, chunkX, chunkZ ); + final File file = new File( this.spawnDirectory, fileName ); + + if( file.isFile() ) + { + FileInputStream fileInputStream = null; + + try + { + fileInputStream = new FileInputStream( file ); + data = CompressedStreamTools.readCompressed( fileInputStream ); + } + catch( Throwable e ) + { + data = new NBTTagCompound(); + AELog.error( e ); + } + finally + { + if( fileInputStream != null ) + { + try + { + fileInputStream.close(); + } + catch( IOException e ) + { + AELog.error( e ); + } + } + } + } + else + { + data = new NBTTagCompound(); + } + + return data; + } + + private void writeSpawnData( int dim, int chunkX, int chunkZ, NBTTagCompound data ) + { + if( !Thread.holdsLock( SpawnData.class ) ) + { + throw new IllegalStateException( "Invalid Request" ); + } + + final String fileName = this.encoder.encode( dim, chunkX, chunkZ ); + final File file = new File( this.spawnDirectory, fileName ); + FileOutputStream fileOutputStream = null; + + try + { + fileOutputStream = new FileOutputStream( file ); + CompressedStreamTools.writeCompressed( data, fileOutputStream ); + } + catch( Throwable e ) + { + AELog.error( e ); + } + finally + { + if( fileOutputStream != null ) + { + try + { + fileOutputStream.close(); + } + catch( IOException e ) + { + AELog.error( e ); + } + } + } + } +} diff --git a/src/main/java/appeng/core/worlddata/StorageData.java b/src/main/java/appeng/core/worlddata/StorageData.java new file mode 100644 index 00000000..134ea95c --- /dev/null +++ b/src/main/java/appeng/core/worlddata/StorageData.java @@ -0,0 +1,166 @@ +/* + * 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.lang.ref.WeakReference; +import java.util.Map; +import java.util.WeakHashMap; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.google.common.base.Preconditions; + +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; + +import appeng.core.AELog; +import appeng.me.GridStorage; +import appeng.me.GridStorageSearch; + + +/** + * @author thatsIch + * @version rv3 - 30.05.2015 + * @since rv3 30.05.2015 + */ +final class StorageData implements IWorldGridStorageData, IOnWorldStartable, IOnWorldStoppable +{ + private static final String LAST_GRID_STORAGE_CATEGORY = "Counters"; + private static final String LAST_GRID_STORAGE_KEY = "lastGridStorage"; + private static final int LAST_GRID_STORAGE_DEFAULT = 0; + + private static final String GRID_STORAGE_CATEGORY = "gridstorage"; + + private final Map> loadedStorage = new WeakHashMap>( 10 ); + private final Configuration config; + + private long lastGridStorage; + + public StorageData( @Nonnull final File settingsFile, @Nonnull final String version ) + { + Preconditions.checkNotNull( settingsFile ); + Preconditions.checkArgument( settingsFile.isFile() ); + Preconditions.checkNotNull( version ); + Preconditions.checkArgument( !version.isEmpty() ); + + this.config = new Configuration( settingsFile, version ); + } + + /** + * lazy loading, can load any id, even ones that don't exist anymore. + * + * @param storageID ID of grid storage + * + * @return corresponding grid storage + */ + @Nullable + @Override + public GridStorage getGridStorage( long storageID ) + { + GridStorageSearch gss = new GridStorageSearch( storageID ); + WeakReference result = this.loadedStorage.get( gss ); + + if( result == null || result.get() == null ) + { + String id = String.valueOf( storageID ); + String data = this.config.get( "gridstorage", id, "" ).getString(); + GridStorage thisStorage = new GridStorage( data, storageID, gss ); + gss.gridStorage = new WeakReference( thisStorage ); + this.loadedStorage.put( gss, new WeakReference( gss ) ); + return thisStorage; + } + + return result.get().gridStorage.get(); + } + + /** + * create a new storage + */ + @Nonnull + @Override + public GridStorage getNewGridStorage() + { + long storageID = this.nextGridStorage(); + GridStorageSearch gss = new GridStorageSearch( storageID ); + GridStorage newStorage = new GridStorage( storageID, gss ); + gss.gridStorage = new WeakReference( newStorage ); + this.loadedStorage.put( gss, new WeakReference( gss ) ); + + return newStorage; + } + + @Override + public long nextGridStorage() + { + long r = this.lastGridStorage; + this.lastGridStorage++; + this.config.get( "Counters", "lastGridStorage", this.lastGridStorage ).set( Long.toString( this.lastGridStorage ) ); + return r; + } + + @Override + public void destroyGridStorage( long id ) + { + String stringID = String.valueOf( id ); + this.config.getCategory( "gridstorage" ).remove( stringID ); + } + + @Override + public int getNextOrderedValue( String name ) + { + Property p = this.config.get( "orderedValues", name, 0 ); + int myValue = p.getInt(); + p.set( myValue + 1 ); + return myValue; + } + + @Override + public void onWorldStart() + { + final String lastString = this.config.get( LAST_GRID_STORAGE_CATEGORY, LAST_GRID_STORAGE_KEY, LAST_GRID_STORAGE_DEFAULT ).getString(); + + try + { + this.lastGridStorage = Long.parseLong( lastString ); + } + catch( NumberFormatException err ) + { + AELog.warning( "The config contained a value which was not represented as a Long: %s", lastString ); + + this.lastGridStorage = 0; + } + } + + @Override + public void onWorldStop() + { + // populate new data + for( GridStorageSearch gs : this.loadedStorage.keySet() ) + { + GridStorage thisStorage = gs.gridStorage.get(); + if( thisStorage != null && thisStorage.getGrid() != null && !thisStorage.getGrid().isEmpty() ) + { + String value = thisStorage.getValue(); + this.config.get( GRID_STORAGE_CATEGORY, String.valueOf( thisStorage.getID() ), value ).set( value ); + } + } + } +} diff --git a/src/main/java/appeng/core/worlddata/WorldData.java b/src/main/java/appeng/core/worlddata/WorldData.java new file mode 100644 index 00000000..a140ffe9 --- /dev/null +++ b/src/main/java/appeng/core/worlddata/WorldData.java @@ -0,0 +1,204 @@ +/* + * 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 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 - 30.05.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 WorldData( @Nonnull final File worldDirectory ) + { + Preconditions.checkNotNull( worldDirectory ); + Preconditions.checkArgument( worldDirectory.isDirectory() ); + + this.ae2directory = new File( worldDirectory, AE2_DIRECTORY_NAME ); + final File settingsFile = new File( this.ae2directory, SETTING_FILE_NAME ); + this.spawnDirectory = new File( this.ae2directory, SPAWNDATA_DIR_NAME ); + + final PlayerData playerData = new PlayerData( settingsFile, AEConfig.VERSION ); + final DimensionData dimensionData = new DimensionData( settingsFile, AEConfig.VERSION ); + final StorageData storageData = new StorageData( settingsFile, AEConfig.VERSION ); + + this.compassDirectory = new File( this.ae2directory, COMPASS_DIR_NAME ); + final ThreadFactory compassThreadFactory = new CompassThreadFactory(); + final CompassService compassService = new CompassService( this.compassDirectory, compassThreadFactory ); + final CompassData compassData = new CompassData( this.compassDirectory, compassService ); + + final SpawnData 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, compassData, spawnData ); + this.stoppables = Lists.newArrayList( playerData, dimensionData, storageData, compassData, spawnData ); + } + + /** + * @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( IOnWorldStartable startable : this.startables ) + { + startable.onWorldStart(); + } + + this.startables.clear(); + } + + @Override + public void onServerStopping() + { + Preconditions.checkNotNull( instance ); + + for( IOnWorldStoppable stoppable : this.stoppables ) + { + stoppable.onWorldStop(); + } + + 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; + } +} diff --git a/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java b/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java index 2fb53457..b7241f90 100644 --- a/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java +++ b/src/main/java/appeng/items/storage/ItemSpatialStorageCell.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -33,9 +33,9 @@ import net.minecraftforge.common.DimensionManager; import appeng.api.implementations.TransitionResult; import appeng.api.implementations.items.ISpatialStorageCell; import appeng.api.util.WorldCoord; -import appeng.core.WorldSettings; import appeng.core.features.AEFeature; import appeng.core.localization.GuiText; +import appeng.core.worlddata.WorldData; import appeng.items.AEBaseItem; import appeng.spatial.StorageHelper; import appeng.spatial.StorageWorldProvider; @@ -110,7 +110,7 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag if( Platform.isServer() ) { int dim = c.getInteger( "StorageDim" ); - return WorldSettings.getInstance().getStoredSize( dim ); + return WorldData.instance().dimensionData().getStoredSize( dim ); } else { @@ -187,7 +187,7 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag NBTTagCompound c = Platform.openNbtData( is ); int newDim = DimensionManager.getNextFreeDimId(); c.setInteger( "StorageDim", newDim ); - WorldSettings.getInstance().addStorageCellDim( newDim ); + WorldData.instance().dimensionData().addStorageCell( newDim ); DimensionManager.initDimension( newDim ); return DimensionManager.getWorld( newDim ); } @@ -201,7 +201,7 @@ public class ItemSpatialStorageCell extends AEBaseItem implements ISpatialStorag c.setInteger( "sizeX", targetX ); c.setInteger( "sizeY", targetY ); c.setInteger( "sizeZ", targetZ ); - WorldSettings.getInstance().setStoredSize( dim, targetX, targetY, targetZ ); + WorldData.instance().dimensionData().setStoredSize( dim, targetX, targetY, targetZ ); } } } diff --git a/src/main/java/appeng/me/Grid.java b/src/main/java/appeng/me/Grid.java index 7c137402..80c18318 100644 --- a/src/main/java/appeng/me/Grid.java +++ b/src/main/java/appeng/me/Grid.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -36,7 +36,7 @@ import appeng.api.networking.IMachineSet; import appeng.api.networking.events.MENetworkEvent; import appeng.api.networking.events.MENetworkPostCacheConstruction; import appeng.api.util.IReadOnlyCollection; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; import appeng.hooks.TickHandler; import appeng.util.ReadOnlyCollection; @@ -166,7 +166,7 @@ public class Grid implements IGrid { if( this.myStorage == null ) { - this.myStorage = WorldSettings.getInstance().getNewGridStorage(); + this.myStorage = WorldData.instance().storageData().getNewGridStorage(); this.myStorage.setGrid( this ); } @@ -189,7 +189,7 @@ public class Grid implements IGrid } else if( this.myStorage == null ) { - this.myStorage = WorldSettings.getInstance().getNewGridStorage(); + this.myStorage = WorldData.instance().storageData().getNewGridStorage(); this.myStorage.setGrid( this ); } diff --git a/src/main/java/appeng/me/GridNode.java b/src/main/java/appeng/me/GridNode.java index 8c09df41..1401bf2f 100644 --- a/src/main/java/appeng/me/GridNode.java +++ b/src/main/java/appeng/me/GridNode.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -49,7 +49,7 @@ import appeng.api.networking.pathing.IPathingGrid; import appeng.api.util.AEColor; import appeng.api.util.DimensionalCoord; import appeng.api.util.IReadOnlyCollection; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; import appeng.hooks.TickHandler; import appeng.me.pathfinding.IPathItem; import appeng.util.ReadOnlyCollection; @@ -328,7 +328,10 @@ public class GridNode implements IGridNode, IPathItem NBTTagCompound node = nodeData.getCompoundTag( name ); this.playerID = node.getInteger( "p" ); this.lastSecurityKey = node.getLong( "k" ); - this.setGridStorage( WorldSettings.getInstance().getGridStorage( node.getLong( "g" ) ) ); + + final long storageID = node.getLong( "g" ); + final GridStorage gridStorage = WorldData.instance().storageData().getGridStorage( storageID ); + this.setGridStorage( gridStorage ); } else { diff --git a/src/main/java/appeng/me/GridStorage.java b/src/main/java/appeng/me/GridStorage.java index e7262fce..53d45a98 100644 --- a/src/main/java/appeng/me/GridStorage.java +++ b/src/main/java/appeng/me/GridStorage.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -31,7 +31,7 @@ import net.minecraft.nbt.NBTTagCompound; import appeng.api.networking.IGrid; import appeng.api.networking.IGridStorage; import appeng.core.AELog; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; public class GridStorage implements IGridStorage @@ -157,6 +157,6 @@ public class GridStorage implements IGridStorage public void remove() { - WorldSettings.getInstance().destroyGridStorage( this.myID ); + WorldData.instance().storageData().destroyGridStorage( this.myID ); } } diff --git a/src/main/java/appeng/me/cache/SecurityCache.java b/src/main/java/appeng/me/cache/SecurityCache.java index a42bcfea..1ef0df51 100644 --- a/src/main/java/appeng/me/cache/SecurityCache.java +++ b/src/main/java/appeng/me/cache/SecurityCache.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -24,6 +24,9 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; +import com.google.common.base.Preconditions; +import com.mojang.authlib.GameProfile; + import net.minecraft.entity.player.EntityPlayer; import appeng.api.config.SecurityPermissions; @@ -35,7 +38,7 @@ import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkSecurityChange; import appeng.api.networking.security.ISecurityGrid; import appeng.api.networking.security.ISecurityProvider; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; import appeng.me.GridNode; @@ -149,7 +152,13 @@ public class SecurityCache implements ISecurityGrid @Override public boolean hasPermission( EntityPlayer player, SecurityPermissions perm ) { - return this.hasPermission( player == null ? -1 : WorldSettings.getInstance().getPlayerID( player.getGameProfile() ), perm ); + Preconditions.checkNotNull( player ); + Preconditions.checkNotNull( perm ); + + final GameProfile profile = player.getGameProfile(); + final int playerID = WorldData.instance().playerData().getPlayerID( profile ); + + return this.hasPermission( playerID, perm ); } @Override diff --git a/src/main/java/appeng/me/helpers/AENetworkProxy.java b/src/main/java/appeng/me/helpers/AENetworkProxy.java index 59f86f25..f756d8c2 100644 --- a/src/main/java/appeng/me/helpers/AENetworkProxy.java +++ b/src/main/java/appeng/me/helpers/AENetworkProxy.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -22,6 +22,8 @@ package appeng.me.helpers; import java.util.Collections; import java.util.EnumSet; +import com.mojang.authlib.GameProfile; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -44,7 +46,7 @@ import appeng.api.networking.ticking.ITickManager; import appeng.api.util.AEColor; import appeng.api.util.DimensionalCoord; import appeng.api.util.IOrientable; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; import appeng.hooks.TickHandler; import appeng.me.GridAccessException; import appeng.me.cache.P2PCache; @@ -163,7 +165,10 @@ public class AENetworkProxy implements IGridBlock } else if( this.node != null && this.owner != null ) { - this.node.setPlayerID( WorldSettings.getInstance().getPlayerID( this.owner.getGameProfile() ) ); + final GameProfile profile = this.owner.getGameProfile(); + final int playerID = WorldData.instance().playerData().getPlayerID( profile ); + + this.node.setPlayerID( playerID ); this.owner = null; } } diff --git a/src/main/java/appeng/services/CompassService.java b/src/main/java/appeng/services/CompassService.java index 1bf8c24a..b037ca78 100644 --- a/src/main/java/appeng/services/CompassService.java +++ b/src/main/java/appeng/services/CompassService.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -27,9 +27,10 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; - import javax.annotation.Nonnull; +import com.google.common.base.Preconditions; + import net.minecraft.block.Block; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -40,18 +41,27 @@ import appeng.services.compass.CompassReader; import appeng.services.compass.ICompassCallback; -public class CompassService implements ThreadFactory +public final class CompassService { private static final int CHUNK_SIZE = 16; - private final Map worldSet = new HashMap(); - private final ExecutorService executor; - private final File rootFolder; - private int jobSize = 0; - public CompassService( File aEFolder ) + private final Map worldSet = new HashMap( 10 ); + private final ExecutorService executor; + + /** + * AE2 Folder for each world + */ + private final File worldCompassFolder; + + private int jobSize; + + public CompassService( @Nonnull final File worldCompassFolder, @Nonnull final ThreadFactory factory ) { - this.rootFolder = aEFolder; - this.executor = Executors.newSingleThreadExecutor( this ); + Preconditions.checkNotNull( worldCompassFolder ); + Preconditions.checkArgument( worldCompassFolder.isDirectory() ); + + this.worldCompassFolder = worldCompassFolder; + this.executor = Executors.newSingleThreadExecutor( factory ); this.jobSize = 0; } @@ -131,7 +141,7 @@ public class CompassService implements ThreadFactory if( cr == null ) { - cr = new CompassReader( w.provider.dimensionId, this.rootFolder ); + cr = new CompassReader( w.provider.dimensionId, this.worldCompassFolder ); this.worldSet.put( w, cr ); } @@ -176,12 +186,6 @@ public class CompassService implements ThreadFactory } } - @Override - public Thread newThread( @Nonnull Runnable job ) - { - return new Thread( job, "AE Compass Service" ); - } - private class CMUpdatePost implements Runnable { diff --git a/src/main/java/appeng/services/compass/CompassReader.java b/src/main/java/appeng/services/compass/CompassReader.java index 676d8826..7cc42b02 100644 --- a/src/main/java/appeng/services/compass/CompassReader.java +++ b/src/main/java/appeng/services/compass/CompassReader.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -21,18 +21,25 @@ package appeng.services.compass; import java.io.File; import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nonnull; + +import com.google.common.base.Preconditions; -public class CompassReader +public final class CompassReader { - private final HashMap regions = new HashMap(); + private final Map regions = new HashMap( 100 ); private final int dimensionId; - private final File rootFolder; + private final File worldCompassFolder; - public CompassReader( int dimensionId, File rootFolder ) + public CompassReader( int dimensionId, @Nonnull final File worldCompassFolder ) { + Preconditions.checkNotNull( worldCompassFolder ); + Preconditions.checkArgument( worldCompassFolder.isDirectory() ); + this.dimensionId = dimensionId; - this.rootFolder = rootFolder; + this.worldCompassFolder = worldCompassFolder; } public void close() @@ -60,7 +67,7 @@ public class CompassReader CompassRegion cr = this.regions.get( pos ); if( cr == null ) { - cr = new CompassRegion( cx, cz, this.dimensionId, this.rootFolder ); + cr = new CompassRegion( cx, cz, this.dimensionId, this.worldCompassFolder ); this.regions.put( pos, cr ); } diff --git a/src/main/java/appeng/services/compass/CompassRegion.java b/src/main/java/appeng/services/compass/CompassRegion.java index 8f3beaf8..27f86860 100644 --- a/src/main/java/appeng/services/compass/CompassRegion.java +++ b/src/main/java/appeng/services/compass/CompassRegion.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -23,55 +23,56 @@ import java.io.File; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; +import javax.annotation.Nonnull; -import appeng.core.AELog; +import com.google.common.base.Preconditions; + +import appeng.core.worlddata.MeteorDataNameEncoder; -public class CompassRegion +public final class CompassRegion { - final int low_x; - final int low_z; + private final int lowX; + private final int lowZ; + private final int world; + private final File worldCompassFolder; + private final MeteorDataNameEncoder encoder; - final int hi_x; - final int hi_z; + private boolean hasFile = false; + private RandomAccessFile raf = null; + private ByteBuffer buffer; - final int world; - final File rootFolder; - boolean hasFile = false; - RandomAccessFile raf = null; - ByteBuffer buffer; - - public CompassRegion( int cx, int cz, int worldID, File rootFolder ) + public CompassRegion( int cx, int cz, int worldID, @Nonnull final File worldCompassFolder ) { + Preconditions.checkNotNull( worldCompassFolder ); + Preconditions.checkArgument( worldCompassFolder.isDirectory() ); this.world = worldID; - this.rootFolder = rootFolder; + this.worldCompassFolder = worldCompassFolder; + this.encoder = new MeteorDataNameEncoder( 0 ); int region_x = cx >> 10; int region_z = cz >> 10; - this.low_x = region_x << 10; - this.low_z = region_z << 10; - - this.hi_x = this.low_x + 1024; - this.hi_z = this.low_z + 1024; + this.lowX = region_x << 10; + this.lowZ = region_z << 10; this.openFile( false ); } private void openFile( boolean create ) { - File fName = this.getFileName(); if( this.hasFile ) { return; } - if( create || this.fileExists( fName ) ) + final File file = this.getFile(); + if( create || this.isFileExistent( file ) ) { try { - this.raf = new RandomAccessFile( fName, "rw" ); + this.raf = new RandomAccessFile( file, "rw" ); FileChannel fc = this.raf.getChannel(); this.buffer = fc.map( FileChannel.MapMode.READ_WRITE, 0, 0x400 * 0x400 );// fc.size() ); this.hasFile = true; @@ -83,25 +84,16 @@ public class CompassRegion } } - private File getFileName() + private File getFile() { - String folder = this.rootFolder.getPath() + File.separatorChar + "compass"; - File folderFile = new File( folder ); + final String fileName = this.encoder.encode( this.world, this.lowX, this.lowZ); - if( !folderFile.exists() || !folderFile.isDirectory() ) - { - if( !folderFile.mkdir() ) - { - AELog.info( "Failed to create AE2/compass/" ); - } - } - - return new File( folder, this.world + '_' + this.low_x + '_' + this.low_z + ".dat" ); + return new File( this.worldCompassFolder, fileName ); } - private boolean fileExists( File name ) + private boolean isFileExistent( File file ) { - return name.exists() && name.isFile(); + return file.exists() && file.isFile(); } public void close() diff --git a/src/main/java/appeng/services/compass/CompassThreadFactory.java b/src/main/java/appeng/services/compass/CompassThreadFactory.java new file mode 100644 index 00000000..aca42c93 --- /dev/null +++ b/src/main/java/appeng/services/compass/CompassThreadFactory.java @@ -0,0 +1,42 @@ +/* + * 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.services.compass; + + +import java.util.concurrent.ThreadFactory; +import javax.annotation.Nonnull; + +import com.google.common.base.Preconditions; + + +/** + * @author thatsIch + * @version rv3 - 31.05.2015 + * @since rv3 31.05.2015 + */ +public final class CompassThreadFactory implements ThreadFactory +{ + @Override + public Thread newThread( @Nonnull final Runnable job ) + { + Preconditions.checkNotNull( job ); + + return new Thread( job, "AE Compass Service" ); + } +} diff --git a/src/main/java/appeng/spatial/CachedPlane.java b/src/main/java/appeng/spatial/CachedPlane.java index 3338167a..b6cd0fae 100644 --- a/src/main/java/appeng/spatial/CachedPlane.java +++ b/src/main/java/appeng/spatial/CachedPlane.java @@ -39,7 +39,7 @@ import appeng.api.movable.IMovableHandler; import appeng.api.movable.IMovableRegistry; import appeng.api.util.WorldCoord; import appeng.core.AELog; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; import appeng.util.Platform; @@ -348,7 +348,7 @@ public class CachedPlane for( int y = 1; y < 255; y += 32 ) { - WorldSettings.getInstance().getCompass().updateArea( this.world, c.xPosition << 4, y, c.zPosition << 4 ); + WorldData.instance().compassData().service().updateArea( this.world, c.xPosition << 4, y, c.zPosition << 4 ); } Platform.sendChunk( c, this.verticalBits ); diff --git a/src/main/java/appeng/worldgen/MeteoritePlacer.java b/src/main/java/appeng/worldgen/MeteoritePlacer.java index 2beecd44..b79a54e1 100644 --- a/src/main/java/appeng/worldgen/MeteoritePlacer.java +++ b/src/main/java/appeng/worldgen/MeteoritePlacer.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -41,8 +41,8 @@ import appeng.api.definitions.IBlockDefinition; import appeng.api.definitions.IBlocks; import appeng.api.definitions.IMaterials; import appeng.core.AEConfig; -import appeng.core.WorldSettings; import appeng.core.features.AEFeature; +import appeng.core.worlddata.WorldData; import appeng.util.InventoryAdaptor; import appeng.util.Platform; import appeng.worldgen.meteorite.Fallout; @@ -265,7 +265,7 @@ public final class MeteoritePlacer if( Math.random() > PRESSES_SPAWN_CHANCE ) { - r = WorldSettings.getInstance().getNextOrderedValue( "presses" ); + r = WorldData.instance().storageData().getNextOrderedValue( "presses" ); } else { @@ -573,7 +573,7 @@ public final class MeteoritePlacer this.settings.setInteger( "skyMode", skyMode ); w.done(); - WorldSettings.getInstance().addNearByMeteorites( w.getWorld().provider.dimensionId, x >> 4, z >> 4, this.settings ); + WorldData.instance().spawnData().addNearByMeteorites( w.getWorld().provider.dimensionId, x >> 4, z >> 4, this.settings ); return true; } return false; diff --git a/src/main/java/appeng/worldgen/MeteoriteWorldGen.java b/src/main/java/appeng/worldgen/MeteoriteWorldGen.java index 6320c06e..90b8a681 100644 --- a/src/main/java/appeng/worldgen/MeteoriteWorldGen.java +++ b/src/main/java/appeng/worldgen/MeteoriteWorldGen.java @@ -1,6 +1,6 @@ /* * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. + * 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 @@ -19,7 +19,6 @@ package appeng.worldgen; -import java.util.Collection; import java.util.Random; import java.util.concurrent.Callable; @@ -31,8 +30,8 @@ import cpw.mods.fml.common.IWorldGenerator; import appeng.api.features.IWorldGen.WorldGenType; import appeng.core.AEConfig; -import appeng.core.WorldSettings; import appeng.core.features.registries.WorldGenRegistry; +import appeng.core.worlddata.WorldData; import appeng.hooks.TickHandler; import appeng.util.Platform; import appeng.worldgen.meteorite.ChunkOnly; @@ -61,7 +60,7 @@ public final class MeteoriteWorldGen implements IWorldGenerator } else { - WorldSettings.getInstance().getCompass().updateArea( w, chunkX, chunkZ ); + WorldData.instance().compassData().service().updateArea( w, chunkX, chunkZ ); } } @@ -87,7 +86,7 @@ public final class MeteoriteWorldGen implements IWorldGenerator continue; } - if( WorldSettings.getInstance().hasGenerated( w.provider.dimensionId, cx, cz ) ) + if( WorldData.instance().spawnData().hasGenerated( w.provider.dimensionId, cx, cz ) ) { MeteoritePlacer mp2 = new MeteoritePlacer(); mp2.spawnMeteorite( new ChunkOnly( w, cx, cz ), mp.getSettings() ); @@ -109,9 +108,9 @@ public final class MeteoriteWorldGen implements IWorldGenerator return false; } - private Collection getNearByMeteorites( World w, int chunkX, int chunkZ ) + private Iterable getNearByMeteorites( World w, int chunkX, int chunkZ ) { - return WorldSettings.getInstance().getNearByMeteorites( w.provider.dimensionId, chunkX, chunkZ ); + return WorldData.instance().spawnData().getNearByMeteorites( w.provider.dimensionId, chunkX, chunkZ ); } class MeteoriteSpawn implements Callable @@ -154,8 +153,8 @@ public final class MeteoriteWorldGen implements IWorldGenerator MeteoriteWorldGen.this.tryMeteorite( this.w, this.depth, this.x, this.z ); } - WorldSettings.getInstance().setGenerated( this.w.provider.dimensionId, chunkX, chunkZ ); - WorldSettings.getInstance().getCompass().updateArea( this.w, chunkX, chunkZ ); + WorldData.instance().spawnData().setGenerated( this.w.provider.dimensionId, chunkX, chunkZ ); + WorldData.instance().compassData().service().updateArea( this.w, chunkX, chunkZ ); return null; } diff --git a/src/test/java/appeng/core/worlddata/MeteorDataNameEncoderTest.java b/src/test/java/appeng/core/worlddata/MeteorDataNameEncoderTest.java new file mode 100644 index 00000000..f66575b0 --- /dev/null +++ b/src/test/java/appeng/core/worlddata/MeteorDataNameEncoderTest.java @@ -0,0 +1,65 @@ +/* + * 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 org.junit.Assert; +import org.junit.Test; + + +/** + * Tests for {@link MeteorDataNameEncoder} + * + * @author thatsIch + * @version rv3 - 06.06.2015 + * @since rv3 06.06.2015 + */ +public class MeteorDataNameEncoderTest +{ + private static final int WITHOUT_DIMENSION = -5; + private static final int WITHOUT_CHUNK_X = 0; + private static final int WITHOUT_CHUNK_Z = 13; + private static final String WITHOUT_EXPECTED = "-5_0_13.dat"; + + private static final int WITH_DIMENSION = 3; + private static final int WITH_CHUNK_X = 32; + private static final int WITH_CHUNK_Z = -64; + private static final String WITH_EXPECTED = "3_2_-4.dat"; + + private final MeteorDataNameEncoder encoderWithZeroShifting = new MeteorDataNameEncoder( 0 ); + private final MeteorDataNameEncoder encoderWithFourShifting = new MeteorDataNameEncoder( 4 ); + + @Test + public void testEncoderWithoutShifting() + { + final String expected = WITHOUT_EXPECTED; + final String actual = this.encoderWithZeroShifting.encode( WITHOUT_DIMENSION, WITHOUT_CHUNK_X, WITHOUT_CHUNK_Z ); + + Assert.assertEquals( expected, actual ); + } + + @Test + public void testEncoderWithShifting() + { + final String expected = WITH_EXPECTED; + final String actual = this.encoderWithFourShifting.encode( WITH_DIMENSION, WITH_CHUNK_X, WITH_CHUNK_Z ); + + Assert.assertEquals( expected, actual ); + } +}