Java 7 & Null checks

Fixes #268: Getting an item tooltip in the A.C.T. is now a checked
operation.
Fixed potential memory leak on networks with essentia monitor listeners.
Added mod identification to aspects in the Essentia Crafting Terminal.
Fixes #270: Restored Java 7 compatibility.
This commit is contained in:
Chris committed 2016-01-30 08:38:15 -05:00
1 parent a61f2275a3
commit d0ca068773
22 files changed
+320 -129

No files matched your search

+11 -1
View File
@@ -1,4 +1,14 @@
01/24/2016 1.0.0.1 - Beta
01/30/2016 1.0.0.2 - Beta
Fixes #270: Restored Java 7 compatibility.
01/26/2016 1.0.0.2 - Beta
Fixed potential memory leak on networks with essentia monitor listeners.
Added mod identification to aspects in the Essentia Crafting Terminal.
01/25/2016 1.0.0.2 - Beta
Fixes #268: Getting an item tooltip in the A.C.T. is now a checked operation.
01/24/2016 1.0.0.1 - Beta
Fixes #267: Wildcard damage values will no longer cause GUI crashes.
Added Thaumcraft's itemShard to the ore dictionary, allowing autocrafting substitutions where allowed.
+1 -1
View File
@@ -17,7 +17,7 @@ buildscript {
apply plugin: 'forge'
version = "1.0.0.1"
version = "1.0.0.2"
group= "thaumicenergistics" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "thaumicenergistics"
@@ -1,17 +1,20 @@
package thaumicenergistics.client.gui.widget;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.lwjgl.opengl.GL11;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.client.lib.UtilsFX;
import thaumicenergistics.api.gui.IWidgetHost;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.client.gui.ThEGuiHelper;
import thaumicenergistics.common.registries.ThEStrings;
import thaumicenergistics.common.integration.tc.AspectHooks;
import thaumicenergistics.common.storage.AspectStack;
import thaumicenergistics.common.utils.ThEUtils;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -52,8 +55,7 @@ public abstract class AspectWidgetBase
/**
* Cached footnote of the aspect.
* NOTE: One day I hope to put what mod the aspect is from here,
* not just its primallity.
* NOTE: One day I hope to put what mod the aspect is from here, not just its primallity.
*/
protected String aspectFootnote = "";
@@ -159,20 +161,23 @@ public abstract class AspectWidgetBase
// Get the description
this.aspectDescription = this.aspectStack.getAspectDescription();
// Get the mod
ModContainer mod = ThEUtils.getOrDefault( AspectHooks.aspectToMod, this.aspectStack.getAspect(), null );
// Set footnote
if( this.aspectStack.getAspect().isPrimal() )
if( mod != null )
{
this.aspectFootnote = StatCollector.translateToLocal( "tc.aspect.primal" );
this.aspectFootnote = mod.getName();
}
else
{
this.aspectFootnote = ThEStrings.Gui_SelectedAspect.getLocalized();
this.aspectFootnote = "Unknown";
}
}
else
{
this.aspectDescription = this.aspectName;
this.aspectFootnote = this.aspectName;
this.aspectFootnote = "Unknown";
}
// Get the color bytes
@@ -236,6 +241,25 @@ public abstract class AspectWidgetBase
return this.aspectStack;
}
/**
* Draws the aspect name and amount
*/
@Override
public void getTooltip( final List<String> tooltip )
{
if( this.hasAspect() )
{
// Add the name
tooltip.add( this.aspectName );
// Add aspect info
tooltip.add( EnumChatFormatting.GRAY.toString() + this.aspectDescription );
// Add footnote
tooltip.add( EnumChatFormatting.DARK_PURPLE.toString() + EnumChatFormatting.ITALIC.toString() + this.aspectFootnote );
}
}
/**
* Returns true if the widget has an aspect.
*
@@ -108,24 +108,31 @@ public class WidgetAEItem
ItemStack stack = this.aeItemStack.getItemStack();
// Get the tooltip list
List<String> stackTooltip = stack.getTooltip( WidgetAEItem.MC.thePlayer, WidgetAEItem.MC.gameSettings.advancedItemTooltips );
// Set colors and add
for( int index = 0; index < stackTooltip.size(); index++ )
try
{
if( index == 0 )
{
// Item name based on rarity
stackTooltip.set( index, stack.getRarity().rarityColor + stackTooltip.get( index ) );
}
else
{
// The rest grey
stackTooltip.set( index, EnumChatFormatting.GRAY + stackTooltip.get( index ) );
}
List<String> stackTooltip = stack.getTooltip( WidgetAEItem.MC.thePlayer, WidgetAEItem.MC.gameSettings.advancedItemTooltips );
// Add the item tooltip line
tooltip.add( stackTooltip.get( index ) );
// Set colors and add
for( int index = 0; index < stackTooltip.size(); index++ )
{
if( index == 0 )
{
// Item name based on rarity
stackTooltip.set( index, stack.getRarity().rarityColor + stackTooltip.get( index ) );
}
else
{
// The rest grey
stackTooltip.set( index, EnumChatFormatting.GRAY + stackTooltip.get( index ) );
}
// Add the item tooltip line
tooltip.add( stackTooltip.get( index ) );
}
}
catch( Exception e )
{
tooltip.add( EnumChatFormatting.ITALIC + "<Unable to get item tooltip>" );
}
// Get the mod name
@@ -1,10 +1,8 @@
package thaumicenergistics.client.gui.widget;
import java.util.List;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumChatFormatting;
import org.lwjgl.opengl.GL11;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.gui.IAspectSelectorGui;
@@ -266,25 +264,6 @@ public class WidgetAspectSelector
GL11.glDisable( GL11.GL_BLEND );
}
/**
* Draws the aspect name and amount
*/
@Override
public void getTooltip( final List<String> tooltip )
{
if( this.hasAspect() )
{
// Add the name
tooltip.add( this.aspectName );
// Add aspect info
tooltip.add( EnumChatFormatting.GRAY.toString() + this.aspectDescription );
// Add footnote
tooltip.add( EnumChatFormatting.BLUE.toString() + EnumChatFormatting.ITALIC.toString() + this.aspectFootnote );
}
}
/**
* Called when the widget is clicked.
*/
@@ -1,6 +1,5 @@
package thaumicenergistics.client.gui.widget;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import org.lwjgl.opengl.GL11;
@@ -102,15 +101,6 @@ public class WidgetAspectSlot
}
@Override
public void getTooltip( final List<String> tooltip )
{
if( this.canRender() && ( this.getAspect() != null ) )
{
tooltip.add( this.aspectName );
}
}
public void mouseClicked( final Aspect withAspect )
{
this.setAspect( withAspect, 1, false );
@@ -17,6 +17,8 @@ import cpw.mods.fml.relauncher.SideOnly;
/**
* Renders the providers.
*
* TODO: GL Display lists
*
* @author Nividica
*
*/
@@ -47,7 +47,7 @@ public class ThaumicEnergistics
/**
* Current version of the mod.
*/
public static final String VERSION = "1.0.0.1"; // NOTE: don't forget to change the build.gradle file as well
public static final String VERSION = "1.0.0.2"; // NOTE: don't forget to change the build.gradle file as well
/**
* Singleton instance
@@ -8,6 +8,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import thaumicenergistics.common.utils.ThELog;
import thaumicenergistics.common.utils.ThEUtils;
/**
* Base container for all ThE containers.
@@ -88,7 +89,7 @@ public abstract class TheContainerBase
@Nullable
protected Slot getSlotOrNull( final int slotNumber )
{
return this.slotMap.getOrDefault( slotNumber, null );
return ThEUtils.getOrDefault( this.slotMap, slotNumber, null );
}
@Override
@@ -110,7 +110,7 @@ public class GridEssentiaCache
if( !this.isListeningForChanges )
{
// Listen for changes
GridEssentiaCache.this.addListener( this, null );
GridEssentiaCache.this.addListener( this, GridEssentiaCache.this.internalGrid );
this.isListeningForChanges = true;
}
}
@@ -118,7 +118,7 @@ public class GridEssentiaCache
@Override
public boolean isValid( final Object verificationToken )
{
return this.isListeningForChanges;
return this.isListeningForChanges && ( verificationToken == GridEssentiaCache.this.internalGrid );
}
/**
@@ -4,12 +4,15 @@ import java.lang.ref.WeakReference;
import java.util.*;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import org.apache.commons.lang3.StringUtils;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.grid.IEssentiaGrid;
import thaumicenergistics.api.grid.IMEEssentiaMonitor;
import thaumicenergistics.api.grid.IMEEssentiaMonitorReceiver;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.common.tiles.TileEssentiaProvider;
import appeng.api.networking.IGrid;
import appeng.me.GridAccessException;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.ILuaObject;
import dan200.computercraft.api.lua.LuaException;
@@ -132,7 +135,7 @@ public class EssentiaProviderPeripheral
break;
case help:
helpText = "\nDisplays help for the following:\n" + String.join( "()\n", this.getMethodNames() ) + "()\n";
helpText = "\nDisplays help for the following:\n" + StringUtils.join( "()\n", this.getMethodNames() ) + "()\n";
break;
}
}
@@ -320,12 +323,17 @@ public class EssentiaProviderPeripheral
IMEEssentiaMonitor monitor = EssentiaProviderPeripheral.this.getProviderMonitor();
if( monitor != null )
{
// Register
monitor.addListener( this, null );
try
{
monitor.addListener( this, EssentiaProviderPeripheral.this.getProvider().getProxy().getGrid() );
// Mark as receiving
this.isReceving = true;
// Mark as receiving
this.isReceving = true;
}
catch( GridAccessException e )
{
}
}
}
}
@@ -334,11 +342,25 @@ public class EssentiaProviderPeripheral
@Override
public boolean isValid( final Object verificationToken )
{
synchronized( this.threadLock )
// Assume false
this.isReceving = false;
try
{
// Only valid if there are computer watchers
this.isReceving = ( this.computerWatchers.size() > 0 );
IGrid grid = EssentiaProviderPeripheral.this.getProvider().getProxy().getGrid();
if( verificationToken == grid )
{
synchronized( this.threadLock )
{
// Only valid if there are computer watchers
this.isReceving = ( this.computerWatchers.size() > 0 );
}
}
}
catch( GridAccessException e )
{
return false;
}
return this.isReceving;
}
@@ -0,0 +1,36 @@
package thaumicenergistics.common.integration.tc;
import java.util.HashMap;
import thaumcraft.api.aspects.Aspect;
import cpw.mods.fml.common.ModContainer;
/**
* Manages hooks inserted into Thaumcraft's {@code Aspect} class.
*
* @author Nividica
*
*/
public class AspectHooks
{
/**
* TODO: Make private and provide wrapper for name or unknown
* Maps an aspect -> mod.
*/
public static final HashMap<Aspect, ModContainer> aspectToMod = new HashMap<Aspect, ModContainer>();
/**
* Called from the constructor.
*
* @param aspect
*/
public static void hook_AspectInit( final Aspect aspect )
{
// Get the mod
ModContainer mod = cpw.mods.fml.common.Loader.instance().activeModContainer();
// Add to the map
aspectToMod.put( aspect, mod );
}
}
@@ -13,6 +13,7 @@ import thaumicenergistics.api.entities.IGolemHookHandler.InteractionLevel;
import thaumicenergistics.api.entities.IGolemHookSyncRegistry;
import thaumicenergistics.common.utils.EffectiveSide;
import thaumicenergistics.common.utils.ThELog;
import thaumicenergistics.common.utils.ThEUtils;
import thaumicenergistics.fml.ThECore;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -201,7 +202,7 @@ public class GolemHooks
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
Object handlerData = ThEUtils.getOrDefault( golemHandlerData, handler, null );
// Call handler
@@ -239,7 +240,7 @@ public class GolemHooks
for( IGolemHookHandler handler : registeredHandlers )
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
Object handlerData = ThEUtils.getOrDefault( golemHandlerData, handler, null );
// Call handler
try
@@ -466,7 +467,7 @@ public class GolemHooks
for( IGolemHookHandler handler : handlersToUpdate )
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
Object handlerData = ThEUtils.getOrDefault( golemHandlerData, handler, null );
boolean hadData = ( handlerData != null );
try
{
@@ -550,7 +551,7 @@ public class GolemHooks
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
Object handlerData = ThEUtils.getOrDefault( golemHandlerData, handler, null );
// Call handler
handlerData = handler.readEntityFromNBT( golem, nbt );
@@ -619,7 +620,7 @@ public class GolemHooks
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
Object handlerData = ThEUtils.getOrDefault( golemHandlerData, handler, null );
boolean hadData = ( handlerData != null );
// Call handler
@@ -674,7 +675,7 @@ public class GolemHooks
try
{
// Get the current handler data
Object handlerData = golemHandlerData.getOrDefault( handler, null );
Object handlerData = ThEUtils.getOrDefault( golemHandlerData, handler, null );
// Call handler
handler.writeEntityNBT( golem, handlerData, nbt );
@@ -7,6 +7,7 @@ import java.util.Map.Entry;
import thaumicenergistics.api.entities.IGolemHookHandler;
import thaumicenergistics.api.entities.IGolemHookSyncRegistry;
import thaumicenergistics.common.utils.ThELog;
import thaumicenergistics.common.utils.ThEUtils;
import com.google.common.base.Charsets;
class GolemSyncRegistry
@@ -60,7 +61,7 @@ class GolemSyncRegistry
@Override
public char getSyncCharOrDefault( final int id, final char defaultChar )
{
return this.dataMappings.getOrDefault( Integer.valueOf( id ), defaultChar );
return ThEUtils.getOrDefault( this.dataMappings, Integer.valueOf( id ), defaultChar );
}
/**
@@ -9,10 +9,14 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.StatCollector;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.common.Thaumcraft;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.integration.tc.AspectHooks;
import thaumicenergistics.common.utils.ThEUtils;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -148,6 +152,12 @@ public class ItemCraftingAspect
{
// Add the aspect info
list.add( aspect.getLocalizedDescription() );
ModContainer mod = ThEUtils.getOrDefault( AspectHooks.aspectToMod, aspect, null );
if( mod != null )
{
list.add( EnumChatFormatting.DARK_PURPLE.toString() + EnumChatFormatting.ITALIC.toString() + mod.getName() );
}
}
else
{
@@ -5,6 +5,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
import thaumicenergistics.common.ThaumicEnergistics;
import thaumicenergistics.common.network.packet.client.*;
import thaumicenergistics.common.network.packet.server.*;
import thaumicenergistics.common.utils.ThEUtils;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
@@ -58,7 +59,7 @@ public class NetworkHandler
*/
public static Class getPacketClassFromID( final Short id )
{
return NetworkHandler.IDToClass.getOrDefault( id, null );
return ThEUtils.getOrDefault( NetworkHandler.IDToClass, id, null );
}
/**
@@ -69,7 +70,7 @@ public class NetworkHandler
*/
public static short getPacketID( final ThEBasePacket packet )
{
return NetworkHandler.ClassToID.getOrDefault( packet.getClass(), (short) -1 );
return ThEUtils.getOrDefault( NetworkHandler.ClassToID, packet.getClass(), (short) -1 );
}
/**
@@ -375,9 +375,6 @@ public class PartEssentiaStorageBus
@Override
public void onNeighborChanged()
{
// Call super
super.onNeighborChanged();
// Send grid update event on server side
if( EffectiveSide.isServerSide() && this.isActive() )
{
@@ -37,7 +37,6 @@ import appeng.api.parts.*;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -102,18 +101,13 @@ public abstract class ThEPartBase
/**
* The IGridBlock for this part.
*/
private AEPartGridBlock gridBlock;
private final AEPartGridBlock gridBlock;
/**
* AE2 player ID for the owner of this part.
*/
private int ownerID = -1;
/**
* Is the part receiving a redstone signal.
*/
private boolean recevingRedstonePower;
/**
* The item that represents this part.
*/
@@ -140,6 +134,16 @@ public abstract class ThEPartBase
{
this.interactionPermissions = null;
}
if( EffectiveSide.isServerSide() )
{
// Create the grid block
this.gridBlock = new AEPartGridBlock( this );
}
else
{
this.gridBlock = null;
}
}
private void updateStatus()
@@ -181,6 +185,11 @@ public abstract class ThEPartBase
*/
protected boolean doesPlayerHavePermission( final EntityPlayer player, final SecurityPermissions permission )
{
if( EffectiveSide.isClientSide() )
{
return false;
}
// Get the security grid
ISecurityGrid sGrid = this.gridBlock.getSecurityGrid();
@@ -205,6 +214,11 @@ public abstract class ThEPartBase
*/
protected boolean doesPlayerHavePermission( final int playerID, final SecurityPermissions permission )
{
if( EffectiveSide.isClientSide() )
{
return false;
}
// Get the security grid
ISecurityGrid sGrid = this.gridBlock.getSecurityGrid();
@@ -226,6 +240,11 @@ public abstract class ThEPartBase
*/
protected TileEntity getFacingTile()
{
if( this.hostTile == null )
{
return null;
}
// Get the world
World world = this.hostTile.getWorldObj();
@@ -245,22 +264,20 @@ public abstract class ThEPartBase
public void addToWorld()
{
// Ignored on client side
if( FMLCommonHandler.instance().getEffectiveSide().isServer() )
if( EffectiveSide.isClientSide() )
{
// Create the grid block
this.gridBlock = new AEPartGridBlock( this );
// Create the node
this.node = AEApi.instance().createGridNode( this.gridBlock );
// Update state
this.node.updateState();
// Set the player id
this.node.setPlayerID( this.ownerID );
this.setPower( null );
return;
}
// Create the node
this.node = AEApi.instance().createGridNode( this.gridBlock );
// Update state
this.node.updateState();
// Set the player id
this.node.setPlayerID( this.ownerID );
this.setPower( null );
}
@Override
@@ -269,8 +286,8 @@ public abstract class ThEPartBase
@Override
public boolean canBePlacedOn( final BusSupport type )
{
// Can not be placed on dense cable
return type != BusSupport.DENSE_CABLE;
// Can only be placed on normal cable
return type == BusSupport.CABLE;
}
@Override
@@ -288,6 +305,7 @@ public abstract class ThEPartBase
@Override
public abstract void getBoxes( IPartCollisionHelper helper );
@SideOnly(Side.CLIENT)
@Override
public abstract IIcon getBreakingTexture();
@@ -461,6 +479,11 @@ public abstract class ThEPartBase
*/
public final boolean isPartUseableByPlayer( final EntityPlayer player )
{
if( EffectiveSide.isClientSide() )
{
return false;
}
// Null check host
if( ( this.hostTile == null ) || ( this.host == null ) )
{
@@ -543,7 +566,12 @@ public abstract class ThEPartBase
*/
public boolean isReceivingRedstonePower()
{
return this.recevingRedstonePower;
if( this.host != null )
{
// Get redstone state
return this.host.hasRedstone( this.cableSide );
}
return false;
}
@Override
@@ -603,20 +631,6 @@ public abstract class ThEPartBase
@Override
public void onNeighborChanged()
{
if( this.hostTile != null )
{
// Get the world
World world = this.hostTile.getWorldObj();
// Get our location
int x = this.hostTile.xCoord;
int y = this.hostTile.yCoord;
int z = this.hostTile.zCoord;
// Check redstone state
this.recevingRedstonePower = world.isBlockIndirectlyGettingPowered( x, y, z );
}
}
@Override
@@ -768,7 +782,7 @@ public abstract class ThEPartBase
List<ItemStack> drops = new ArrayList<ItemStack>();
// Get this item
drops.add( this.getItemStack( null ) );
drops.add( this.getItemStack( PartItemStack.Break ) );
// Get the drops for this part
this.getDrops( drops, false );
@@ -785,9 +799,7 @@ public abstract class ThEPartBase
public final void setPartHostInfo( final ForgeDirection side, final IPartHost host, final TileEntity tile )
{
this.cableSide = side;
this.host = host;
this.hostTile = tile;
}
@@ -796,8 +808,6 @@ public abstract class ThEPartBase
public final void setPower( final MENetworkPowerStatusChange event )
{
this.updateStatus();
this.host.markForUpdate();
}
/**
@@ -472,9 +472,6 @@ public abstract class ThEPartEssentiaIOBus_Base
@Override
public void onNeighborChanged()
{
// Call super
super.onNeighborChanged();
// Ignored client side
if( EffectiveSide.isClientSide() )
{
@@ -7,6 +7,7 @@ import java.util.concurrent.ConcurrentHashMap;
import thaumcraft.api.aspects.Aspect;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.api.storage.IEssentiaRepo;
import thaumicenergistics.common.utils.ThEUtils;
/**
* Manages a repository of essentia.
@@ -71,7 +72,7 @@ public class EssentiaRepo
@Override
public IAspectStack get( final Aspect aspect )
{
return this.cache.getOrDefault( aspect, null );
return ThEUtils.getOrDefault( this.cache, aspect, null );
}
@Override
@@ -83,7 +84,7 @@ public class EssentiaRepo
@Override
public IAspectStack getOrDefault( final Aspect aspect, final IAspectStack defaultValue )
{
return this.cache.getOrDefault( aspect, defaultValue );
return ThEUtils.getOrDefault( this.cache, aspect, defaultValue );
}
@Override
@@ -1,5 +1,6 @@
package thaumicenergistics.common.utils;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;
@@ -51,6 +52,27 @@ public final class ThEUtils
}
/**
* Returns the value to which the specified key is mapped, or defaultValue if the map contains no mapping for the key.
* <hr>
* NOTE: This is included for java 7 compatibility.
* <hr>
*
* @param map
* @param key
* @param defaultValue
* @return
*/
public static final <K, V> V getOrDefault( final Map<K, V> map, final K key, final V defaultValue )
{
if( map.containsKey( key ) )
{
return map.get( key );
}
return defaultValue;
}
/**
* Returns true if the item stack is a wand, scepter, or staff if they are
* allowed.
@@ -35,6 +35,11 @@ import cpw.mods.fml.relauncher.FMLRelaunchLog;
* <li>Adds hook to method <em>render</em></li>
* </ul>
*
* Thaumcraft class <em>Aspect</em>
* <ul>
* <li>Adds hook to <em>constructor</em></li>
* </ul>
*
* @author Nividica
*
*/
@@ -42,7 +47,9 @@ public class ASMTransformer
implements IClassTransformer
{
private static final String CLASS_EntityGolemBase = "thaumcraft/common/entities/golems/EntityGolemBase";
private static final String CLASS_Aspect = "thaumcraft/api/aspects/Aspect";
private static final String CLASS_GolemHooks = "thaumicenergistics/common/integration/tc/GolemHooks";
private static final String CLASS_AspectHooks = "thaumicenergistics/common/integration/tc/AspectHooks";
private static final String INTERFACE_IGolemHookHandler = "thaumicenergistics/api/entities/IGolemHookHandler";
private static final String FIELD_EntityGolemBase_hookHandlers = "hookHandlers";
@@ -218,6 +225,34 @@ public class ASMTransformer
FMLRelaunchLog.log( "ThE-Core", Level.INFO, text );
}
private byte[] transformClass_Aspect( final byte[] classBytes )
{
// Create the class node and read in the class
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader( classBytes );
classReader.accept( classNode, 0 );
// Transform methods
for( MethodNode method : classNode.methods )
{
// Constructor
if( method.name.equals( "<init>" ) )
{
if( this.transformMethod_Aspect_init( method ) )
{
break; // Stop searching.
}
}
}
// Create the writer
ClassWriter writer = new ClassWriter( ClassWriter.COMPUTE_MAXS );
classNode.accept( writer );
// Return the modified class
return writer.toByteArray();
}
private byte[] transformClass_GolemBase( final byte[] classBytes )
{
@@ -360,6 +395,37 @@ public class ASMTransformer
return writer.toByteArray();
}
private boolean transformMethod_Aspect_init( final MethodNode method )
{
// Is this the full constructor?
// Check description
if( !"(Ljava/lang/String;I[Lthaumcraft/api/aspects/Aspect;Lnet/minecraft/util/ResourceLocation;I)V".equals( method.desc ) )
{
return false;
}
int opSequence[] = new int[] { Opcodes.GETSTATIC, Opcodes.ALOAD, Opcodes.ALOAD, Opcodes.INVOKEVIRTUAL, Opcodes.POP };
AbstractInsnNode insertionPoint = this.findSequence( method.instructions, opSequence, false );
// Insert the hook
// AspectHooks.hook_AspectInit( this )
InsnList instructionList = new InsnList();
// this
instructionList.add( new VarInsnNode( Opcodes.ALOAD, 0 ) );
// AspectHooks.hook_AspectInit( Aspect )
instructionList.add( new MethodInsnNode( Opcodes.INVOKESTATIC,
CLASS_AspectHooks, "hook_AspectInit",
"(L" + CLASS_Aspect + ";)V", false ) );
// Insert the static call
method.instructions.insert( insertionPoint, instructionList );
return true;
}
private void transformMethod_GolemBase_CustomInteraction( final MethodNode method )
{
int opSequence[] = new int[] { Opcodes.ALOAD, Opcodes.INVOKEVIRTUAL, Opcodes.ICONST_M1 };
@@ -689,6 +755,20 @@ public class ASMTransformer
}
}
else if( transformedName.equals( "thaumcraft.api.aspects.Aspect" ) )
{
try
{
this.log( "Transforming Class (thaumcraft.api.aspects.Aspect)" );
return this.transformClass_Aspect( basicClass );
}
catch( Exception e )
{
this.log( "Unable to transform (thaumcraft.api.aspects.Aspect)" );
}
}
}
return basicClass;