public FunctionRedirect(IntPtr unrealClass, string dummyName, Delegate callback) { Debug.Assert(!Native_UStruct.IsChildOf(unrealClass, Runtime.Classes.UClass)); Class = unrealClass; DummyName = dummyName; Callback = callback; }
public bool IsChildOf(UStruct someBase) { if (someBase == null) { return(false); } return(Native_UStruct.IsChildOf(Address, someBase.Address)); }
/// <summary> /// Validates that the given property exists and matches the given UProperty class (e.g. UBoolProperty::StaticClass()) /// </summary> /// <param name="unrealStruct">The address of the structure which owns the property</param> /// <param name="propertyName">The name of the property</param> /// <param name="propertyClass">The expected UProperty class of the property</param> /// <returns></returns> public static bool ValidatePropertyClass(IntPtr unrealStruct, string propertyName, IntPtr propertyClass) { IntPtr field = FindField(unrealStruct, propertyName); if (field == IntPtr.Zero || !Native_UObjectBaseUtility.IsA(field, Classes.UProperty)) { return(false); } IntPtr actualClass = Native_UObjectBase.GetClass(field); if (actualClass == propertyClass) { return(true); } if (actualClass != IntPtr.Zero && propertyClass == Classes.UEnumProperty && Native_UStruct.IsChildOf(actualClass, Classes.UNumericProperty)) { return(Native_UNumericProperty.IsEnum(field)); } return(false); }
/// <summary> /// Gets the first known type from a given UObject address (classes may be defined at runtime which we don't have a type mapping for. /// Look up the inheritance chain until we have a known type) /// </summary> /// <param name="objectAddress">The UObject address</param> /// <param name="isKnownType">True if the result is the exact type of the given UObject address</param> /// <param name="includeAbstract">Include abstract types (if true a wrapper cannot be instantiated from this type)</param> /// <returns>The first known managed type</returns> public static Type GetFirstKnownType(IntPtr objectAddress, out bool isKnownType, bool includeAbstract = true) { isKnownType = true; if (objectAddress == IntPtr.Zero) { return(null); } Type type = GetType(objectAddress); if (type != null && (!type.IsAbstract || includeAbstract)) { return(type); } else { type = null; } IntPtr parentClassAddress = IntPtr.Zero; IntPtr unrealClassAddress = Native_UObjectBase.GetClass(objectAddress); if (unrealClassAddress == Classes.UClass) { // The objectAddress is already a class unrealClassAddress = objectAddress; } if (unrealClassAddress != IntPtr.Zero) { parentClassAddress = Native_UStruct.GetSuperStruct(unrealClassAddress); } while (type == null && parentClassAddress != IntPtr.Zero) { isKnownType = false; classesByAddress.TryGetValue(parentClassAddress, out type); if (type != null && type.IsAbstract && !includeAbstract) { type = null; } parentClassAddress = Native_UStruct.GetSuperStruct(parentClassAddress); } if (type == null && unrealClassAddress != IntPtr.Zero) { // Some fallbacks if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UStruct)) { if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UClass)) { if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UBlueprintGeneratedClass)) { return(typeof(UBlueprintGeneratedClass)); } return(typeof(UClass)); } if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UScriptStruct)) { if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UUserDefinedStruct)) { return(typeof(UUserDefinedStruct)); } return(typeof(UScriptStruct)); } if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UEnum)) { if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UUserDefinedEnum)) { return(typeof(UUserDefinedEnum)); } return(typeof(UEnum)); } if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UFunction)) { return(typeof(UFunction)); } return(typeof(UStruct)); } // UObject fallback (would expect this to always be true) if (Native_UStruct.IsChildOf(unrealClassAddress, Classes.UObject)) { return(typeof(UObject)); } } return(type); }