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 1f961e29..f27fe2d4 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 @@ -21,6 +21,8 @@ package appeng.block.solids; import java.util.EnumSet; +import com.google.common.base.Optional; + import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; @@ -29,12 +31,11 @@ import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import appeng.block.AEBaseBlock; -import appeng.core.WorldSettings; -import appeng.core.features.AEFeature; -import appeng.util.Platform; -import com.google.common.base.Optional; +import appeng.block.AEBaseBlock; +import appeng.core.features.AEFeature; +import appeng.core.worlddata.WorldData; +import appeng.util.Platform; public class BlockSkyStone extends AEBaseBlock @@ -93,7 +94,7 @@ public class BlockSkyStone extends AEBaseBlock super.onBlockAdded( w, pos, state ); if( Platform.isServer() ) { - WorldSettings.getInstance().getCompass().updateArea( w, pos.getX(), pos.getY(), pos.getZ() ); + WorldData.instance().compassData().service().updateArea( w, pos.getX(), pos.getY(), pos.getZ() ); } } @@ -118,7 +119,7 @@ public class BlockSkyStone extends AEBaseBlock super.breakBlock( w, pos, state ); if( Platform.isServer() ) { - WorldSettings.getInstance().getCompass().updateArea( w, pos.getX(), pos.getY(), pos.getZ() ); + WorldData.instance().compassData().service().updateArea( w, pos.getX(), pos.getY(), pos.getZ() ); } } } diff --git a/src/main/java/appeng/core/AppEng.java b/src/main/java/appeng/core/AppEng.java index 1b2267f4..82040113 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 4279a47c..00000000 --- a/src/main/java/appeng/core/WorldSettings.java +++ /dev/null @@ -1,489 +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 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; - -import com.google.common.base.Optional; -import com.mojang.authlib.GameProfile; - - -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.sendPacket( ( 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 cc77f546..06767109 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 net.minecraft.entity.player.EntityPlayer; -import appeng.api.features.IPlayerRegistry; -import appeng.core.WorldSettings; +import javax.annotation.Nullable; import com.mojang.authlib.GameProfile; +import net.minecraft.entity.player.EntityPlayer; +import appeng.api.features.IPlayerRegistry; +import appeng.core.worlddata.WorldData; + public class PlayerRegistry implements IPlayerRegistry { @@ -32,18 +34,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 8dec11f2..0174fd66 100644 --- a/src/main/java/appeng/core/sync/network/NetworkHandler.java +++ b/src/main/java/appeng/core/sync/network/NetworkHandler.java @@ -30,13 +30,12 @@ import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientCustomPacketE import net.minecraftforge.fml.common.network.FMLNetworkEvent.ServerConnectionFromClientEvent; import net.minecraftforge.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent; import net.minecraftforge.fml.common.network.NetworkRegistry; -import appeng.core.WorldSettings; -import appeng.core.sync.AppEngPacket; +import appeng.core.sync.AppEngPacket; +import appeng.core.worlddata.WorldData; public class NetworkHandler { - public static NetworkHandler instance; final FMLEventChannel ec; @@ -82,7 +81,7 @@ public class NetworkHandler @SubscribeEvent public void newConnection( ServerConnectionFromClientEvent ev ) { - WorldSettings.getInstance().sendToPlayer( ev.manager ); + WorldData.instance().dimensionData().sendToPlayer( ev.manager ); } @SubscribeEvent @@ -90,7 +89,7 @@ public class NetworkHandler { if( loginEvent.player instanceof EntityPlayerMP ) { - WorldSettings.getInstance().sendToPlayer( null ); + WorldData.instance().dimensionData().sendToPlayer( null ); } } @@ -104,9 +103,9 @@ public class NetworkHandler { this.serveHandler.onPacketData( null, ev.handler, ev.packet, srv.playerEntity ); } - catch ( final ThreadQuickExitException ext ) + catch ( final ThreadQuickExitException ignored ) { - ; + } } } @@ -120,9 +119,9 @@ public class NetworkHandler { this.clientHandler.onPacketData( null, ev.handler, ev.packet, null ); } - catch ( final ThreadQuickExitException ext ) + catch ( final ThreadQuickExitException ignored ) { - ; + } } } diff --git a/src/main/java/appeng/core/sync/packets/PacketCompassRequest.java b/src/main/java/appeng/core/sync/packets/PacketCompassRequest.java index 990049d5..3ed8d979 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 @@ -24,10 +24,10 @@ import io.netty.buffer.Unpooled; 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; @@ -77,6 +77,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..f22954bf --- /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.sendPacket( ( 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 332113bf..b2d23c0e 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,11 +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; import net.minecraftforge.fml.relauncher.FMLRelaunchLog; @@ -33,7 +37,7 @@ import com.google.common.base.Optional; * 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, @@ -42,22 +46,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 ); @@ -65,14 +62,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 a37df014..b82f8341 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; @@ -26,13 +26,15 @@ import java.util.UUID; import net.minecraftforge.common.config.ConfigCategory; import net.minecraftforge.common.config.Property; import net.minecraftforge.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 @@ -50,7 +52,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(); @@ -69,9 +71,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 540e83a8..f29e2e9e 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 @@ -30,9 +30,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; @@ -109,7 +109,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 { @@ -186,7 +186,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 ); } @@ -200,7 +200,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 f0d2813e..c35a4c0c 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 @@ -50,7 +50,7 @@ import appeng.api.util.AEColor; import appeng.api.util.AEPartLocation; 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; @@ -330,7 +330,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 760574be..e1a9402f 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 @@ -30,7 +30,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 @@ -156,6 +156,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 baf8b410..125571d7 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; import appeng.api.networking.IGrid; @@ -34,7 +37,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; @@ -148,7 +151,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 eae1bdb7..d4f77b2c 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; @@ -43,7 +45,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; @@ -162,7 +164,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 407968f7..1e08fce4 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; @@ -39,18 +40,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; } @@ -130,7 +140,7 @@ public class CompassService implements ThreadFactory if( cr == null ) { - cr = new CompassReader( w.provider.getDimensionId(), this.rootFolder ); + cr = new CompassReader( w.provider.getDimensionId(), this.worldCompassFolder ); this.worldSet.put( w, cr ); } @@ -175,12 +185,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 ada7360b..f37042e4 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.IMovableRegistry; import appeng.api.util.AEPartLocation; import appeng.api.util.WorldCoord; import appeng.core.AELog; -import appeng.core.WorldSettings; +import appeng.core.worlddata.WorldData; import appeng.util.Platform; @@ -353,7 +353,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 15c34afe..7a619964 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 @@ -42,8 +42,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; @@ -272,7 +272,7 @@ public final class MeteoritePlacer if( Math.random() > PRESSES_SPAWN_CHANCE ) { - r = WorldSettings.getInstance().getNextOrderedValue( "presses" ); + r = WorldData.instance().storageData().getNextOrderedValue( "presses" ); } else { @@ -579,7 +579,7 @@ public final class MeteoritePlacer this.settings.setInteger( "skyMode", skyMode ); w.done(); - WorldSettings.getInstance().addNearByMeteorites( w.getWorld().provider.getDimensionId(), x >> 4, z >> 4, this.settings ); + WorldData.instance().spawnData().addNearByMeteorites( w.getWorld().provider.getDimensionId(), 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 3adca8d8..388eabac 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; @@ -29,8 +28,8 @@ import net.minecraft.world.chunk.IChunkProvider; import net.minecraftforge.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; @@ -59,7 +58,7 @@ public final class MeteoriteWorldGen implements IWorldGenerator } else { - WorldSettings.getInstance().getCompass().updateArea( w, chunkX, chunkZ ); + WorldData.instance().compassData().service().updateArea( w, chunkX, chunkZ ); } } @@ -85,7 +84,7 @@ public final class MeteoriteWorldGen implements IWorldGenerator continue; } - if( WorldSettings.getInstance().hasGenerated( w.provider.getDimensionId(), cx, cz ) ) + if( WorldData.instance().spawnData().hasGenerated( w.provider.getDimensionId(), cx, cz ) ) { MeteoritePlacer mp2 = new MeteoritePlacer(); mp2.spawnMeteorite( new ChunkOnly( w, cx, cz ), mp.getSettings() ); @@ -107,9 +106,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.getDimensionId(), chunkX, chunkZ ); + return WorldData.instance().spawnData().getNearByMeteorites( w.provider.getDimensionId(), chunkX, chunkZ ); } class MeteoriteSpawn implements Callable @@ -152,8 +151,8 @@ public final class MeteoriteWorldGen implements IWorldGenerator MeteoriteWorldGen.this.tryMeteorite( this.w, this.depth, this.x, this.z ); } - WorldSettings.getInstance().setGenerated( this.w.provider.getDimensionId(), chunkX, chunkZ ); - WorldSettings.getInstance().getCompass().updateArea( this.w, chunkX, chunkZ ); + WorldData.instance().spawnData().setGenerated( this.w.provider.getDimensionId(), 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 ); + } +}