2
0
Fork 0

Fixed bukkit damage event breaking from EntityLivingBase mixin

main
Shinare 1 year ago
parent 7efd097de5
commit 4b35d7f9b6

@ -1,15 +1,15 @@
package com.zivilon.cinder_loe.mixins; package com.zivilon.cinder_loe.mixins;
import com.zivilon.cinder_loe.util.Pair; import com.zivilon.cinder_loe.util.*;
import com.zivilon.cinder_loe.util.DamageEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.injection.callback.*;
import net.minecraft.potion.Potion; import net.minecraft.potion.Potion;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.passive.EntityTameable;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
@ -18,10 +18,14 @@ import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.ForgeHooks;
import java.lang.reflect.*;
import java.util.List; import java.util.List;
@Mixin(EntityLivingBase.class) @Mixin(EntityLivingBase.class)
public abstract class MixinEntityLivingBase extends Entity { public abstract class MixinEntityLivingBase extends Entity {
private static boolean checked_cauldron = false;
private static Method cauldron_method;
@Shadow @Shadow
protected int entityAge; protected int entityAge;
@Shadow @Shadow
@ -50,13 +54,13 @@ public abstract class MixinEntityLivingBase extends Entity {
@Shadow @Shadow
protected abstract String getHurtSound(); protected abstract String getHurtSound();
@Shadow @Shadow
public abstract void onDeath(DamageSource p_70645_1_); public abstract void onDeath(DamageSource source);
@Shadow @Shadow
protected abstract String getDeathSound(); protected abstract String getDeathSound();
@Shadow @Shadow
public abstract float getHealth(); public abstract float getHealth();
@Shadow @Shadow
public abstract void knockBack(Entity p_70653_1_, float p_70653_2_, double p_70653_3_, double p_70653_5_); public abstract void knockBack(Entity entity, float strength, double direction_x, double direction_z);
@Shadow @Shadow
public abstract void setRevengeTarget(EntityLivingBase p_70604_1_); public abstract void setRevengeTarget(EntityLivingBase p_70604_1_);
@Shadow @Shadow
@ -79,40 +83,53 @@ public abstract class MixinEntityLivingBase extends Entity {
@Overwrite @Overwrite
public boolean attackEntityFrom(DamageSource source, float damage) { public boolean attackEntityFrom(DamageSource source, float damage) {
if (ForgeHooks.onLivingAttack((EntityLivingBase)(Object)this, source, damage)) return false; if (ForgeHooks.onLivingAttack((EntityLivingBase)(Object)this, source, damage)) return false;
if (this.isEntityInvulnerable()) { if (this.isEntityInvulnerable()) return false;
return false; if (this.worldObj.isRemote) return false;
} else if (this.worldObj.isRemote) { this.entityAge = 0;
return false;
} else {
this.entityAge = 0;
if (this.getHealth() <= 0.0F) { if (this.getHealth() <= 0.0F) return false;
return false; if (source.isFireDamage() && isPotionActive(Potion.fireResistance)) return false;
} else if (source.isFireDamage() && this.isPotionActive(Potion.fireResistance)) {
return false;
}
DamageEvent event = new DamageEvent(source, damage, (EntityLivingBase)(Object)this, source.getEntity()); if (!(checked_cauldron)) {
Pair<DamageEvent, Boolean> result = DamageEvent.run_events(event); check_cauldron();
if (result.value) return false; checked_cauldron = true;
damage = result.key.damage; }
DamageEvent event = new DamageEvent(source, damage, (EntityLivingBase)(Object)this, source.getEntity());
Pair<DamageEvent, Boolean> result = DamageEvent.run_events(event);
if (result.value) return false;
damage = result.key.damage;
if (cauldron_method == null) {
if ((source == DamageSource.anvil || source == DamageSource.fallingBlock) && this.getEquipmentInSlot(4) != null) { if ((source == DamageSource.anvil || source == DamageSource.fallingBlock) && this.getEquipmentInSlot(4) != null) {
this.getEquipmentInSlot(4).damageItem((int)(damage * 4.0F + this.rand.nextFloat() * damage * 2.0F), (EntityLivingBase)(Object)this); this.getEquipmentInSlot(4).damageItem((int)(damage * 4.0F + this.rand.nextFloat() * damage * 2.0F), (EntityLivingBase)(Object)this);
damage *= 0.75F; damage *= 0.75F;
} }
}
this.limbSwingAmount = 1.5F; this.limbSwingAmount = 1.5F;
boolean flag = true; boolean flag = true;
if ((float)this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F) {
if (damage <= this.lastDamage) {
return false;
}
if (this.hurtResistantTime > (float)this.maxHurtResistantTime / 2.0F) {
if (damage <= this.lastDamage) return false;
if (cauldron_method != null) {
boolean cauldron_cancel = entitydamage_cauldron(source, damage - this.lastDamage);
if (!cauldron_cancel) return false;
} else {
this.damageEntity(source, damage - this.lastDamage); this.damageEntity(source, damage - this.lastDamage);
}
this.lastDamage = damage;
flag = false;
} else {
if (cauldron_method != null) {
float previousHealth = getHealth();
boolean cauldron_cancel = entitydamage_cauldron(source, damage);
if (!cauldron_cancel) return false;
this.lastDamage = damage; this.lastDamage = damage;
flag = false; this.prevHealth = previousHealth;
this.hurtResistantTime = this.maxHurtResistantTime;
this.hurtTime = this.maxHurtTime = 10;
} else { } else {
this.lastDamage = damage; this.lastDamage = damage;
this.prevHealth = this.getHealth(); this.prevHealth = this.getHealth();
@ -120,69 +137,100 @@ public abstract class MixinEntityLivingBase extends Entity {
this.damageEntity(source, damage); this.damageEntity(source, damage);
this.hurtTime = this.maxHurtTime = 10; this.hurtTime = this.maxHurtTime = 10;
} }
}
this.attackedAtYaw = 0.0F; this.attackedAtYaw = 0.0F;
Entity entity = source.getEntity(); Entity entity = source.getEntity();
if (entity != null) { if (entity != null) {
if (entity instanceof EntityLivingBase) { if (entity instanceof EntityLivingBase)
this.setRevengeTarget((EntityLivingBase)entity); this.setRevengeTarget((EntityLivingBase)entity);
}
if (entity instanceof EntityPlayer) { if (entity instanceof EntityPlayer) {
this.recentlyHit = 100; this.recentlyHit = 100;
this.attackingPlayer = (EntityPlayer)entity; this.attackingPlayer = (EntityPlayer)entity;
} else if (entity instanceof net.minecraft.entity.passive.EntityTameable) { } else if (entity instanceof EntityTameable) {
net.minecraft.entity.passive.EntityTameable entitywolf = (net.minecraft.entity.passive.EntityTameable)entity; EntityTameable entitywolf = (EntityTameable)entity;
if (entitywolf.isTamed()) { if (entitywolf.isTamed()) {
this.recentlyHit = 100; this.recentlyHit = 100;
this.attackingPlayer = null; this.attackingPlayer = null;
}
} }
} }
}
if (flag) { if (flag) {
this.worldObj.setEntityState(this, (byte)2); this.worldObj.setEntityState((Entity)this, (byte)2);
if (source != DamageSource.drown)
this.setBeenAttacked();
if (source != DamageSource.drown) { if (entity != null) {
this.setBeenAttacked(); double d1 = entity.posX - this.posX;
} double d0;
if (entity != null) {
double d1 = entity.posX - this.posX;
double d0;
for (d0 = entity.posZ - this.posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) { for (d0 = entity.posZ - this.posZ; d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D)
d1 = (Math.random() - Math.random()) * 0.01D; d1 = (Math.random() - Math.random()) * 0.01D;
}
this.attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - this.rotationYaw; this.attackedAtYaw = (float)(Math.atan2(d0, d1) * 180.0D / Math.PI) - this.rotationYaw;
this.knockBack(entity, damage, d1, d0); this.knockBack(entity, damage, d1, d0);
} else { } else {
this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180); this.attackedAtYaw = (float)((int)(Math.random() * 2.0D) * 180);
}
} }
}
String s; String sound;
if (this.getHealth() <= 0.0F) { if (getHealth() <= 0.0F) {
s = this.getDeathSound(); sound = getDeathSound();
if (flag && s != null) { if (flag && sound != null)
this.playSound(s, this.getSoundVolume(), this.getSoundPitch()); this.playSound(sound, getSoundVolume(), getSoundPitch());
}
this.onDeath(source); onDeath(source);
} else { } else {
s = this.getHurtSound(); sound = getHurtSound();
if (flag && sound != null)
this.playSound(sound, getSoundVolume(), getSoundPitch());
}
if (flag && s != null) { return true;
this.playSound(s, this.getSoundVolume(), this.getSoundPitch()); }
@Dynamic
private void check_cauldron() {
try {
Class<?> target_class = EntityLivingBase.class;
while (target_class != null) {
Method[] methods = target_class.getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("damageEntity_CB")) {
cauldron_method = method;
return;
}
} }
} }
} catch (Exception e) {
e.printStackTrace();
}
return;
}
return true; @Dynamic
public boolean entitydamage_cauldron(DamageSource source, float damage) {
boolean return_value = true;
if (cauldron_method != null) {
try {
Object result = cauldron_method.invoke(this, source, damage);
if (result instanceof Boolean) { // Check if the result is a boolean
return_value = (Boolean) result;
}
} catch (IllegalAccessException | InvocationTargetException e) {
}
} }
return return_value;
} }
} }

@ -10,7 +10,7 @@ import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Field; import java.lang.reflect.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.UUID; import java.util.UUID;
@ -153,31 +153,6 @@ public class Utilities {
return builder.toString(); return builder.toString();
} }
public static void dumpClass(String className, String outputFilePath, Class<?> contextClass) {
// Convert class name to a resource path
String resourcePath = className.replace('.', '/') + ".class";
// Use the class loader of the context class to find the resource
try (InputStream classStream = contextClass.getClassLoader().getResourceAsStream(resourcePath)) {
if (classStream == null) {
System.err.println("Class " + className + " could not be found.");
return;
}
try (OutputStream outputStream = new FileOutputStream(outputFilePath)) {
// Copy the class stream to the output file
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = classStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
System.out.println("Dumped " + className + " to " + outputFilePath);
} catch (IOException e) {
System.err.println("Failed to write class file: " + e.getMessage());
}
} catch (IOException e) {
System.err.println("Failed to read class file: " + e.getMessage());
}
}
public static void writeLog(String message) { public static void writeLog(String message) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("custom_log.txt", true))) { try (BufferedWriter writer = new BufferedWriter(new FileWriter("custom_log.txt", true))) {
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();

Loading…
Cancel
Save