Skip to content

Comments

NativeAPI: Expose TypeTreeGenerator_getMonoBehaviorDefinitions#1

Merged
K0lb3 merged 2 commits intoUnityPy-Org:mainfrom
mos9527:patch-1
Feb 26, 2025
Merged

NativeAPI: Expose TypeTreeGenerator_getMonoBehaviorDefinitions#1
K0lb3 merged 2 commits intoUnityPy-Org:mainfrom
mos9527:patch-1

Conversation

@mos9527
Copy link
Contributor

@mos9527 mos9527 commented Feb 18, 2025

This PR exposes GetMonoBehaviourDefinitions to the Python side of things

Can be accessed through TypeTreeGenerator.get_monobehavior_definitions where it returns a list of (module name, class full path) which can be then used as arguments to e.g. get_nodes

names_ptr, ctypes.POINTER(ctypes.c_char_p * names_cnt.value)
).contents
names = [name.decode("ascii") for name in names_array]
DLL.FreeCoTaskMem(names_ptr)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would leak memory, as the array pointers to the names wouldn't be freed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which reminds me, that I still have to double check if the raw typetree struct leaks or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which reminds me, that I still have to double check if the raw typetree struct leaks or not.

Unfortunately it does according to the docs :(

fDeleteOld
true to call the DestroyStructure(IntPtr, Type) method on the ptr parameter before this method copies the data. The block must contain valid data. Note that passing false when the memory block already contains data can lead to a memory leak.

Back to this one - when I was trying to free the allocated strings with the following snippet Python seem to crash after a few frees. Any ideas why this is happening?

        for ptr in ptr_array:
            ptr = ctypes.cast(ptr, ctypes.c_void_p).value
            DLL.FreeCoTaskMem(ptr)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that the iterator doesn't work as intended.
I managed to fix it, but the solution isn't pretty.

So I'm simply going to include free function in the NativeAPI as well, which would also make usage in other languages next to python easier and less hacky.

{
string module = typeNames[i].Module.Name;
string fullName = typeNames[i].FullName;
Marshal.WriteIntPtr(arrayPtr, (i * 2) * Marshal.SizeOf<IntPtr>(), Marshal.StringToCoTaskMemAnsi(module));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might result in errors if the names include non ansi ascii compatible characters.
StringToCoTaskMemUTF8( would be better.

I should use this for the json code.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the encoding system locally just now, so that the system's default encoding gets used to prevent possible issues.

NativeAPI: Use UTF8 for string encoding
@mos9527
Copy link
Contributor Author

mos9527 commented Feb 20, 2025

Thanks again for the awesome project and code reviews! There's something else that might be out of context for this very PR I'd like to disscuss though:
As of the current commit only TypeTrees of nodes with base of MonoBehavior is correctly exportable. This is sufficient in many cases but for the sake of correctness (and for a WIP codegen script) maybe this should be rectified.
For example - with Live2D Unity SDK there's plenty of classes that's based on ScriptableObject

namespace Live2D.Cubism.Framework.Expression
{
	// Token: 0x020001B1 RID: 433
	[Token(Token = "0x020001B1")]
	public class CubismExpressionList : ScriptableObject
	{
		// Token: 0x06000989 RID: 2441 RVA: 0x000F26DF File Offset: 0x000F08DF
		[Token(Token = "0x06000989")]
		[Address(RVA = "0x053CEEA8", Offset = "0x53CEEA8", VA = "0x00000070C889AEA8")]
		public CubismExpressionList()
		{
		}

		// Token: 0x040005E0 RID: 1504
		[FieldOffset(Offset = "0x18")]
		[Token(Token = "0x040005E0")]
		[SerializeField]
		public CubismExpressionData[] CubismExpressionObjects;
	}
}

The TypeTree generator however assumes the nodes would always base on MonoBehavior which isn't true in this case

        public List<TypeTreeNode> GenerateTreeNodes(TypeDefinition typeDef)
        {
            //  from AssetStudioUtility.MonoBehaviourConverter
            var m_Nodes = new List<TypeTreeNode>();
            serializedTypeHelper.AddMonoBehaviour(m_Nodes, 0);
            var converter = new TypeDefinitionConverter(typeDef, serializedTypeHelper, 1);
            m_Nodes.AddRange(converter.ConvertToTypeTreeNodes());
            return m_Nodes;
        }

This is also an issue with the old dumper/https://github.com/K0lb3/TypeTreeGenerator.
Normally this won't be an issue since TypeTrees do contain all the fields recursively - but it would be nice if this can be also corrected.
Also there's no API yet to dump all the types of all bases yet. Perhaps there can be one to dump all the type definitions not limited to MonoBehavior too? (the motivations, again, mostly come from the said codegen script)

@K0lb3
Copy link
Collaborator

K0lb3 commented Feb 24, 2025

The TypeTree generator however assumes the nodes would always base on MonoBehavior which isn't true in this case
I'm aware of the issue. It also fails to include classes that are indirect subtypes of MonoBehaviour.
I guess that ScriptableObject can be included by hand for now as well.
Later on the TPK dump can be used to correctly generate the parent, and then go from there to include the custom fields.

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.

2 participants