/*
* 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
{
@Nonnull
private final File spawnDirectory;
@Nonnull
private final MeteorDataNameEncoder encoder;
public SpawnData( @Nonnull final File spawnDirectory )
{
Preconditions.checkNotNull( spawnDirectory );
this.spawnDirectory = spawnDirectory;
this.encoder = new MeteorDataNameEncoder( 4 );
}
@Override
public void setGenerated( final int dim, final int chunkX, final int chunkZ )
{
synchronized( SpawnData.class )
{
final NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ );
// edit.
data.setBoolean( chunkX + "," + chunkZ, true );
this.writeSpawnData( dim, chunkX, chunkZ, data );
}
}
@Override
public boolean hasGenerated( final int dim, final int chunkX, final int chunkZ )
{
synchronized( SpawnData.class )
{
final NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ );
return data.getBoolean( chunkX + "," + chunkZ );
}
}
@Override
public boolean addNearByMeteorites( final int dim, final int chunkX, final int chunkZ, final NBTTagCompound newData )
{
synchronized( SpawnData.class )
{
final NBTTagCompound data = this.loadSpawnData( dim, chunkX, chunkZ );
// edit.
final 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( final int dim, final int chunkX, final int chunkZ )
{
final Collection<NBTTagCompound> ll = new LinkedList<NBTTagCompound>();
synchronized( SpawnData.class )
{
for( int x = -1; x <= 1; x++ )
{
for( int z = -1; z <= 1; z++ )
{
final int cx = x + ( chunkX >> 4 );
final int cz = z + ( chunkZ >> 4 );
final NBTTagCompound data = this.loadSpawnData( dim, cx << 4, cz << 4 );
if( data != null )
{
// edit.
final int size = data.getInteger( "num" );
for( int s = 0; s < size; s++ )
{
ll.add( data.getCompoundTag( String.valueOf( s ) ) );
}
}
}
}
}
return ll;
}
private NBTTagCompound loadSpawnData( final int dim, final int chunkX, final 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( final Throwable e )
{
data = new NBTTagCompound();
AELog.debug( e );
}
finally
{
if( fileInputStream != null )
{
try
{
fileInputStream.close();
}
catch( final IOException e )
{
AELog.debug( e );
}
}
}
}
else
{
data = new NBTTagCompound();
}
return data;
}
private void writeSpawnData( final int dim, final int chunkX, final int chunkZ, final 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( final Throwable e )
{
AELog.debug( e );
}
finally
{
if( fileOutputStream != null )
{
try
{
fileOutputStream.close();
}
catch( final IOException e )
{
AELog.debug( e );
}
}
}
}
}