Fixes #1264: Does not crash on missing RF API

This commit is contained in:
thatsIch 2015-04-13 19:28:53 +02:00
parent 817163dbf6
commit 071ae6d680
13 changed files with 120 additions and 100 deletions

View file

@ -49,7 +49,7 @@ import appeng.util.IConfigManagerHost;
import appeng.util.Platform; import appeng.util.Platform;
public class AEConfig extends Configuration implements IConfigurableObject, IConfigManagerHost public final class AEConfig extends Configuration implements IConfigurableObject, IConfigManagerHost
{ {
public static final double TUNNEL_POWER_LOSS = 0.05; public static final double TUNNEL_POWER_LOSS = 0.05;

View file

@ -53,7 +53,7 @@ import appeng.util.Platform;
@Mod( modid = AppEng.MOD_ID, acceptedMinecraftVersions = "[1.7.10]", name = AppEng.MOD_NAME, version = AEConfig.VERSION, dependencies = AppEng.MOD_DEPENDENCIES, guiFactory = "appeng.client.gui.config.AEConfigGuiFactory" ) @Mod( modid = AppEng.MOD_ID, acceptedMinecraftVersions = "[1.7.10]", name = AppEng.MOD_NAME, version = AEConfig.VERSION, dependencies = AppEng.MOD_DEPENDENCIES, guiFactory = "appeng.client.gui.config.AEConfigGuiFactory" )
public class AppEng public final class AppEng
{ {
public static final String MOD_ID = "appliedenergistics2"; public static final String MOD_ID = "appliedenergistics2";
public static final String MOD_NAME = "Applied Energistics 2"; public static final String MOD_NAME = "Applied Energistics 2";

View file

@ -24,7 +24,7 @@ import java.util.Set;
import appeng.core.AEConfig; import appeng.core.AEConfig;
public class FeaturedActiveChecker public final class FeaturedActiveChecker
{ {
private final Set<AEFeature> features; private final Set<AEFeature> features;

View file

@ -11,7 +11,7 @@ import java.lang.annotation.Target;
* Marker interface to help identify invocation of reflection * Marker interface to help identify invocation of reflection
*/ */
@Retention( RetentionPolicy.SOURCE ) @Retention( RetentionPolicy.SOURCE )
@Target( { ElementType.CONSTRUCTOR, ElementType.FIELD } ) @Target( { ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.TYPE } )
public @interface Reflected public @interface Reflected
{ {

View file

@ -22,13 +22,14 @@ package appeng.integration;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModAPIManager;
import appeng.api.exceptions.ModNotInstalled; import appeng.api.exceptions.ModNotInstalled;
import appeng.core.AEConfig; import appeng.core.AEConfig;
import appeng.core.AELog; import appeng.core.AELog;
public class IntegrationNode public final class IntegrationNode
{ {
final String displayName; final String displayName;
@ -59,12 +60,12 @@ public class IntegrationNode
public boolean isActive() public boolean isActive()
{ {
if( this.state == IntegrationStage.PRE_INIT ) if( this.state == IntegrationStage.PRE_INIT )
this.Call( IntegrationStage.PRE_INIT ); this.call( IntegrationStage.PRE_INIT );
return this.state != IntegrationStage.FAILED; return this.state != IntegrationStage.FAILED;
} }
void Call( IntegrationStage stage ) void call( IntegrationStage stage )
{ {
if( this.state != IntegrationStage.FAILED ) if( this.state != IntegrationStage.FAILED )
{ {
@ -76,15 +77,15 @@ public class IntegrationNode
switch( stage ) switch( stage )
{ {
case PRE_INIT: case PRE_INIT:
final ModAPIManager apiManager = ModAPIManager.INSTANCE;
boolean enabled = this.modID == null || Loader.isModLoaded( this.modID ); boolean enabled = this.modID == null || Loader.isModLoaded( this.modID ) || apiManager.hasAPI( this.modID );
AEConfig.instance.addCustomCategoryComment( "ModIntegration", "Valid Values are 'AUTO', 'ON', or 'OFF' - defaults to 'AUTO' ; Suggested that you leave this alone unless your experiencing an issue, or wish to disable the integration for a reason." ); AEConfig.instance.addCustomCategoryComment( "ModIntegration", "Valid Values are 'AUTO', 'ON', or 'OFF' - defaults to 'AUTO' ; Suggested that you leave this alone unless your experiencing an issue, or wish to disable the integration for a reason." );
String Mode = AEConfig.instance.get( "ModIntegration", this.displayName.replace( " ", "" ), "AUTO" ).getString(); String mode = AEConfig.instance.get( "ModIntegration", this.displayName.replace( " ", "" ), "AUTO" ).getString();
if( Mode.toUpperCase().equals( "ON" ) ) if( mode.toUpperCase().equals( "ON" ) )
enabled = true; enabled = true;
if( Mode.toUpperCase().equals( "OFF" ) ) if( mode.toUpperCase().equals( "OFF" ) )
enabled = false; enabled = false;
if( enabled ) if( enabled )

View file

@ -46,16 +46,16 @@ public enum IntegrationRegistry
public void init() public void init()
{ {
for( IntegrationNode node : this.modules ) for( IntegrationNode node : this.modules )
node.Call( IntegrationStage.PRE_INIT ); node.call( IntegrationStage.PRE_INIT );
for( IntegrationNode node : this.modules ) for( IntegrationNode node : this.modules )
node.Call( IntegrationStage.INIT ); node.call( IntegrationStage.INIT );
} }
public void postInit() public void postInit()
{ {
for( IntegrationNode node : this.modules ) for( IntegrationNode node : this.modules )
node.Call( IntegrationStage.POST_INIT ); node.call( IntegrationStage.POST_INIT );
} }
public String getStatus() public String getStatus()

View file

@ -33,9 +33,9 @@ public enum IntegrationType
MJ5( IntegrationSide.BOTH, "BuildCraft5 Power", null ), MJ5( IntegrationSide.BOTH, "BuildCraft5 Power", null ),
RF( IntegrationSide.BOTH, "RedstoneFlux Power - Tiles", null ), RF( IntegrationSide.BOTH, "RedstoneFlux Power - Tiles", "CoFHAPI" ),
RFItem( IntegrationSide.BOTH, "RedstoneFlux Power - Items", null ), RFItem( IntegrationSide.BOTH, "RedstoneFlux Power - Items", "CoFHAPI" ),
MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "MineFactoryReloaded" ), MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "MineFactoryReloaded" ),

View file

@ -53,6 +53,8 @@ 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;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.items.AEBaseItem; import appeng.items.AEBaseItem;
@ -86,6 +88,9 @@ public class ItemMultiPart extends AEBaseItem implements IPartItem, IItemGroup
for( AEFeature f : mat.getFeature() ) for( AEFeature f : mat.getFeature() )
enabled = enabled && AEConfig.instance.isFeatureEnabled( f ); enabled = enabled && AEConfig.instance.isFeatureEnabled( f );
for( IntegrationType integrationType : mat.getIntegrations() )
enabled &= IntegrationRegistry.INSTANCE.isEnabled( integrationType );
int newPartNum = mat.baseDamage + varID; int newPartNum = mat.baseDamage + varID;
ItemStackSrc output = new ItemStackSrc( this, newPartNum ); ItemStackSrc output = new ItemStackSrc( this, newPartNum );

View file

@ -20,11 +20,14 @@ package appeng.items.parts;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Set;
import appeng.api.parts.IPart; import appeng.api.parts.IPart;
import appeng.core.features.AEFeature; import appeng.core.features.AEFeature;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
import appeng.integration.IntegrationType;
import appeng.parts.automation.PartAnnihilationPlane; import appeng.parts.automation.PartAnnihilationPlane;
import appeng.parts.automation.PartExportBus; import appeng.parts.automation.PartExportBus;
import appeng.parts.automation.PartFormationPlane; import appeng.parts.automation.PartFormationPlane;
@ -60,9 +63,9 @@ import appeng.parts.reporting.PartTerminal;
public enum PartType public enum PartType
{ {
InvalidType( -1, EnumSet.of( AEFeature.Core ), null ), InvalidType( -1, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), null ),
CableGlass( 0, EnumSet.of( AEFeature.Core ), PartCableGlass.class ) CableGlass( 0, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartCableGlass.class )
{ {
@Override @Override
public boolean isCable() public boolean isCable()
@ -71,7 +74,7 @@ public enum PartType
} }
}, },
CableCovered( 20, EnumSet.of( AEFeature.Core ), PartCableCovered.class ) CableCovered( 20, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartCableCovered.class )
{ {
@Override @Override
public boolean isCable() public boolean isCable()
@ -80,7 +83,7 @@ public enum PartType
} }
}, },
CableSmart( 40, EnumSet.of( AEFeature.Channels ), PartCableSmart.class ) CableSmart( 40, EnumSet.of( AEFeature.Channels ), EnumSet.noneOf( IntegrationType.class ), PartCableSmart.class )
{ {
@Override @Override
public boolean isCable() public boolean isCable()
@ -89,7 +92,7 @@ public enum PartType
} }
}, },
CableDense( 60, EnumSet.of( AEFeature.Channels ), PartDenseCable.class ) CableDense( 60, EnumSet.of( AEFeature.Channels ), EnumSet.noneOf( IntegrationType.class ), PartDenseCable.class )
{ {
@Override @Override
public boolean isCable() public boolean isCable()
@ -98,74 +101,76 @@ public enum PartType
} }
}, },
ToggleBus( 80, EnumSet.of( AEFeature.Core ), PartToggleBus.class ), ToggleBus( 80, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartToggleBus.class ),
InvertedToggleBus( 100, EnumSet.of( AEFeature.Core ), PartInvertedToggleBus.class ), InvertedToggleBus( 100, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartInvertedToggleBus.class ),
CableAnchor( 120, EnumSet.of( AEFeature.Core ), PartCableAnchor.class ), CableAnchor( 120, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartCableAnchor.class ),
QuartzFiber( 140, EnumSet.of( AEFeature.Core ), PartQuartzFiber.class ), QuartzFiber( 140, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartQuartzFiber.class ),
Monitor( 160, EnumSet.of( AEFeature.Core ), PartMonitor.class ), Monitor( 160, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartMonitor.class ),
SemiDarkMonitor( 180, EnumSet.of( AEFeature.Core ), PartSemiDarkMonitor.class ), SemiDarkMonitor( 180, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartSemiDarkMonitor.class ),
DarkMonitor( 200, EnumSet.of( AEFeature.Core ), PartDarkMonitor.class ), DarkMonitor( 200, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartDarkMonitor.class ),
StorageBus( 220, EnumSet.of( AEFeature.StorageBus ), PartStorageBus.class ), StorageBus( 220, EnumSet.of( AEFeature.StorageBus ), EnumSet.noneOf( IntegrationType.class ), PartStorageBus.class ),
ImportBus( 240, EnumSet.of( AEFeature.ImportBus ), PartImportBus.class ), ImportBus( 240, EnumSet.of( AEFeature.ImportBus ), EnumSet.noneOf( IntegrationType.class ), PartImportBus.class ),
ExportBus( 260, EnumSet.of( AEFeature.ExportBus ), PartExportBus.class ), ExportBus( 260, EnumSet.of( AEFeature.ExportBus ), EnumSet.noneOf( IntegrationType.class ), PartExportBus.class ),
LevelEmitter( 280, EnumSet.of( AEFeature.LevelEmitter ), PartLevelEmitter.class ), LevelEmitter( 280, EnumSet.of( AEFeature.LevelEmitter ), EnumSet.noneOf( IntegrationType.class ), PartLevelEmitter.class ),
AnnihilationPlane( 300, EnumSet.of( AEFeature.AnnihilationPlane ), PartAnnihilationPlane.class ), AnnihilationPlane( 300, EnumSet.of( AEFeature.AnnihilationPlane ), EnumSet.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
FormationPlane( 320, EnumSet.of( AEFeature.FormationPlane ), PartFormationPlane.class ), FormationPlane( 320, EnumSet.of( AEFeature.FormationPlane ), EnumSet.noneOf( IntegrationType.class ), PartFormationPlane.class ),
PatternTerminal( 340, EnumSet.of( AEFeature.Patterns ), PartPatternTerminal.class ), PatternTerminal( 340, EnumSet.of( AEFeature.Patterns ), EnumSet.noneOf( IntegrationType.class ), PartPatternTerminal.class ),
CraftingTerminal( 360, EnumSet.of( AEFeature.CraftingTerminal ), PartCraftingTerminal.class ), CraftingTerminal( 360, EnumSet.of( AEFeature.CraftingTerminal ), EnumSet.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
Terminal( 380, EnumSet.of( AEFeature.Core ), PartTerminal.class ), Terminal( 380, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartTerminal.class ),
StorageMonitor( 400, EnumSet.of( AEFeature.StorageMonitor ), PartStorageMonitor.class ), StorageMonitor( 400, EnumSet.of( AEFeature.StorageMonitor ), EnumSet.noneOf( IntegrationType.class ), PartStorageMonitor.class ),
ConversionMonitor( 420, EnumSet.of( AEFeature.PartConversionMonitor ), PartConversionMonitor.class ), ConversionMonitor( 420, EnumSet.of( AEFeature.PartConversionMonitor ), EnumSet.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
Interface( 440, EnumSet.of( AEFeature.Core ), PartInterface.class ), Interface( 440, EnumSet.of( AEFeature.Core ), EnumSet.noneOf( IntegrationType.class ), PartInterface.class ),
P2PTunnelME( 460, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelME ), PartP2PTunnelME.class, GuiText.METunnel ), P2PTunnelME( 460, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelME ), EnumSet.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel ),
P2PTunnelRedstone( 461, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelRedstone ), PartP2PRedstone.class, GuiText.RedstoneTunnel ), P2PTunnelRedstone( 461, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelRedstone ), EnumSet.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel ),
P2PTunnelItems( 462, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelItems ), PartP2PItems.class, GuiText.ItemTunnel ), P2PTunnelItems( 462, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelItems ), EnumSet.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel ),
P2PTunnelLiquids( 463, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelLiquids ), PartP2PLiquids.class, GuiText.FluidTunnel ), P2PTunnelLiquids( 463, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelLiquids ), EnumSet.noneOf( IntegrationType.class ), PartP2PLiquids.class, GuiText.FluidTunnel ),
P2PTunnelEU( 465, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelEU ), PartP2PIC2Power.class, GuiText.EUTunnel ), P2PTunnelEU( 465, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelEU ), EnumSet.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel ),
P2PTunnelRF( 466, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelRF ), PartP2PRFPower.class, GuiText.RFTunnel ), P2PTunnelRF( 466, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelRF ), EnumSet.of( IntegrationType.RF ), PartP2PRFPower.class, GuiText.RFTunnel ),
P2PTunnelLight( 467, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelLight ), PartP2PLight.class, GuiText.LightTunnel ), P2PTunnelLight( 467, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelLight ), EnumSet.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel ),
InterfaceTerminal( 480, EnumSet.of( AEFeature.InterfaceTerminal ), PartInterfaceTerminal.class ); InterfaceTerminal( 480, EnumSet.of( AEFeature.InterfaceTerminal ), EnumSet.noneOf( IntegrationType.class ), PartInterfaceTerminal.class );
public final int baseDamage; public final int baseDamage;
private final EnumSet<AEFeature> features; private final Set<AEFeature> features;
private final Set<IntegrationType> integrations;
private final Class<? extends IPart> myPart; private final Class<? extends IPart> myPart;
private final GuiText extraName; private final GuiText extraName;
public Constructor<? extends IPart> constructor; public Constructor<? extends IPart> constructor;
PartType( int baseMetaValue, EnumSet<AEFeature> features, Class<? extends IPart> c ) PartType( int baseMetaValue, Set<AEFeature> features, Set<IntegrationType> integrations, Class<? extends IPart> c )
{ {
this( baseMetaValue, features, c, null ); this( baseMetaValue, features, integrations, c, null );
} }
PartType( int baseMetaValue, EnumSet<AEFeature> features, Class<? extends IPart> c, GuiText en ) PartType( int baseMetaValue, Set<AEFeature> features, Set<IntegrationType> integrations, Class<? extends IPart> c, GuiText en )
{ {
this.features = features; this.features = Collections.unmodifiableSet( features ) ;
this.integrations = Collections.unmodifiableSet( integrations );
this.myPart = c; this.myPart = c;
this.extraName = en; this.extraName = en;
this.baseDamage = baseMetaValue; this.baseDamage = baseMetaValue;
@ -176,11 +181,16 @@ public enum PartType
return false; return false;
} }
public EnumSet<AEFeature> getFeature() public Set<AEFeature> getFeature()
{ {
return this.features; return this.features;
} }
public Set<IntegrationType> getIntegrations()
{
return this.integrations;
}
public Class<? extends IPart> getPart() public Class<? extends IPart> getPart()
{ {
return this.myPart; return this.myPart;

View file

@ -41,7 +41,7 @@ import appeng.util.Platform;
@InterfaceList( value = { @Interface( iface = "cofh.api.energy.IEnergyReceiver", iname = "RF" ) } ) @InterfaceList( value = { @Interface( iface = "cofh.api.energy.IEnergyReceiver", iname = "RF" ) } )
public class PartP2PRFPower extends PartP2PTunnel<PartP2PRFPower> implements IEnergyReceiver public final class PartP2PRFPower extends PartP2PTunnel<PartP2PRFPower> implements IEnergyReceiver
{ {
private static final ThreadLocal<Stack<PartP2PRFPower>> THREAD_STACK = new ThreadLocal<Stack<PartP2PRFPower>>(); private static final ThreadLocal<Stack<PartP2PRFPower>> THREAD_STACK = new ThreadLocal<Stack<PartP2PRFPower>>();
/** /**

View file

@ -20,6 +20,7 @@ package appeng.transformer;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable;
import cpw.mods.fml.common.DummyModContainer; import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.LoadController; import cpw.mods.fml.common.LoadController;
@ -36,25 +37,21 @@ import appeng.core.AEConfig;
@MCVersion( "1.7.10" ) @MCVersion( "1.7.10" )
public class AppEngCore extends DummyModContainer implements IFMLLoadingPlugin public final class AppEngCore extends DummyModContainer implements IFMLLoadingPlugin
{ {
private final ModMetadata metadata = new ModMetadata();
public final AppEngCore instance;
protected final ModMetadata md = new ModMetadata();
public AppEngCore() public AppEngCore()
{ {
this.instance = this;
FMLRelaunchLog.info( "[AppEng] Core Init" ); FMLRelaunchLog.info( "[AppEng] Core Init" );
this.md.autogenerated = false; this.metadata.autogenerated = false;
this.md.authorList.add( "AlgorithmX2" ); this.metadata.authorList.add( "AlgorithmX2" );
this.md.credits = "AlgorithmX2"; this.metadata.credits = "AlgorithmX2";
this.md.modId = this.getModId(); this.metadata.modId = this.getModId();
this.md.version = this.getVersion(); this.metadata.version = this.getVersion();
this.md.name = this.getName(); this.metadata.name = this.getName();
this.md.url = "http://ae2.ae-mod.info"; this.metadata.url = "http://ae2.ae-mod.info";
this.md.description = "Embedded Coremod for Applied Energistics 2"; this.metadata.description = "Embedded Coremod for Applied Energistics 2";
} }
@EventHandler @EventHandler
@ -74,6 +71,7 @@ public class AppEngCore extends DummyModContainer implements IFMLLoadingPlugin
return "appeng.transformer.AppEngCore"; return "appeng.transformer.AppEngCore";
} }
@Nullable
@Override @Override
public String getSetupClass() public String getSetupClass()
{ {
@ -95,7 +93,7 @@ public class AppEngCore extends DummyModContainer implements IFMLLoadingPlugin
@Override @Override
public ModMetadata getMetadata() public ModMetadata getMetadata()
{ {
return this.md; return this.metadata;
} }
@Override @Override

View file

@ -20,7 +20,7 @@ package appeng.transformer.asm;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import javax.annotation.Nullable;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
@ -34,13 +34,16 @@ import net.minecraft.launchwrapper.IClassTransformer;
import cpw.mods.fml.relauncher.FMLRelaunchLog; import cpw.mods.fml.relauncher.FMLRelaunchLog;
import appeng.helpers.Reflected;
import appeng.integration.IntegrationRegistry; import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType; import appeng.integration.IntegrationType;
import appeng.transformer.annotations.Integration; import appeng.transformer.annotations.Integration;
public class ASMIntegration implements IClassTransformer @Reflected
public final class ASMIntegration implements IClassTransformer
{ {
@Reflected
public ASMIntegration() public ASMIntegration()
{ {
@ -64,6 +67,7 @@ public class ASMIntegration implements IClassTransformer
} }
@Nullable
@Override @Override
public byte[] transform( String name, String transformedName, byte[] basicClass ) public byte[] transform( String name, String transformedName, byte[] basicClass )
{ {
@ -72,8 +76,6 @@ public class ASMIntegration implements IClassTransformer
if( transformedName.startsWith( "appeng." ) ) if( transformedName.startsWith( "appeng." ) )
{ {
// log( "Found " + transformedName );
ClassNode classNode = new ClassNode(); ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader( basicClass ); ClassReader classReader = new ClassReader( basicClass );
classReader.accept( classNode, 0 ); classReader.accept( classNode, 0 );
@ -112,7 +114,7 @@ public class ASMIntegration implements IClassTransformer
} }
else if( this.hasAnnotation( an, Integration.InterfaceList.class ) ) else if( this.hasAnnotation( an, Integration.InterfaceList.class ) )
{ {
for( Object o : ( (List) an.values.get( 1 ) ) ) for( Object o : ( (Iterable) an.values.get( 1 ) ) )
{ {
if( this.stripInterface( classNode, Integration.InterfaceList.class, (AnnotationNode) o ) ) if( this.stripInterface( classNode, Integration.InterfaceList.class, (AnnotationNode) o ) )
changed = true; changed = true;
@ -145,12 +147,12 @@ public class ASMIntegration implements IClassTransformer
return changed; return changed;
} }
private boolean hasAnnotation( AnnotationNode ann, Class annotation ) private boolean hasAnnotation( AnnotationNode ann, Class<?> annotation )
{ {
return ann.desc.equals( Type.getDescriptor( annotation ) ); return ann.desc.equals( Type.getDescriptor( annotation ) );
} }
private boolean stripInterface( ClassNode classNode, Class class1, AnnotationNode an ) private boolean stripInterface( ClassNode classNode, Class<?> class1, AnnotationNode an )
{ {
if( an.values.size() != 4 ) if( an.values.size() != 4 )
throw new RuntimeException( "Unable to handle Interface annotation on " + classNode.name ); throw new RuntimeException( "Unable to handle Interface annotation on " + classNode.name );
@ -168,10 +170,9 @@ public class ASMIntegration implements IClassTransformer
else if( an.values.get( 2 ).equals( "iname" ) ) else if( an.values.get( 2 ).equals( "iname" ) )
iName = (String) an.values.get( 3 ); iName = (String) an.values.get( 3 );
IntegrationType type = IntegrationType.valueOf( iName );
if( iName != null && iFace != null ) if( iName != null && iFace != null )
{ {
final IntegrationType type = IntegrationType.valueOf( iName );
if( !IntegrationRegistry.INSTANCE.isEnabled( type ) ) if( !IntegrationRegistry.INSTANCE.isEnabled( type ) )
{ {
this.log( "Removing Interface " + iFace + " from " + classNode.name + " because " + iName + " integration is disabled." ); this.log( "Removing Interface " + iFace + " from " + classNode.name + " because " + iName + " integration is disabled." );

View file

@ -20,6 +20,7 @@ package appeng.transformer.asm;
import java.util.Iterator; import java.util.Iterator;
import javax.annotation.Nullable;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
@ -39,26 +40,31 @@ import cpw.mods.fml.relauncher.FMLRelaunchLog;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import appeng.helpers.Reflected;
public class ASMTweaker implements IClassTransformer
@Reflected
public final class ASMTweaker implements IClassTransformer
{ {
private static final String[] EXCEPTIONS = new String[0];
private final Multimap<String, PublicLine> privateToPublicMethods = HashMultimap.create();
final Multimap<String, publicLine> privateToPublicMethods = HashMultimap.create(); @Reflected
public ASMTweaker() public ASMTweaker()
{ {
this.privateToPublicMethods.put( "net.minecraft.client.gui.inventory.GuiContainer", new publicLine( "func_146977_a", "(Lnet/minecraft/inventory/Slot;)V" ) ); this.privateToPublicMethods.put( "net.minecraft.client.gui.inventory.GuiContainer", new PublicLine( "func_146977_a", "(Lnet/minecraft/inventory/Slot;)V" ) );
this.privateToPublicMethods.put( "net.minecraft.client.gui.inventory.GuiContainer", new publicLine( "a", "(Lzk;)V" ) ); this.privateToPublicMethods.put( "net.minecraft.client.gui.inventory.GuiContainer", new PublicLine( "a", "(Lzk;)V" ) );
this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new publicLine( "writeToNBT", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) ); this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new PublicLine( "writeToNBT", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) );
this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new publicLine( "func_145841_b", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) ); this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new PublicLine( "func_145841_b", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) );
this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new publicLine( "b", "(Ldh;)V" ) ); this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new PublicLine( "b", "(Ldh;)V" ) );
this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new publicLine( "readFromNBT", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) ); this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new PublicLine( "readFromNBT", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) );
this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new publicLine( "func_145839_a", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) ); this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new PublicLine( "func_145839_a", "(Lnet/minecraft/nbt/NBTTagCompound;)V" ) );
this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new publicLine( "a", "(Ldh;)V" ) ); this.privateToPublicMethods.put( "appeng.tile.AEBaseTile", new PublicLine( "a", "(Ldh;)V" ) );
} }
@Nullable
@Override @Override
public byte[] transform( String name, String transformedName, byte[] basicClass ) public byte[] transform( String name, String transformedName, byte[] basicClass )
{ {
@ -73,9 +79,9 @@ public class ASMTweaker implements IClassTransformer
ClassReader classReader = new ClassReader( basicClass ); ClassReader classReader = new ClassReader( basicClass );
classReader.accept( classNode, 0 ); classReader.accept( classNode, 0 );
for( publicLine Set : this.privateToPublicMethods.get( transformedName ) ) for( PublicLine set : this.privateToPublicMethods.get( transformedName ) )
{ {
this.makePublic( classNode, Set ); this.makePublic( classNode, set );
} }
// CALL VIRTUAL! // CALL VIRTUAL!
@ -85,7 +91,7 @@ public class ASMTweaker implements IClassTransformer
{ {
if( mn.name.equals( "func_146977_a" ) || ( mn.name.equals( "a" ) && mn.desc.equals( "(Lzk;)V" ) ) ) if( mn.name.equals( "func_146977_a" ) || ( mn.name.equals( "a" ) && mn.desc.equals( "(Lzk;)V" ) ) )
{ {
MethodNode newNode = new MethodNode( Opcodes.ACC_PUBLIC, "func_146977_a_original", mn.desc, mn.signature, new String[0] ); MethodNode newNode = new MethodNode( Opcodes.ACC_PUBLIC, "func_146977_a_original", mn.desc, mn.signature, EXCEPTIONS );
newNode.instructions.add( new VarInsnNode( Opcodes.ALOAD, 0 ) ); newNode.instructions.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
newNode.instructions.add( new VarInsnNode( Opcodes.ALOAD, 1 ) ); newNode.instructions.add( new VarInsnNode( Opcodes.ALOAD, 1 ) );
newNode.instructions.add( new MethodInsnNode( Opcodes.INVOKESPECIAL, classNode.name, mn.name, mn.desc, false ) ); newNode.instructions.add( new MethodInsnNode( Opcodes.INVOKESPECIAL, classNode.name, mn.name, mn.desc, false ) );
@ -132,7 +138,7 @@ public class ASMTweaker implements IClassTransformer
return basicClass; return basicClass;
} }
private void makePublic( ClassNode classNode, publicLine set ) private void makePublic( ClassNode classNode, PublicLine set )
{ {
for( MethodNode mn : classNode.methods ) for( MethodNode mn : classNode.methods )
{ {
@ -149,13 +155,12 @@ public class ASMTweaker implements IClassTransformer
FMLRelaunchLog.log( "AE2-CORE", Level.INFO, string ); FMLRelaunchLog.log( "AE2-CORE", Level.INFO, string );
} }
class publicLine private static final class PublicLine
{ {
private final String name;
private final String desc;
final String name; public PublicLine( String name, String desc )
final String desc;
public publicLine( String name, String desc )
{ {
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;