Merge pull request #1341 from thatsIch/b-1339-server-crash

Fixes #1339: Was not able to retrieve the name of an unregistered part
This commit is contained in:
thatsIch
2015-04-28 18:42:42 +02:00
2 changed files with 134 additions and 139 deletions
@@ -3,8 +3,6 @@ package appeng.core.api.definitions;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import com.google.common.base.Optional;
import appeng.api.definitions.IBlockDefinition; import appeng.api.definitions.IBlockDefinition;
import appeng.api.definitions.IItemDefinition; import appeng.api.definitions.IItemDefinition;
import appeng.api.definitions.ITileDefinition; import appeng.api.definitions.ITileDefinition;
@@ -91,13 +89,9 @@ public class DefinitionConstructor
for( AEColor color : AEColor.values() ) for( AEColor color : AEColor.values() )
{ {
ItemStackSrc multiPartSource = target.createPart( type, color ); final ItemStackSrc multiPartSource = target.createPart( type, color );
final Optional<ItemStackSrc> maybeSource = Optional.fromNullable( multiPartSource );
if( maybeSource.isPresent() ) definition.add( color, multiPartSource );
{
definition.add( color, multiPartSource );
}
} }
return definition; return definition;
@@ -19,6 +19,7 @@
package appeng.items.parts; package appeng.items.parts;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@@ -28,6 +29,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.client.renderer.texture.IIconRegister;
@@ -41,6 +43,8 @@ import net.minecraft.world.World;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
import com.google.common.base.Preconditions;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.implementations.items.IItemGroup; import appeng.api.implementations.items.IItemGroup;
import appeng.api.parts.IPart; import appeng.api.parts.IPart;
@@ -48,7 +52,6 @@ import appeng.api.parts.IPartHelper;
import appeng.api.parts.IPartItem; import appeng.api.parts.IPartItem;
import appeng.api.util.AEColor; import appeng.api.util.AEColor;
import appeng.core.AEConfig; import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.AEFeature; import appeng.core.features.AEFeature;
import appeng.core.features.ItemStackSrc; import appeng.core.features.ItemStackSrc;
import appeng.core.features.NameResolver; import appeng.core.features.NameResolver;
@@ -58,27 +61,55 @@ import appeng.integration.IntegrationType;
import appeng.items.AEBaseItem; import appeng.items.AEBaseItem;
public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup public final class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
{ {
public static ItemMultiPart instance; public static ItemMultiPart instance;
private final NameResolver nameResolver; private final NameResolver nameResolver;
private final Map<Integer, PartTypeIst> dmgToPart = new HashMap<Integer, PartTypeIst>(); private final Map<Integer, PartTypeWithVariant> registered;
private final Map<Integer, PartTypeWithVariant> unregistered;
public ItemMultiPart( IPartHelper partHelper ) public ItemMultiPart( IPartHelper partHelper )
{ {
Preconditions.checkNotNull( partHelper );
this.registered = new HashMap<Integer, PartTypeWithVariant>();
this.unregistered = new HashMap<Integer, PartTypeWithVariant>();
this.nameResolver = new NameResolver( this.getClass() ); this.nameResolver = new NameResolver( this.getClass() );
this.setFeature( EnumSet.of( AEFeature.Core ) ); this.setFeature( EnumSet.of( AEFeature.Core ) );
partHelper.setItemBusRenderer( this ); partHelper.setItemBusRenderer( this );
this.setHasSubtypes( true ); this.setHasSubtypes( true );
instance = this; instance = this;
} }
@Nonnull
public final ItemStackSrc createPart( PartType mat ) public final ItemStackSrc createPart( PartType mat )
{ {
int varID = 0; Preconditions.checkNotNull( mat );
return this.createPart( mat, 0 );
}
@Nonnull
public ItemStackSrc createPart( PartType mat, AEColor color )
{
Preconditions.checkNotNull( mat );
Preconditions.checkNotNull( color );
final int varID = color.ordinal();
return this.createPart( mat, varID );
}
@Nonnull
private ItemStackSrc createPart( PartType mat, int varID )
{
assert mat != null;
assert varID >= 0;
// verify // verify
for( PartTypeIst p : this.dmgToPart.values() ) for( PartTypeWithVariant p : this.registered.values() )
{ {
if( p.part == mat && p.variant == varID ) if( p.part == mat && p.variant == varID )
throw new IllegalStateException( "Cannot create the same material twice..." ); throw new IllegalStateException( "Cannot create the same material twice..." );
@@ -91,81 +122,34 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
for( IntegrationType integrationType : mat.getIntegrations() ) for( IntegrationType integrationType : mat.getIntegrations() )
enabled &= IntegrationRegistry.INSTANCE.isEnabled( integrationType ); enabled &= IntegrationRegistry.INSTANCE.isEnabled( integrationType );
int newPartNum = mat.baseDamage + varID; final int partDamage = mat.baseDamage + varID;
ItemStackSrc output = new ItemStackSrc( this, newPartNum ); final ItemStackSrc output = new ItemStackSrc( this, partDamage );
if( enabled ) final PartTypeWithVariant pti = new PartTypeWithVariant( mat, varID );
{
PartTypeIst pti = new PartTypeIst();
pti.part = mat;
pti.variant = varID;
if( this.dmgToPart.get( newPartNum ) == null ) this.processMetaOverlap( enabled, partDamage, mat, pti );
{
this.dmgToPart.put( newPartNum, pti );
return output;
}
else
{
throw new IllegalStateException( "Meta Overlap detected." );
}
}
return output; return output;
} }
public ItemStackSrc createPart( PartType mat, Enum variant ) private void processMetaOverlap( boolean enabled, int partDamage, PartType mat, PartTypeWithVariant pti )
{ {
try assert partDamage >= 0;
{ assert mat != null;
// I think this still works? assert pti != null;
ItemStack is = new ItemStack( this );
mat.getPart().getConstructor( ItemStack.class ).newInstance( is );
}
catch( Throwable e )
{
AELog.integration( e );
e.printStackTrace();
return null; // part not supported..
}
int varID = variant == null ? 0 : variant.ordinal(); final Map<Integer, PartTypeWithVariant> reference = ( enabled ) ? this.registered : this.unregistered;
if( reference.containsKey( partDamage ) )
throw new IllegalStateException( "Meta Overlap detected with type " + mat + " and damage " + partDamage + ". Found " + reference.get( partDamage ) + " there already." );
// verify reference.put( partDamage, pti );
for( PartTypeIst p : this.dmgToPart.values() )
{
if( p.part == mat && p.variant == varID )
throw new IllegalStateException( "Cannot create the same material twice..." );
}
boolean enabled = true;
for( AEFeature f : mat.getFeature() )
enabled = enabled && AEConfig.instance.isFeatureEnabled( f );
if( enabled )
{
int newPartNum = mat.baseDamage + varID;
ItemStackSrc output = new ItemStackSrc( this, newPartNum );
PartTypeIst pti = new PartTypeIst();
pti.part = mat;
pti.variant = varID;
if( this.dmgToPart.get( newPartNum ) == null )
{
this.dmgToPart.put( newPartNum, pti );
return output;
}
else
throw new IllegalStateException( "Meta Overlap detected." );
}
return null;
} }
public int getDamageByType( PartType t ) public int getDamageByType( PartType t )
{ {
for( Entry<Integer, PartTypeIst> pt : this.dmgToPart.entrySet() ) Preconditions.checkNotNull( t );
for( Entry<Integer, PartTypeWithVariant> pt : this.registered.entrySet() )
{ {
if( pt.getValue().part == t ) if( pt.getValue().part == t )
return pt.getKey(); return pt.getKey();
@@ -183,7 +167,7 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
@Override @Override
public IIcon getIconFromDamage( int dmg ) public IIcon getIconFromDamage( int dmg )
{ {
return this.dmgToPart.get( dmg ).ico; return this.registered.get( dmg ).ico;
} }
@Override @Override
@@ -198,36 +182,16 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
return "item.appliedenergistics2." + this.getName( is ); return "item.appliedenergistics2." + this.getName( is );
} }
public String getName( ItemStack is )
{
return this.nameResolver.getName( this.getTypeByStack( is ).name() );
}
@Nullable
public PartType getTypeByStack( ItemStack is )
{
if( is == null )
return null;
PartTypeIst pt = this.dmgToPart.get( is.getItemDamage() );
if( pt != null )
return pt.part;
return null;
}
@Override @Override
public String getItemStackDisplayName( ItemStack is ) public String getItemStackDisplayName( ItemStack is )
{ {
PartType pt = this.getTypeByStack( is ); final PartType pt = this.getTypeByStack( is );
if( pt == null )
return "Unnamed";
if( pt.isCable() ) if( pt.isCable() )
{ {
final AEColor[] variants = AEColor.values(); final AEColor[] variants = AEColor.values();
return super.getItemStackDisplayName( is ) + " - " + variants[this.dmgToPart.get( is.getItemDamage() ).variant].toString(); return super.getItemStackDisplayName( is ) + " - " + variants[this.registered.get( is.getItemDamage() ).variant].toString();
} }
if( pt.getExtraName() != null ) if( pt.getExtraName() != null )
@@ -239,60 +203,96 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
@Override @Override
public void getSubItems( Item number, CreativeTabs tab, List cList ) public void getSubItems( Item number, CreativeTabs tab, List cList )
{ {
List<Entry<Integer, PartTypeIst>> types = new ArrayList<Entry<Integer, PartTypeIst>>( this.dmgToPart.entrySet() ); List<Entry<Integer, PartTypeWithVariant>> types = new ArrayList<Entry<Integer, PartTypeWithVariant>>( this.registered.entrySet() );
Collections.sort( types, new Comparator<Entry<Integer, PartTypeIst>>() Collections.sort( types, new Comparator<Entry<Integer, PartTypeWithVariant>>()
{ {
@Override @Override
public int compare( Entry<Integer, PartTypeIst> o1, Entry<Integer, PartTypeIst> o2 ) public int compare( Entry<Integer, PartTypeWithVariant> o1, Entry<Integer, PartTypeWithVariant> o2 )
{ {
return o1.getValue().part.name().compareTo( o2.getValue().part.name() ); return o1.getValue().part.name().compareTo( o2.getValue().part.name() );
} }
} ); } );
for( Entry<Integer, PartTypeIst> part : types ) for( Entry<Integer, PartTypeWithVariant> part : types )
cList.add( new ItemStack( this, 1, part.getKey() ) ); cList.add( new ItemStack( this, 1, part.getKey() ) );
} }
@Override @Override
public void registerIcons( IIconRegister par1IconRegister ) public void registerIcons( IIconRegister par1IconRegister )
{ {
for( Entry<Integer, PartTypeIst> part : this.dmgToPart.entrySet() ) for( Entry<Integer, PartTypeWithVariant> part : this.registered.entrySet() )
{ {
String tex = "appliedenergistics2:" + this.getName( new ItemStack( this, 1, part.getKey() ) ); String tex = "appliedenergistics2:" + this.getName( new ItemStack( this, 1, part.getKey() ) );
part.getValue().ico = par1IconRegister.registerIcon( tex ); part.getValue().ico = par1IconRegister.registerIcon( tex );
} }
} }
public String getName( ItemStack is )
{
Preconditions.checkNotNull( is );
final PartType stackType = this.getTypeByStack( is );
final String typeName = stackType.name();
return this.nameResolver.getName( typeName );
}
@Nonnull
public PartType getTypeByStack( ItemStack is )
{
Preconditions.checkNotNull( is );
final PartTypeWithVariant pt = this.registered.get( is.getItemDamage() );
if( pt != null )
return pt.part;
final PartTypeWithVariant unregisteredPartType = this.unregistered.get( is.getItemDamage() );
if( unregisteredPartType != null )
return unregisteredPartType.part;
throw new IllegalStateException( "ItemStack " + is + " has to be either registered or unregistered, but was not found in either." );
}
@Nonnull
@Override @Override
public IPart createPartFromItemStack( ItemStack is ) public IPart createPartFromItemStack( ItemStack is )
{ {
final PartType type = this.getTypeByStack( is );
final Class<? extends IPart> part = type.getPart();
try try
{ {
PartType t = this.getTypeByStack( is ); if( type.constructor == null )
if( t != null ) type.constructor = part.getConstructor( ItemStack.class );
{
if( t.constructor == null )
t.constructor = t.getPart().getConstructor( ItemStack.class );
return t.constructor.newInstance( is ); return type.constructor.newInstance( is );
}
} }
catch( Throwable e ) catch( InstantiationException e )
{ {
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + this.getTypeByStack( is ).getPart().getName() + " ; Possibly didn't have correct constructor( ItemStack )", e ); throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
}
catch( IllegalAccessException e )
{
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
}
catch( InvocationTargetException e )
{
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
}
catch( NoSuchMethodException e )
{
throw new IllegalStateException( "Unable to construct IBusPart from IBusItem : " + part.getName() + " ; Possibly didn't have correct constructor( ItemStack )", e );
} }
return null;
} }
public int variantOf( int itemDamage ) public int variantOf( int itemDamage )
{ {
if( this.dmgToPart.containsKey( itemDamage ) ) if( this.registered.containsKey( itemDamage ) )
return this.dmgToPart.get( itemDamage ).variant; return this.registered.get( itemDamage ).variant;
return 0; return 0;
} }
@Nullable
@Override @Override
public String getUnlocalizedGroupName( Set<ItemStack> others, ItemStack is ) public String getUnlocalizedGroupName( Set<ItemStack> others, ItemStack is )
{ {
@@ -307,22 +307,19 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
if( stack.getItem() == this ) if( stack.getItem() == this )
{ {
PartType pt = this.getTypeByStack( stack ); PartType pt = this.getTypeByStack( stack );
if ( pt != null ) switch( pt )
{ {
switch( pt ) case ImportBus:
{ importBus = true;
case ImportBus: if( u == pt )
importBus = true; group = true;
if( u == pt ) break;
group = true; case ExportBus:
break; exportBus = true;
case ExportBus: if( u == pt )
exportBus = true; group = true;
if( u == pt ) break;
group = true; default:
break;
default:
}
} }
} }
} }
@@ -333,17 +330,21 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
return null; return null;
} }
public ItemStack getStackFromTypeAndVariant( PartType mt, int variant ) private static final class PartTypeWithVariant
{ {
return new ItemStack( this, 1, mt.baseDamage + variant ); private final PartType part;
} private final int variant;
private static class PartTypeIst
{
private PartType part;
private int variant;
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
private IIcon ico; private IIcon ico;
private PartTypeWithVariant( PartType part, int variant )
{
assert part != null;
assert variant >= 0;
this.part = part;
this.variant = variant;
}
} }
} }