Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[1.7.10] [SOLVED] how to reference a field added by ASM at compile time?

Featured Replies

Posted

I add a public boolean field to PotionEffect via ASM and I wanted to know how can I access that field while writing my code. Do I need reflection?

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

  • Author

Both solutions sound good. when you say reflection you mean that unreflected getter/setter thing you taught me using

MethodHandle

and invokeExact, right?

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

no need to do that. if u make the clas implement ur interface via asm u can just cast to it and call the getter and setter. should be performance saving

  • Author

This is what I did, according to the teachings of diesieben07

 

/* in my actual code, the methods here span 3 classes that contain other methods and stuff, I simplified the code for clarity 
* (hopefully) putting all relevant methods to this use case together here and changing the names of some identifiers for
* readability. Because of that, something may have broke, because I'm doing theses edits directly in the textArea of this reply.
*/

private final static MethodHandle myFieldGetter = createGetterForField(PotionEffect.class, "gw_myField", "gw_myField");
private final static MethodHandle myFieldSetter = createSetterForField(PotionEffect.class, "gw_myField", "gw_myField");

public static MethodHandle createGetterForField(Class c, String forgeFieldName, String srgFieldName)
{
String fieldName = isDeobfEnvironment() ? forgeFieldName: srgFieldName;
Field field = null;
try
{
	field = c.getDeclaredField(fieldName);
}
catch (NoSuchFieldException e)
{
	// TODO this is unlikely to happen;
}
catch (SecurityException e)
{
	// TODO this is unlikely to happen;
}

field.setAccessible(true);

try
{
	return MethodHandles.publicLookup().unreflectGetter(field);
}
catch (IllegalAccessException e)
{
	return null;
}

public static MethodHandle createSetterForField(Class c, String forgeFieldName, String srgFieldName)
{
Field field = null;
String fieldName = FMLHelper.isDeobfEnvironment() ? forgeFieldName: srgFieldName;
try
{
	field = c.getDeclaredField(fieldName);
}
catch (NoSuchFieldException e)
{
}
catch (SecurityException e)
{
}

field.setAccessible(true);

try
{
	return MethodHandles.publicLookup().unreflectSetter(field);
}
catch (IllegalAccessException e)
{
	return null;
}
}

public static void setMyField(PotionEffect instance, boolean value) throws Throwable
{
myFieldSetter.invokeExact((PotionEffect)instance, value);
}

public static boolean getMyField(PotionEffect instance) throws Throwable
{
return (boolean) myFieldGetter.invokeExact((PotionEffect)instance);
}

public static boolean isDeobfEnvironment()
{
return (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
}

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

  • Author

Yes, I agree, that's a very good point. I usually end up ignoring a few when coding. In my real code I log those marked as "TODO" in this example. I just didn't want to clutter the solution with anything non essential. I was going to write something similar to your advice in the TODO comment, but I chose that short comment instead for simplicity.

WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.