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

Support injecting fields in il2cpp domain #24

Merged
merged 5 commits into from
Apr 9, 2022
Merged

Support injecting fields in il2cpp domain #24

merged 5 commits into from
Apr 9, 2022

Conversation

Kasuromi
Copy link
Member

@Kasuromi Kasuromi commented Apr 2, 2022

Summary

Class Injection

Injects a class' fields and their corresponding il2cpp type with proper attributes set (attributes are required for asset bundle field serialization)
Adds Il2CppReferenceField and Il2CppValueField each responsible for wrapping an il2cpp field at runtime.

Native Classes

Adds extra Size methods to UnityVersionHandler for each struct handler.
Wraps fields and field_count in native classes.
Wraps attrs in native types.

QOL

Il2CppObjectBase now has a propery ObjectClass which returns the object's native class pointer.
Fixes an exception being thrown in ClassInjector when a class has no namespace.
ClassInjector now uses a struct InjectedClassData to store the managed gc handle instead of an IntPtr.
Il2CppClassPointerStore now has a non-generic version that handles getting the class pointers through reflection.

Notes

Il2CppSystem.String reference types do not get deserialized correctly from asset bundles and do not persist after being set.
Il2Cpp*Field classes have a stub implicit operator to support future default value support but at the moment do nothing.

Field Injection Example

Unity Editor Script

public class TestScript : MonoBehaviour {
    public string refString;
    public GameObject refGameObject;
    public long longValue;
}

Injection Script

public class TestScript : MonoBehaviour {
    public void Start() {
        Log.LogInfo($"refGameObject.name -> {refGameObject.Get().name}");
        Log.LogInfo($"longValue -> {longValue.Get()}");
    }
    // this is the only reference type that doesn't get serialized correctly
    public Il2CppReferenceField<Il2CppSystem.String> refString;
    public Il2CppReferenceField<GameObject> refGameObject;
    public Il2CppValueField<long> longValue;
}

@Alexejhero
Copy link

@ghorsington Please take a look at this pull request when you have the chance. 🙂

@ghorsington
Copy link
Contributor

ghorsington commented Apr 9, 2022

This looks otherwise good to me, but I was mainly waiting if the string serialization issue was solved.

@Kasuromi: Are you going to have a look at the serialization issue in this same PR? I did try to check it out myself but wasn't able to determine the problem for now. It's fine if you don't want to fix it here; I'll just merge this and then make an issue that mentions the limitation (along with adding it to docs). If it's really the only limitation (just string serialization for assembly bundles), I think it's fine for now as long as in basic use case strings get injected fine.

@Kasuromi
Copy link
Member Author

Kasuromi commented Apr 9, 2022

Looked into strings a little further - it appears that the string data gets collected no matter where it comes from. Strings just don't persist for any significant period of time.

We can have this merged as is, I just need to push support for setting up the field wrappers when creating an injected object from managed space.

@ghorsington ghorsington merged commit 784fb98 into BepInEx:master Apr 9, 2022
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.

3 participants