Closed solomode0001 closed 5 months ago
Maybe will be added in BNM v2.0
Done in BNM v2.0 beta. (I will close issue with its release). Example: C# side:
public class Delegates : MonoBehaviour { // Who cares about style in testes?
public delegate int JustDelegate(int x, int y);
public JustDelegate justDelegateDef;
public UnityAction<int, int> JustUnityAction;
public Action<int, int> JustAction;
public UnityEvent<int, int> JustEvent;
private AndroidJavaClass logClass;
void Log(string s) { logClass.CallStatic<int>("e", "BNM_TargetApp", s); }
void Start()
{
logClass = new AndroidJavaClass("android.util.Log");
justDelegateDef += delegate
(int x, int y)
{
Log($"justDelegateDef(1) x: {x}, y: {y}");
return 1;
};
justDelegateDef += delegate
(int x, int y)
{
Log($"justDelegateDef(3) x: {x}, y: {y}");
return 3;
};
justDelegateDef += delegate(int x, int y)
{
Log($"justDelegateDef(500) x: {x}, y: {y}");
return 500;
};
JustAction += delegate
(int x, int y)
{
Log($"JustAction x: {x}, y: {y}");
return;
};
JustUnityAction += delegate
(int x, int y)
{
Log($"JustUnityAction x: {x}, y: {y}");
return;
};
JustEvent.AddListener(delegate
(int x, int y)
{
Log($"JustEvent x: {x}, y: {y}");
return;
});
}
}
C++ (BNM) side:
struct Delegates : BNM::UnityEngine::MonoBehaviour {
BNM::MulticastDelegate<int> *justDelegateDef;
BNM::UnityEngine::UnityAction<int, int> *JustUnityAction;
BNM::Structures::Mono::Action<int, int> *JustAction;
BNM::UnityEngine::UnityEvent<int, int> *JustEvent;
void *logClass;
BNM_CustomClass(Delegates, BNM::CompileTimeClassBuilder().Class("Delegates").Build(), {}, {});
void Start() {
BNM_CallOriginalCustomMethod(Start, this);
BNM_LOG_DEBUG("justDelegateDef: %p", justDelegateDef);
BNM_LOG_DEBUG("JustUnityAction: %p", JustUnityAction);
BNM_LOG_DEBUG("JustAction: %p", JustAction);
BNM_LOG_DEBUG("JustEvent: %p", JustEvent);
if (justDelegateDef) justDelegateDef->Invoke(10, 60);
if (JustUnityAction) JustUnityAction->Invoke(70, 9);
if (JustAction) JustAction->Invoke(30, 42);
if (JustEvent) JustEvent->Invoke(7, 234);
}
BNM_CustomMethod(Start, false, BNM::GetType<void>(), "Start");
};
Logs:
ByNameModding com.DefaultCompany.TestStructs D justDelegateDef: 0x7986ef6900
ByNameModding com.DefaultCompany.TestStructs D JustUnityAction: 0x7986ef67e0
ByNameModding com.DefaultCompany.TestStructs D JustAction: 0x7986ef6870
ByNameModding com.DefaultCompany.TestStructs D JustEvent: 0x7986eea480
BNM_TargetApp com.DefaultCompany.TestStructs E justDelegateDef(1) x: 10, y: 60
BNM_TargetApp com.DefaultCompany.TestStructs E justDelegateDef(3) x: 10, y: 60
BNM_TargetApp com.DefaultCompany.TestStructs E justDelegateDef(500) x: 10, y: 60
BNM_TargetApp com.DefaultCompany.TestStructs E JustUnityAction x: 70, y: 9
BNM_TargetApp com.DefaultCompany.TestStructs E JustAction x: 30, y: 42
BNM_TargetApp com.DefaultCompany.TestStructs E JustEvent x: 7, y: 234
Work with stripped engine code.
Done in BNM v2.0 beta. (I will close issue with its release). Example: C# side:
public class Delegates : MonoBehaviour { // Who cares about style in testes? public delegate int JustDelegate(int x, int y); public JustDelegate justDelegateDef; public UnityAction<int, int> JustUnityAction; public Action<int, int> JustAction; public UnityEvent<int, int> JustEvent; private AndroidJavaClass logClass; void Log(string s) { logClass.CallStatic<int>("e", "BNM_TargetApp", s); } void Start() { logClass = new AndroidJavaClass("android.util.Log"); justDelegateDef += delegate (int x, int y) { Log($"justDelegateDef(1) x: {x}, y: {y}"); return 1; }; justDelegateDef += delegate (int x, int y) { Log($"justDelegateDef(3) x: {x}, y: {y}"); return 3; }; justDelegateDef += delegate(int x, int y) { Log($"justDelegateDef(500) x: {x}, y: {y}"); return 500; }; JustAction += delegate (int x, int y) { Log($"JustAction x: {x}, y: {y}"); return; }; JustUnityAction += delegate (int x, int y) { Log($"JustUnityAction x: {x}, y: {y}"); return; }; JustEvent.AddListener(delegate (int x, int y) { Log($"JustEvent x: {x}, y: {y}"); return; }); } }
C++ (BNM) side:
struct Delegates : BNM::UnityEngine::MonoBehaviour { BNM::MulticastDelegate<int> *justDelegateDef; BNM::UnityEngine::UnityAction<int, int> *JustUnityAction; BNM::Structures::Mono::Action<int, int> *JustAction; BNM::UnityEngine::UnityEvent<int, int> *JustEvent; void *logClass; BNM_CustomClass(Delegates, BNM::CompileTimeClassBuilder().Class("Delegates").Build(), {}, {}); void Start() { BNM_CallOriginalCustomMethod(Start, this); BNM_LOG_DEBUG("justDelegateDef: %p", justDelegateDef); BNM_LOG_DEBUG("JustUnityAction: %p", JustUnityAction); BNM_LOG_DEBUG("JustAction: %p", JustAction); BNM_LOG_DEBUG("JustEvent: %p", JustEvent); if (justDelegateDef) justDelegateDef->Invoke(10, 60); if (JustUnityAction) JustUnityAction->Invoke(70, 9); if (JustAction) JustAction->Invoke(30, 42); if (JustEvent) JustEvent->Invoke(7, 234); } BNM_CustomMethod(Start, false, BNM::GetType<void>(), "Start"); };
Logs:
ByNameModding com.DefaultCompany.TestStructs D justDelegateDef: 0x7986ef6900 ByNameModding com.DefaultCompany.TestStructs D JustUnityAction: 0x7986ef67e0 ByNameModding com.DefaultCompany.TestStructs D JustAction: 0x7986ef6870 ByNameModding com.DefaultCompany.TestStructs D JustEvent: 0x7986eea480 BNM_TargetApp com.DefaultCompany.TestStructs E justDelegateDef(1) x: 10, y: 60 BNM_TargetApp com.DefaultCompany.TestStructs E justDelegateDef(3) x: 10, y: 60 BNM_TargetApp com.DefaultCompany.TestStructs E justDelegateDef(500) x: 10, y: 60 BNM_TargetApp com.DefaultCompany.TestStructs E JustUnityAction x: 70, y: 9 BNM_TargetApp com.DefaultCompany.TestStructs E JustAction x: 30, y: 42 BNM_TargetApp com.DefaultCompany.TestStructs E JustEvent x: 7, y: 234
Work with stripped engine code.
Oh my gosh, I can't wait for it to be released! I hope it comes out soon. Thank you so much!
However, if I may ask for one more thing, how can we create a feature to call Java methods like this:
public class MyToast {
public static void showToast(Context context, String message, int length) {
Toast.makeText(context, message, length).show();
}
}
void Start()
{
auto unityPlayer = BNM::LoadJavaClass("com.unity3d.player.UnityPlayer");
auto currentActivity = unityPlayer.GetStatic<void*>("currentActivity");
auto myClass = BNM::LoadJavaClass("com.bynamemodding.MyToastClass");
myClass.CallStatic<void>("showToast", currentActivity, "Hello From Bynamemodding");
}
If this is possible, ByNameModding will have the most complete and best features for modding
However, if I may ask for one more thing, how can we create a feature to call Java methods like this:
public class MyToast { public static void showToast(Context context, String message, int length) { Toast.makeText(context, message, length).show(); } } void Start() { auto unityPlayer = BNM::LoadJavaClass("com.unity3d.player.UnityPlayer"); auto currentActivity = unityPlayer.GetStatic<void*>("currentActivity"); auto myClass = BNM::LoadJavaClass("com.bynamemodding.MyToastClass"); myClass.CallStatic<void>("showToast", currentActivity, "Hello From Bynamemodding"); }
If this is possible, ByNameModding will have the most complete and best features for modding
Java API don't needed because Android has JNI. And if you don't like C API, I think on github you can find C++ wrapper. BNM's main target is Unity, not JNI.
#include <jni.h>
JavaVM *globalVm{};
jclass UnityPlayer{};
jclass myClass{};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, [[maybe_unused]] void *reserved) {
JNIEnv *env;
vm->GetEnv((void **) &env, JNI_VERSION_1_6);
globalVm = vm;
UnityPlayer = (jclass) env->NewGlobalRef(env->FindClass(OBFUSCATE_BNM("com/unity3d/player/UnityPlayer")));
myClass = (jclass) env->NewGlobalRef(env->FindClass(OBFUSCATE_BNM("com/bynamemodding/MyToastClass")));
return JNI_VERSION_1_6;
}
void Start() {
JNIEnv *env;
globalVm->GetEnv((void **) &env, JNI_VERSION_1_6);
if (!env) globalVm->AttachCurrentThread(&env, nullptr);
auto currentActivityId = env->GetFieldID(UnityPlayer, OBFUSCATE_BNM("currentActivity"), OBFUSCATE_BNM("Landroid/app/Activity;"));
auto currentActivity = env->GetStaticObjectField(UnityPlayer, currentActivityId);
auto showToast = env->GetStaticMethodID(myClass, OBFUSCATE_BNM("showToast"), OBFUSCATE_BNM("(Landroid/context/Context;Ljava/lang/String;I)V"));
env->CallStaticVoidMethod(myClass, showToast, currentActivity, env->NewStringUTF(OBFUSCATE_BNM("Hello From ByNameModding")), 0);
}
v2.0 Beta released.
System.Action
UnityEngine.Events.UnityAction
UnityEngine.Events.UnityEvent
With parameter