Removed AT and replaced with efficient reflection.

Will make mod easier to build in future.
This commit is contained in:
Alkalus committed 2021-08-24 18:22:20 +01:00
1 parent b796fa42c4
commit a1ecb41350
14 files changed
+208 -59

No files matched your search

+1 -1
View File
@@ -72,7 +72,7 @@ jar {
archiveName = modid+" MC-"+project.minecraft.version+" v"+modver+".jar"
manifest {
attributes 'FMLAT': 'hee_at.cfg'
//attributes 'FMLAT': 'hee_at.cfg'
}
}
tasks.build.dependsOn createResourcePack
@@ -6,6 +6,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants.NBT;
import chylex.hee.api.message.element.base.Precondition;
import chylex.hee.system.util.ReflectionUtils;
public class ListValue<T> extends Precondition<List<T>>{
public static final ListValue<String> strings(Precondition<String> condition){
@@ -31,17 +32,26 @@ public class ListValue<T> extends Precondition<List<T>>{
@Override
public boolean checkValue(NBTBase tag){
for(NBTBase element:(List<NBTBase>)((NBTTagList)tag).tagList){
if (!condition.checkType(element) || !condition.checkValue(element))return false;
}
List tagList = ReflectionUtils.getFieldValue((List<NBTBase>)((NBTTagList)tag), "tagList");
for(Object element : tagList){
if (element instanceof NBTBase) {
if (!condition.checkType((NBTBase) element) || !condition.checkValue((NBTBase) element)) {
return false;
}
}
}
return true;
}
@Override
public List<T> getValue(NBTBase tag){
List<T> elements = new ArrayList<>();
for(NBTBase element:(List<NBTBase>)((NBTTagList)tag).tagList)elements.add(condition.getValue(element));
List tagList = ReflectionUtils.getFieldValue((List<NBTBase>)((NBTTagList)tag), "tagList");
for (Object element : tagList) {
if (element instanceof NBTBase) {
elements.add(condition.getValue((NBTBase) element));
}
}
return elements;
}
}
@@ -1,12 +1,16 @@
package chylex.hee.block;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.ObjectIntIdentityMap;
import chylex.hee.system.logging.Log;
import chylex.hee.system.logging.Stopwatch;
import chylex.hee.system.util.ReflectionUtils;
import chylex.hee.system.util.Unfinalizer;
import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry;
import cpw.mods.fml.common.registry.GameData;
@@ -27,13 +31,18 @@ public class BlockReplaceHelper{
String registryName = Block.blockRegistry.getNameForObject(block);
int id = Block.getIdFromBlock(block);
Log.debug("Replacing block - $0/$1",id,registryName);
Log.debug("Replacing block - $0/$1",id,registryName);
((ItemBlock)Item.getItemFromBlock(block)).field_150939_a = replacement;
ReflectionUtils.setFieldValue(((ItemBlock)Item.getItemFromBlock(block)), "field_150939_a", replacement);
FMLControlledNamespacedRegistry<Block> registryBlocks = GameData.getBlockRegistry();
registryBlocks.registryObjects.put(registryName,replacement);
registryBlocks.underlyingIntegerMap.func_148746_a(replacement,id); // OBFUSCATED put object
Map registryObjects = ReflectionUtils.getFieldValue(registryBlocks, "registryObjects");
ObjectIntIdentityMap underlyingIntegerMap = ReflectionUtils.getFieldValue(registryBlocks, "underlyingIntegerMap");
registryObjects.put(registryName,replacement);
underlyingIntegerMap.func_148746_a(replacement,id); // OBFUSCATED put object
ReflectionUtils.setFieldValue(registryBlocks, "registryObjects", registryObjects);
ReflectionUtils.setFieldValue(registryBlocks, "underlyingIntegerMap", underlyingIntegerMap);
blockField.setAccessible(true);
Unfinalizer.unfinalizeField(blockField);
@@ -23,6 +23,7 @@ import chylex.hee.mechanics.enhancements.EnhancementHandler;
import chylex.hee.mechanics.enhancements.types.EnderPearlEnhancements;
import chylex.hee.packets.PacketPipeline;
import chylex.hee.packets.client.C20Effect;
import chylex.hee.system.util.ReflectionUtils;
import cpw.mods.fml.client.FMLClientHandler;
public class EntityProjectileEnhancedEnderPearl extends EntityEnderPearl{
@@ -105,10 +106,11 @@ public class EntityProjectileEnhancedEnderPearl extends EntityEnderPearl{
ride.lastTickPosY = ride.prevPosY = ride.posY = posY+ride.height+yOffset;
ride.lastTickPosZ = ride.prevPosZ = ride.posZ = posZ;
NetHandlerPlayServer serverHandler = ((EntityPlayerMP)ride).playerNetServerHandler;
serverHandler.floatingTickCount = 0;
serverHandler.lastPosX = ride.posX;
serverHandler.lastPosY = ride.posY;
serverHandler.lastPosZ = ride.posZ;
ReflectionUtils.setFieldValue(serverHandler, "floatingTickCount", 0);
ReflectionUtils.setFieldValue(serverHandler, "lastPosX", ride.posX);
ReflectionUtils.setFieldValue(serverHandler, "lastPosY", ride.posY);
ReflectionUtils.setFieldValue(serverHandler, "lastPosZ", ride.posZ);
}
@Override
@@ -12,6 +12,7 @@ import chylex.hee.HardcoreEnderExpansion;
import chylex.hee.proxy.ModCommonProxy;
import chylex.hee.system.util.BlockPosM;
import chylex.hee.system.util.DragonUtil;
import chylex.hee.system.util.ReflectionUtils;
public class EntityProjectileFlamingBall extends EntityFireball{
public EntityProjectileFlamingBall(World world){
@@ -52,8 +53,12 @@ public class EntityProjectileFlamingBall extends EntityFireball{
}
mop.entityHit.attackEntityFrom(DamageSource.onFire,3F);
if (isLiving)mop.entityHit.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity),ModCommonProxy.opMobs ? 8F : 5F);
mop.entityHit.fire += 3+EnchantmentProtection.getFireTimeForEntity(mop.entityHit,25);
if (isLiving) {
mop.entityHit.attackEntityFrom(DamageSource.causeMobDamage(shootingEntity),ModCommonProxy.opMobs ? 8F : 5F);
}
int fire = ReflectionUtils.getFieldValue(mop.entityHit, "fire");
fire += 3+EnchantmentProtection.getFireTimeForEntity(mop.entityHit,25);
ReflectionUtils.setFieldValue(mop.entityHit, "fire", fire);
}
else if (rand.nextInt(3) == 0){
switch(mop.sideHit){
@@ -45,6 +45,7 @@ import chylex.hee.system.util.BlockPosM;
import chylex.hee.system.util.CollectionUtil;
import chylex.hee.system.util.DragonUtil;
import chylex.hee.system.util.MathUtil;
import chylex.hee.system.util.ReflectionUtils;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
@@ -389,7 +390,7 @@ public final class CharmEvents{
if (impactRad.length > 0){
float[] impactAmt = getProp(sourcePlayer,"impactamt");
float lastDamage = e.entityLiving.lastDamage;
float lastDamage = ReflectionUtils.getFieldValue(e.entityLiving, "lastDamage");
for(int a = 0; a < impactRad.length; a++){
List<EntityLivingBase> entities = e.entity.worldObj.getEntitiesWithinAABB(EntityLivingBase.class,e.entity.boundingBox.expand(impactRad[a],impactRad[a],impactRad[a]));
@@ -26,6 +26,7 @@ import chylex.hee.proxy.ModClientProxy;
import chylex.hee.proxy.ModCommonProxy;
import chylex.hee.system.achievements.AchievementManager;
import chylex.hee.system.logging.Stopwatch;
import chylex.hee.system.util.ReflectionUtils;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
@@ -155,9 +156,12 @@ public final class CompendiumEventsClient{
int mouseX = Mouse.getX()*res.getScaledWidth()/mc.displayWidth,
mouseY = res.getScaledHeight()-Mouse.getY()*res.getScaledHeight()/mc.displayHeight-1;
int xSize = ReflectionUtils.getFieldValue(container, "xSize");
int ySize = ReflectionUtils.getFieldValue(container, "ySize");
mouseX -= (container.width-container.xSize)/2;
mouseY -= (container.height-container.ySize)/2;
mouseX -= (container.width-xSize)/2;
mouseY -= (container.height-ySize)/2;
for(Slot slot:slots){
if (slot.getHasStack() && slot.func_111238_b() &&
@@ -27,6 +27,7 @@ import chylex.hee.packets.client.C22EffectLine;
import chylex.hee.system.util.BlockPosM;
import chylex.hee.system.util.ColorUtil;
import chylex.hee.system.util.MathUtil;
import chylex.hee.system.util.ReflectionUtils;
public enum CurseType{
TELEPORTATION(0, new ICurseHandler(){
@@ -118,13 +119,13 @@ public enum CurseType{
}
else if (entity instanceof EntityGhast){
EntityGhast ghast = (EntityGhast)entity;
if (ghast.targetedEntity == null || ghast.targetedEntity instanceof EntityPlayer){
Entity target = ReflectionUtils.getFieldValue(ghast, "targetedEntity");
if (target == null || target instanceof EntityPlayer){
EntityLiving newTarget = getMob(ghast,64D);
if (newTarget != null){
cooldown = 60;
ghast.targetedEntity = newTarget;
ReflectionUtils.setFieldValue(ghast, "targetedEntity", newTarget);
}
}
}
@@ -165,7 +166,9 @@ public enum CurseType{
if (creature.getEntityToAttack() != null)creature.setTarget(null);
if (creature.getAttackTarget() != null)creature.setAttackTarget(null);
}
else if (entity instanceof EntityGhast)((EntityGhast)entity).targetedEntity = null;
else if (entity instanceof EntityGhast) {
ReflectionUtils.setFieldValue(entity, "targetedEntity", null);
}
return entity.ticksExisted%20 == 0;
}
@@ -379,12 +382,13 @@ public enum CurseType{
while(!indexes.isEmpty()){
int index = indexes.get(rand.nextInt(indexes.size()));
indexes.remove(index);
if (equipment[index] == null || MathUtil.floatEquals(living.equipmentDropChances[index],0F))continue;
ItemStack is = equipment[index];
if (living.equipmentDropChances[index] <= 1F && is.isItemStackDamageable()){
indexes.remove(index);
float[] equipmentDropChances = ReflectionUtils.getFieldValue(living, "equipmentDropChances");
if (equipment[index] == null || MathUtil.floatEquals(equipmentDropChances[index],0F)) {
continue;
}
ItemStack is = equipment[index];
if (equipmentDropChances[index] <= 1F && is.isItemStackDamageable()){
int maxDmg = Math.max(is.getMaxDamage()-25,1), dmg = is.getMaxDamage()-rand.nextInt(rand.nextInt(maxDmg)+1);
if (dmg > maxDmg)dmg = maxDmg;
is.setItemDamage(Math.max(dmg,1));
@@ -13,6 +13,7 @@ import chylex.hee.item.ItemMusicDisk;
import chylex.hee.packets.AbstractClientPacket;
import chylex.hee.sound.CustomMusicTicker;
import chylex.hee.system.util.BlockPosM;
import chylex.hee.system.util.ReflectionUtils;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -51,7 +52,7 @@ public class C02PlayRecord extends AbstractClientPacket{
SoundHandler soundHandler = mc.getSoundHandler();
ChunkCoordinates coords = new ChunkCoordinates(pos.x,pos.y,pos.z);
Map mapSoundPositions = mc.renderGlobal.mapSoundPositions;
Map mapSoundPositions = ReflectionUtils.getFieldValue(mc.renderGlobal, "mapSoundPositions");
ISound currentSound = (ISound)mapSoundPositions.get(coords);
if (currentSound != null){
@@ -4,6 +4,7 @@ import net.minecraft.client.audio.MusicTicker;
import net.minecraftforge.client.event.sound.SoundLoadEvent;
import net.minecraftforge.common.MinecraftForge;
import chylex.hee.system.logging.Log;
import chylex.hee.system.util.ReflectionUtils;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
@@ -27,16 +28,18 @@ public final class MusicManager{
if (hasLoaded || (!enableCustomMusic && !removeVanillaDelay))return;
Minecraft mc = Minecraft.getMinecraft();
MusicTicker mcMusicTicker = ReflectionUtils.getFieldValue(mc, "mcMusicTicker");
if (mc.mcMusicTicker != null){
Class<? extends MusicTicker> tickerClass = mc.mcMusicTicker.getClass();
if (mcMusicTicker != null){
Class<? extends MusicTicker> tickerClass = mcMusicTicker.getClass();
if (tickerClass == MusicTicker.class){
mc.mcMusicTicker = new CustomMusicTicker(mc,null);
ReflectionUtils.setFieldValue(mc, "mcMusicTicker", new CustomMusicTicker(mc,null));
Log.info("Successfully replaced music system.");
}
else{
mc.mcMusicTicker = new CustomMusicTicker(mc,mc.mcMusicTicker);
ReflectionUtils.setFieldValue(mc, "mcMusicTicker", new CustomMusicTicker(mc,mcMusicTicker));
Log.info("Successfully wrapped a music system replaced by another mod: $0",tickerClass.getName());
}
@@ -0,0 +1,130 @@
package chylex.hee.system.util;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.Map;
public class ReflectionUtils {
public static Map<String, CachedField> mCachedFields = new LinkedHashMap<String, CachedField>();
private static class CachedField {
private final Field FIELD;
public CachedField(Field aField) {
FIELD = aField;
}
public Field get() {
return FIELD;
}
}
private static boolean cacheField(Class<?> aClass, Field aField) {
if (aField == null) {
return false;
}
CachedField y = mCachedFields.get(aClass.getName()+"."+aField.getName());
if (y == null) {
mCachedFields.put(aClass.getName()+"."+aField.getName(), new CachedField(aField));
return true;
}
return false;
}
/**
* Returns a cached {@link Field} object.
* @param aClass - Class containing the Method.
* @param aFieldName - Field name in {@link String} form.
* @return - Valid, non-final, {@link Field} object, or {@link null}.
*/
public static Field getField(final Class<?> aClass, final String aFieldName) {
if (aClass == null || aFieldName == null || aFieldName.length() <= 0) {
return null;
}
CachedField y = mCachedFields.get(aClass.getName()+"."+aFieldName);
if (y == null) {
Field u;
try {
u = getField_Internal(aClass, aFieldName);
if (u != null) {
cacheField(aClass, u);
return u;
}
} catch (NoSuchFieldException e) {
}
return null;
} else {
return y.get();
}
}
/**
* Returns a cached {@link Field} object.
* @param aInstance - {@link Object} to get the field instance from.
* @param aFieldName - Field name in {@link String} form.
* @return - Valid, non-final, {@link Field} object, or {@link null}.
*/
public static Field getField(final Object aInstance, final String aFieldName) {
return getField(aInstance.getClass(), aFieldName);
}
@SuppressWarnings("unchecked")
public static <T> T getFieldValue(final Object aInstance, final String aFieldName) {
try {
return (T) getField(aInstance, aFieldName).get(aInstance);
} catch (IllegalArgumentException | IllegalAccessException e) {
return null;
}
}
public static void setFieldValue(final Object aInstance, final String aFieldName, Object aNewValue) {
setFieldValue(aInstance, aFieldName, aInstance instanceof Class ? true : false, aNewValue);
}
public static void setFieldValue(final Object aInstance, final String aFieldName, boolean aStatic, Object aNewValue) {
Field f;
try {
if (aInstance instanceof Class && aStatic) {
f = getField((Class) aInstance, aFieldName);
f.set(null, aNewValue);
}
else {
f = getField(aInstance, aFieldName);
f.set(aInstance, aNewValue);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
private static Field getField_Internal(final Class<?> clazz, final String fieldName) throws NoSuchFieldException {
try {
Field k = clazz.getDeclaredField(fieldName);
makeFieldAccessible(k);
return k;
} catch (final NoSuchFieldException e) {
final Class<?> superClass = clazz.getSuperclass();
if (superClass == null) {
throw e;
}
return getField_Internal(superClass, fieldName);
}
}
public static void makeFieldAccessible(final Field field) {
if (!Modifier.isPublic(field.getModifiers()) ||
!Modifier.isPublic(field.getDeclaringClass().getModifiers()))
{
field.setAccessible(true);
}
}
}
@@ -13,6 +13,7 @@ import net.minecraft.world.gen.structure.MapGenScatteredFeature;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.terraingen.ChunkProviderEvent;
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
import chylex.hee.system.util.ReflectionUtils;
import chylex.hee.world.biome.BiomeGenHardcoreEnd;
import chylex.hee.world.structure.island.MapGenIsland;
import chylex.hee.world.structure.tower.MapGenTower;
@@ -26,7 +27,7 @@ public class ChunkProviderHardcoreEnd extends ChunkProviderEnd{
public ChunkProviderHardcoreEnd(World world, long seed){
super(world,seed);
this.world = world;
this.randCopy = endRNG;
this.randCopy = ReflectionUtils.getFieldValue(this, "endRNG");
islandGen = new MapGenIsland();
towerGen = new MapGenTower();
@@ -11,6 +11,7 @@ import net.minecraft.world.gen.structure.MapGenStructureIO;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import chylex.hee.system.util.ReflectionUtils;
import chylex.hee.world.biome.BiomeGenHardcoreEnd;
import chylex.hee.world.structure.island.ComponentIsland;
import chylex.hee.world.structure.island.StructureIsland;
@@ -21,7 +22,7 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
public final class DimensionOverride{
public static void setup(){
BiomeGenBase.getBiomeGenArray()[9] = null;
BiomeGenBase.sky = new BiomeGenHardcoreEnd(9).setColor(8421631).setBiomeName("Sky").setDisableRain();
ReflectionUtils.setFieldValue(BiomeGenBase.class, "sky", new BiomeGenHardcoreEnd(9).setColor(8421631).setBiomeName("Sky").setDisableRain());
BiomeGenBase.getBiomeGenArray()[9] = BiomeGenBase.sky;
MapGenStructureIO.registerStructure(StructureTower.class,"hardcoreenderdragon_EndTower");
@@ -60,7 +61,7 @@ public final class DimensionOverride{
public void onWorldLoad(WorldEvent.Load e){
if (e.world.provider.dimensionId == 1 && e.world instanceof WorldServer){
WorldServer world = (WorldServer)e.world;
world.chunkProvider = world.theChunkProviderServer = new ChunkProviderServerOverride(world);
ReflectionUtils.setFieldValue(world, "chunkProvider", (world.theChunkProviderServer = new ChunkProviderServerOverride(world)));
}
}
-22
View File
@@ -1,22 +0,0 @@
# C:\Gradle\caches\minecraft\net\minecraftforge\forge\1.7.10-10.13.0.1208\unpacked\conf
public net.minecraft.util.RegistrySimple field_82596_a # registryObjects
public net.minecraft.util.RegistryNamespaced field_148759_a # underlyingIntegerMap
public-f net.minecraft.item.ItemBlock field_150939_a # block
public net.minecraft.entity.EntityLivingBase field_110153_bc # lastDamage
public net.minecraft.entity.EntityLiving field_82174_bp # equipmentDropChances
public net.minecraft.entity.Entity field_70151_c # fire
public net.minecraft.entity.monster.EntityGhast field_70792_g # targetedEntity
public net.minecraft.nbt.NBTTagList field_74747_a # tagList
public net.minecraft.network.NetHandlerPlayServer field_147365_f # floatingTickCount
public net.minecraft.network.NetHandlerPlayServer field_147373_o # lastPosX
public net.minecraft.network.NetHandlerPlayServer field_147382_p # lastPosY
public net.minecraft.network.NetHandlerPlayServer field_147381_q # lastPosZ
public net.minecraft.world.gen.ChunkProviderEnd field_73204_i # endRNG
public-f net.minecraft.world.biome.BiomeGenBase field_76779_k # sky
public net.minecraft.world.World field_73020_y # chunkProvider
public net.minecraft.client.Minecraft field_147126_aw # mcMusicTicker
public net.minecraft.client.gui.inventory.GuiContainer field_146999_f # xSize
public net.minecraft.client.gui.inventory.GuiContainer field_147000_g # ySize
public net.minecraft.client.renderer.RenderGlobal field_147593_P # mapSoundPositions