Skip to content

Commit

Permalink
Encode NBT_PRIMARY_STATE as a string when saving crossworld format.
Browse files Browse the repository at this point in the history
  • Loading branch information
AlgorithmX2 committed Feb 12, 2017
1 parent 4147928 commit 8e941bb
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 133 deletions.
Expand Up @@ -5,13 +5,15 @@
import mod.chiselsandbits.chiseledblock.data.VoxelBlob;
import mod.chiselsandbits.chiseledblock.data.VoxelBlob.BlobStats;
import mod.chiselsandbits.chiseledblock.data.VoxelBlobStateReference;
import mod.chiselsandbits.chiseledblock.serialization.StringStates;
import mod.chiselsandbits.core.ChiselsAndBits;
import mod.chiselsandbits.helpers.ModUtil;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagString;

public class NBTBlobConverter
{
Expand Down Expand Up @@ -124,7 +126,16 @@ public final void writeChisleData(
final byte[] voxelBytes = newFormat == format ? voxelRef.getByteArray() : voxelRef.getVoxelBlob().blobToBytes( newFormat );

compound.setInteger( NBT_LIGHTVALUE, lightValue );
compound.setInteger( NBT_PRIMARY_STATE, primaryBlockState );

if ( crossWorld )
{
compound.setString( NBT_PRIMARY_STATE, StringStates.getNameFromStateID( primaryBlockState ) );
}
else
{
compound.setInteger( NBT_PRIMARY_STATE, primaryBlockState );
}

compound.setInteger( NBT_SIDE_FLAGS, sideState );
compound.setBoolean( NBT_NORMALCUBE_FLAG, isNormalCube );
compound.setByteArray( NBT_VERSIONED_VOXEL, voxelBytes );
Expand All @@ -148,7 +159,15 @@ public final boolean readChisleData(
}

sideState = compound.getInteger( NBT_SIDE_FLAGS );
primaryBlockState = compound.getInteger( NBT_PRIMARY_STATE );

if ( compound.getTag( NBT_PRIMARY_STATE ) instanceof NBTTagString )
{
primaryBlockState = StringStates.getStateIDFromName( compound.getString( NBT_PRIMARY_STATE ) );
}
{
primaryBlockState = compound.getInteger( NBT_PRIMARY_STATE );
}

lightValue = compound.getInteger( NBT_LIGHTVALUE );
isNormalCube = compound.getBoolean( NBT_NORMALCUBE_FLAG );
byte[] v = compound.getByteArray( NBT_VERSIONED_VOXEL );
Expand Down
@@ -1,21 +1,7 @@
package mod.chiselsandbits.chiseledblock.serialization;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import com.google.common.base.Optional;

import mod.chiselsandbits.chiseledblock.data.VoxelBlob;
import mod.chiselsandbits.core.Log;
import mod.chiselsandbits.helpers.ModUtil;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.ResourceLocation;

public class CrossWorldBlobSerializer extends BlobSerializer
{
Expand All @@ -39,130 +25,15 @@ protected int readStateID(
final String name = buffer.readStringFromBuffer( 2047 );
buffer.readStringFromBuffer( 2047 );

final String parts[] = name.split( "[?&]" );

try
{
parts[0] = URLDecoder.decode( parts[0], "UTF-8" );
}
catch ( final UnsupportedEncodingException e )
{
Log.logError( "Failed to reload Property from store data : " + name, e );
}

final Block blk = Block.REGISTRY.getObject( new ResourceLocation( parts[0] ) );

if ( blk == null || blk == Blocks.AIR )
{
return 0;
}

IBlockState state = blk.getDefaultState();

if ( state == null )
{
return 0;
}

// rebuild state...
for ( int x = 1; x < parts.length; ++x )
{
try
{
if ( parts[x].length() > 0 )
{
final String nameval[] = parts[x].split( "[=]" );
if ( nameval.length == 2 )
{
nameval[0] = URLDecoder.decode( nameval[0], "UTF-8" );
nameval[1] = URLDecoder.decode( nameval[1], "UTF-8" );

state = withState( state, blk, nameval );
}
}
}
catch ( final Exception err )
{
Log.logError( "Failed to reload Property from store data : " + name, err );
}
}

return ModUtil.getStateId( state );
}

@SuppressWarnings( { "unchecked", "rawtypes" } )
private IBlockState withState(
final IBlockState state,
final Block blk,
final String[] nameval )
{
final IProperty prop = blk.getBlockState().getProperty( nameval[0] );
if ( prop == null )
{
Log.info( nameval[0] + " is not a valid property for " + Block.REGISTRY.getNameForObject( blk ) );
return state;
}

final Optional pv = prop.parseValue( nameval[1] );
if ( pv.isPresent() )
{
return state.withProperty( prop, pv.get() );
}
else
{
Log.info( nameval[1] + " is not a valid value of " + nameval[0] + " for " + Block.REGISTRY.getNameForObject( blk ) );
return state;
}
return StringStates.getStateIDFromName( name );
}

@Override
protected void writeStateID(
final PacketBuffer buffer,
final int key )
{
final IBlockState state = ModUtil.getStateById( key );
final Block blk = state.getBlock();

String sname = "air?";

try
{
final StringBuilder stateName = new StringBuilder( URLEncoder.encode( Block.REGISTRY.getNameForObject( blk ).toString(), "UTF-8" ) );
stateName.append( '?' );

boolean first = true;
for ( final IProperty<?> P : state.getPropertyNames() )
{
if ( !first )
{
stateName.append( '&' );
}

first = false;

final Comparable<?> propVal = state.getProperties().get( P );

String saveAs;
if ( propVal instanceof IStringSerializable )
{
saveAs = ( (IStringSerializable) propVal ).getName();
}
else
{
saveAs = propVal.toString();
}

stateName.append( URLEncoder.encode( P.getName(), "UTF-8" ) );
stateName.append( '=' );
stateName.append( URLEncoder.encode( saveAs, "UTF-8" ) );
}

sname = stateName.toString();
}
catch ( final UnsupportedEncodingException e )
{
Log.logError( "Failed to Serialize State", e );
}
final String sname = StringStates.getNameFromStateID( key );

buffer.writeString( sname );
buffer.writeString( "" ); // extra data for later use.
Expand Down
@@ -0,0 +1,150 @@
package mod.chiselsandbits.chiseledblock.serialization;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import com.google.common.base.Optional;

import mod.chiselsandbits.core.Log;
import mod.chiselsandbits.helpers.ModUtil;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.ResourceLocation;

public class StringStates
{

public static int getStateIDFromName(
final String name )
{
final String parts[] = name.split( "[?&]" );

try
{
parts[0] = URLDecoder.decode( parts[0], "UTF-8" );
}
catch ( final UnsupportedEncodingException e )
{
Log.logError( "Failed to reload Property from store data : " + name, e );
}

final Block blk = Block.REGISTRY.getObject( new ResourceLocation( parts[0] ) );

if ( blk == null || blk == Blocks.AIR )
{
return 0;
}

IBlockState state = blk.getDefaultState();

if ( state == null )
{
return 0;
}

// rebuild state...
for ( int x = 1; x < parts.length; ++x )
{
try
{
if ( parts[x].length() > 0 )
{
final String nameval[] = parts[x].split( "[=]" );
if ( nameval.length == 2 )
{
nameval[0] = URLDecoder.decode( nameval[0], "UTF-8" );
nameval[1] = URLDecoder.decode( nameval[1], "UTF-8" );

state = withState( state, blk, nameval );
}
}
}
catch ( final Exception err )
{
Log.logError( "Failed to reload Property from store data : " + name, err );
}
}

return ModUtil.getStateId( state );
}

@SuppressWarnings( { "unchecked", "rawtypes" } )
private static IBlockState withState(
final IBlockState state,
final Block blk,
final String[] nameval )
{
final IProperty prop = blk.getBlockState().getProperty( nameval[0] );
if ( prop == null )
{
Log.info( nameval[0] + " is not a valid property for " + Block.REGISTRY.getNameForObject( blk ) );
return state;
}

final Optional pv = prop.parseValue( nameval[1] );
if ( pv.isPresent() )
{
return state.withProperty( prop, pv.get() );
}
else
{
Log.info( nameval[1] + " is not a valid value of " + nameval[0] + " for " + Block.REGISTRY.getNameForObject( blk ) );
return state;
}
}

public static String getNameFromStateID(
final int key )
{
final IBlockState state = ModUtil.getStateById( key );
final Block blk = state.getBlock();

String sname = "air?";

try
{
final StringBuilder stateName = new StringBuilder( URLEncoder.encode( Block.REGISTRY.getNameForObject( blk ).toString(), "UTF-8" ) );
stateName.append( '?' );

boolean first = true;
for ( final IProperty<?> P : state.getPropertyNames() )
{
if ( !first )
{
stateName.append( '&' );
}

first = false;

final Comparable<?> propVal = state.getProperties().get( P );

String saveAs;
if ( propVal instanceof IStringSerializable )
{
saveAs = ( (IStringSerializable) propVal ).getName();
}
else
{
saveAs = propVal.toString();
}

stateName.append( URLEncoder.encode( P.getName(), "UTF-8" ) );
stateName.append( '=' );
stateName.append( URLEncoder.encode( saveAs, "UTF-8" ) );
}

sname = stateName.toString();
}
catch ( final UnsupportedEncodingException e )
{
Log.logError( "Failed to Serialize State", e );
}

return sname;
}

}

0 comments on commit 8e941bb

Please sign in to comment.