Follow along with the video below to see how to install our site as a web app on your home screen.
Примечание: This feature may not be available in some browsers.
М? У меня просто переменная, не итем.Dragon2488 написал(а):Хватит лепить костыли. Имплементишь ISpecialArmor на предмете и делаешь нормально.
А как мне это сделать? Сделал при помощи либы глуми:Nichie написал(а):Свой хук на выход из метода ставить. Только так можно получить урон после всех расчетов.
@Hook
public static void hurt(LivingHurtEvent e)
{
System.out.println("+");
}
[13:57:05] [Server thread/INFO] [STDOUT]: [gloomyfolken.hooklib.asm.HookLogger$SystemOutLogger:debug:20]: [DEBUG] Injecting hooks into class net.minecraftforge.event.entity.living.LivingHurtEvent
[13:57:05] [Server thread/INFO] [STDOUT]: [gloomyfolken.hooklib.asm.HookLogger$SystemOutLogger:debug:20]: [DEBUG] Successfully injected 0 hooks
[13:57:05] [Server thread/INFO] [STDOUT]: [gloomyfolken.hooklib.asm.HookLogger$SystemOutLogger:warning:25]: [WARNING] Can not found target method of hook AsmHook: net.minecraftforge.event.entity.living.LivingHurtEvent#hurt() -> gloomyfolken.hooklib.example.AnnotationHooks#hurt(Lnet/minecraftforge/event/entity/living/LivingHurtEvent;)V, ReturnCondition=NEVER, ReturnValue=VOID, InjectorFactory: gloomyfolken.hooklib.asm.HookInjectorFactory$MethodEnter
1 - даNichie написал(а):Т.е. ты хранишь переменную, и после того, как рассчитается весь урон, который должен пройти по игроку, ты хочешь уменьшить его?
А почему ты не можешь сразу урезать урон? А после дать майну уменьшить его еще сильнее, с учетом брони и зелий? (Все в том же LivingHurtEvent)
damage = MyHookClass.foo(damage);
private byte[] transformEntityPlayer(byte[] bytecode, boolean obf) {
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytecode);
classReader.accept(classNode, 0);
// Тут твоя логика
ClassWriter writer = new ClassWriter(0);
classNode.accept(writer);
return writer.toByteArray();
}
Нет, я с таким дело не имел. Но очень надо, помоги пожалуйстаNichie написал(а):Тогда не все так просто.
Во первых. Хук тебе нужно ставить на выход из метода 'damageEntity' в классе 'EntityPlayer', а не в ивент.
А во вторых.. ASMHook тебе тут не поможет. Нужно ставить ручками хук.
С помощью ASMHook'a ты не сможешь вставить в метод такой код:
Код:damage = MyHookClass.foo(damage);
Если умеешь ставить хук ручками, то это хорошо.
HookLoader.registerHook(AsmHook.newBuilder()
.setTargetClass("net.minecraft.client.renderer.texture.TextureManager")
.setTargetMethod("bindTexture")
.addTargetMethodParameters("net.minecraft.util.ResourceLocation")
.setHookClass(HOOKS_CLASS)
.setHookMethod("bindTexture")
.addHookMethodParameter("net.minecraft.util.ResourceLocation", 1)
.setReturnCondition(ReturnCondition.ALWAYS)
.build());
И?Oldestkon написал(а):
@Override
public byte[] transform(String className, String s1, byte[] bytecode) {
if(className.equals("net.minecraft.entity.player.EntityPlayer")) {
bytecode = transformEntityPlayer(bytecode, false);
}
// TODO: Тут тебе еще нужно проверять на обф. имя класса. В таком случае вызывать с аргументом true.
return bytecode;
}
private byte[] transformEntityPlayer(byte[] bytecode, boolean obf) {
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytecode);
classReader.accept(classNode, 0);
String methodDamageEntity = obf ? "OBF ИМЯ МЕТОДА ТУТ" : "damageEntity";
String methodDamageEntityDesc = obf ? "Замени пути к классам на обф имена классов. Типо Lnet.minecraft.ItemStack; на Ladd;"
: "(Lnet/minecraft/util/DamageSource;F)V";
for (MethodNode method : classNode.methods) {
if(method.name.equals(methodDamageEntity) && method.desc.equals(methodDamageEntityDesc)) {
for(int i = 0; i < method.instructions.size(); i+=4) {
AbstractInsnNode currentLine;
if((currentLine = method.instructions.get(i)).getOpcode() == Opcodes.ALOAD &&
currentLine.getNext().getOpcode() == Opcodes.ALOAD &&
currentLine.getNext().getNext().getOpcode() == Opcodes.INVOKEVIRTUAL &&
currentLine.getNext().getNext().getNext().getOpcode() == Opcodes.INVOKEVIRTUAL) {
method.instructions.insertBefore(currentLine, new VarInsnNode(Opcodes.ALOAD, 0));
method.instructions.insertBefore(currentLine, new VarInsnNode(Opcodes.ALOAD, 1));
method.instructions.insertBefore(currentLine, new VarInsnNode(Opcodes.ALOAD, 2));
method.instructions.insertBefore(currentLine, new MethodInsnNode(Opcodes.INVOKESTATIC, "nichiecode/coremod/asm/NichieTransformer", "entityPlayer_recalcDamage",
// TODO: Тут тоже нужно проверять на obf и менять имена классов на их обфусцированные имена
"(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/util/DamageSource;F)F", false));
method.instructions.insertBefore(currentLine, new VarInsnNode(Opcodes.FSTORE, 2));
break;
}
}
}
}
ClassWriter writer = new ClassWriter(0);
classNode.accept(writer);
return writer.toByteArray();
}
// Твой метод. Высчитывай урон как хочешь
public static float entityPlayer_recalcDamage(EntityPlayer p, DamageSource src, float srcDamage) {
return srcDamage / 2;
}
Да, дошло, чёт я между строк читал походуOldestkon написал(а):