Improves the message generated when generating the folder for the compass data.

Outsources the encoding of the compass data into the file name
Written tests for the encoding
Did some internal cleaning of the class

Conflicts:
	src/main/java/appeng/block/solids/BlockSkyStone.java
	src/main/java/appeng/core/WorldSettings.java
	src/main/java/appeng/core/features/registries/PlayerRegistry.java
	src/main/java/appeng/core/sync/network/NetworkHandler.java
	src/main/java/appeng/core/worlddata/PlayerMapping.java
	src/main/java/appeng/core/worlddata/PlayerMappingsInitializer.java
	src/main/java/appeng/services/CompassService.java
	src/main/java/appeng/worldgen/MeteoritePlacer.java
	src/main/java/appeng/worldgen/MeteoriteWorldGen.java
This commit is contained in:
thatsIch 2015-05-28 20:01:21 +02:00 committed by thatsIch
parent a62d9bfcbf
commit 863b57fc3b
39 changed files with 1718 additions and 646 deletions

View File

@ -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 );
}

View File

@ -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() );
}
}
}

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<Integer> storageCellDims = new ArrayList<Integer>();
private final File spawnDataFolder;
private final CompassService compass;
private final PlayerMappings mappings;
private final Map<GridStorageSearch, WeakReference<GridStorageSearch>> loadedStorage = new WeakHashMap<GridStorageSearch, WeakReference<GridStorageSearch>>();
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<NBTTagCompound> getNearByMeteorites( int dim, int chunkX, int chunkZ )
{
Collection<NBTTagCompound> ll = new LinkedList<NBTTagCompound>();
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<GridStorageSearch> 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<GridStorage>( thisStorage );
this.loadedStorage.put( gss, new WeakReference<GridStorageSearch>( 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<GridStorage>( newStorage );
this.loadedStorage.put( gss, new WeakReference<GridStorageSearch>( 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<UUID> 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;
}
}

View File

@ -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 );
}
}

View File

@ -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 )
{
;
}
}
}

View File

@ -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 );
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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();
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<Integer> 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() );
}
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.worlddata;
/**
* @author thatsIch
* @version rv3 - 30.05.2015
* @since rv3 30.05.2015
*/
public interface IOnWorldStartable
{
void onWorldStart();
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.core.worlddata;
/**
* @author thatsIch
* @version rv3 - 30.05.2015
* @since rv3 30.05.2015
*/
public interface IOnWorldStoppable
{
void onWorldStop();
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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();
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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();
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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 );
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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 );
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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 );
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<UUID> 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 );
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<NBTTagCompound> getNearByMeteorites( int dim, int chunkX, int chunkZ );
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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 <tt>dim_x_y.dat</tt> where <tt>x</tt> and <tt>y</tt> 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 );
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<UUID> 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;
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<Integer, UUID> 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<UUID> 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 );
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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
{

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<NBTTagCompound> getNearByMeteorites( int dim, int chunkX, int chunkZ )
{
Collection<NBTTagCompound> ll = new LinkedList<NBTTagCompound>();
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 );
}
}
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<GridStorageSearch, WeakReference<GridStorageSearch>> loadedStorage = new WeakHashMap<GridStorageSearch, WeakReference<GridStorageSearch>>( 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<GridStorageSearch> 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<GridStorage>( thisStorage );
this.loadedStorage.put( gss, new WeakReference<GridStorageSearch>( 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<GridStorage>( newStorage );
this.loadedStorage.put( gss, new WeakReference<GridStorageSearch>( 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 );
}
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<IOnWorldStartable> startables;
private final List<IOnWorldStoppable> 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.<IOnWorldStartable>newArrayList( playerData, dimensionData, storageData, compassData, spawnData );
this.stoppables = Lists.<IOnWorldStoppable>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;
}
}

View File

@ -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 );
}
}
}

View File

@ -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 );
}

View File

@ -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
{

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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<World, CompassReader> worldSet = new HashMap<World, CompassReader>();
private final ExecutorService executor;
private final File rootFolder;
private int jobSize = 0;
public CompassService( File aEFolder )
private final Map<World, CompassReader> worldSet = new HashMap<World, CompassReader>( 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
{

View File

@ -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<Long, CompassRegion> regions = new HashMap<Long, CompassRegion>();
private final Map<Long, CompassRegion> regions = new HashMap<Long, CompassRegion>( 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 );
}

View File

@ -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()

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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" );
}
}

View File

@ -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 );

View File

@ -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;

View File

@ -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<NBTTagCompound> getNearByMeteorites( World w, int chunkX, int chunkZ )
private Iterable<NBTTagCompound> 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;
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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 );
}
}