Jump to content

Recommended Posts

Posted (edited)

So I was going to implement and try to edit a final field like I found online on how to do but, I discovered I wasn't even calling my new method and it was working. By changing block material.

public static void setMaterial(Block b, Material m)
{
		ReflectionUtil.setObject(b, m, Block.class, "blockMaterial");
}
public static void setObject(Object instance,Object toset,Class clazz,String str)
{
	try{
		ReflectionHelper.findField(clazz, str).set(instance,toset);
	}catch(Exception e){e.printStackTrace();}
}

 

Main Class:
 

System.out.println("Before:" + (BlockApi.getblockmaterial(Blocks.STONE) == Material.ROCK) );
		BlockApi.setMaterial(Blocks.STONE, Material.WOOD);
		System.out.println("After:" + (BlockApi.getblockmaterial(Blocks.STONE) == Material.ROCK) + " isWood:" + (BlockApi.getblockmaterial(Blocks.STONE) == Material.WOOD) );

Output:

true
false isWood:true

 

Edited by jredfox
Posted (edited)
9 minutes ago, diesieben07 said:
  • Don't ignore exceptions. No, printStackTrace is not handling them.
  • ReflectionHelper already has setPrivateValue.
  • When accessing the same field multiple times, store the Field instance and re-use it. Do not look it up every time.
  • You must also provide the SRG name for vanilla Minecraft fields, see MCPBot.

yes I know that I was doing a debug test. I fixed it using MCPMappingsApi my own

I was stating for some reason I was able to change the final field even though it's suppose to be never changed because it was final. Does this mean the final was removed at runtime?

	public static void setMaterial(Block b, Material m)
	{
		ReflectionUtil.setObject(b, m, Block.class, MCPMappings.getField(Block.class,"blockMaterial"));
	}


I choose to ignore exceptions specifically for this since if a mod is incompatible rather then the material not getting set or OS causing exceptions I would rather it continue the program and just not work in that specific area.

Edited by jredfox
Posted
40 minutes ago, diesieben07 said:

ReflectionHelper.findField calls Field::setAccessible(true), which disables access checks on fields (does not work for fields which are static and final).

 

Then log a proper warning message to the console instead of vomiting the stacktrace without further comment.

Well I have performed it on static fields before, as to why it's working on final fields I have no idea. I just set the instance to null when it's static.

Posted
Just now, diesieben07 said:

It is working on final fields, because setAccessible(true) is being called, this disables the finality of non-static fields.

You can also set static non-final non-accessible fields this way, but static final fields cannot be set.

ok setAccessible(true) is why it's being able to be modified even though it's final. Well I found this article for static final and it sounds like it works depending on the security enabled or not
https://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.