Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added transformer for onUsingTick in EntityPlayer #414

Conversation

RecursivePineapple
Copy link
Contributor

EntityPlayer does not call onUsingTick properly on the server because it uses a == instead of a proper ItemStack.areItemStacksEqual call. Another piece of code constantly copies the itemInUse stack, so this condition is never true. This transformer changes the == to call ItemStack.areItemStacksEqual instead. This isn't a mixin because mixins can't change expressions like this.

EntityPlayer does not call onUsingTick properly on the server because
it uses a == instead of a proper ItemStack.areItemStacksEqual call.
Another piece of code constantly copies the itemInUse stack, so this
condition is never true. This transformer changes the == to call
ItemStack.areItemStacksEqual instead. This isn't a mixin because mixins
can't change expressions like this.
@RecursivePineapple
Copy link
Contributor Author

I've been testing this for a few weeks and it works well. I enabled the transformer on both sides (client & server) even though it's not necessary because the client only works by happenstance.

@Caedis Caedis requested review from mitchej123, a team and eigenraven August 29, 2024 03:32
Copy link
Member

@glowredman glowredman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Please use the correct types instead of var
  2. Please use a LOG4J logger instead of System.out

@Alexdoru
Copy link
Member

Another piece of code constantly copies the itemInUse stack

what other piece of code ?

public byte[] transform(String name, String transformedName, byte[] basicClass) {
if (basicClass == null) return null;

if (NameContext.Obf.entityPlayer.equals(name)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can check transformedName directly, it won't be obfuscated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it in the full pack and it looks like this isn't the case. I had to use the obfuscated name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do "net.minecraft.entity.player.EntityPlayer".equals(transformedName) even when in obfuscated environement

if (basicClass == null) return null;

if (NameContext.Obf.entityPlayer.equals(name)) {
final ClassReader cr = new ClassReader(basicClass);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write the class reader code once for both classes

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cn.accept(cw);

LOGGER.info("Transformed {}", name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to log that you are transforming a class, however you should use a try catch and if it returns an exception, you should log it and return the untransformed class

}

public void transformClassNode(NameContext names, ClassNode cn) {
LOGGER.info("Found EntityPlayer (class = {}, name context = {})", names.entityPlayer, names.name());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need to log


var cursor = method.instructions.getFirst();

while (cursor != null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why don't you use the built in iterator or a for loop over instructions.toArray()

import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;

public class ASMUtil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this class even used ? just delete it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was useful for me, so I figured I should leave it in for others. Instructions don't have a toString implementation, so you can't see what instructions in an InsnList do without debugging the transformer. Should I still remove it?

Copy link
Member

@Alexdoru Alexdoru Aug 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah remove it, you can see the instructions in intellij, select the class do View > show bytecode

final ClassReader cr = new ClassReader(basicClass);
final ClassNode cn = new ClassNode();
cr.accept(cn, 0);
transformClassNode(NameContext.Deobf, cn);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't do that to check the obfuscation state, check it from the injectData method in the IFMLLoadingPlugin implementation

@Alexdoru Alexdoru closed this Sep 1, 2024
@Alexdoru
Copy link
Member

Alexdoru commented Sep 1, 2024

this introduces a bug where if you have 2 of the same items in your hotbar for example 2 bows, you can draw your first bow and then switch the the second one and it will be fully draw, same with eating the same food

We should instead find what code changes the items while they are being used which prevents the vanilla code == from being true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants