Posted April 4, 20187 yr 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 April 4, 20187 yr by jredfox
April 4, 20187 yr Author 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 April 4, 20187 yr by jredfox
April 4, 20187 yr Author 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.
April 4, 20187 yr Author 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 nothttps://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.