예제 #1
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
 /// <summary>
 /// Gets all objects, including class default objects.
 /// </summary>
 public static FObjectIterator GetObjectsEx <T>(
     bool onlyGCedObjects = false,
     EObjectFlags additionalExclusionFlags       = EObjectFlags.NoFlags,
     EInternalObjectFlags internalExclusionFlags = EInternalObjectFlags.None) where T : UObject
 {
     return(GetObjectsEx(UClass.GetClass <T>(), onlyGCedObjects, additionalExclusionFlags, internalExclusionFlags));
 }
예제 #2
0
            public string ResolveNameConflict(UField field, string name)
            {
                UFunction function = field as UFunction;

                if (function != null)
                {
                    // Functions are a special case and must use the base-most function for name resolving.
                    // See above for more info on this.
                    UFunction originalFunction;
                    UClass    originalOwner = codeGenerator.GetOriginalFunctionOwner(function, out originalFunction);
                    if (originalOwner != Class)
                    {
                        StructInfo originalOwnerStructInfo = codeGenerator.GetStructInfo(originalOwner);
                        return(originalOwnerStructInfo.ResolveNameConflict(originalFunction, name));
                    }
                }

                string resolvedName;

                if (conflictInfo.ResolvedName.TryGetValue(field, out resolvedName))
                {
                    return(resolvedName);
                }

                return(name);
            }
예제 #3
0
 /// <summary>
 /// reate a component or subobject
 /// </summary>
 /// <typeparam name="TReturnType">class of return type, all overrides must be of this type </typeparam>
 /// <typeparam name="TClassToConstructByDefault">class to construct by default</typeparam>
 /// <param name="outer">outer to construct the subobject in </param>
 /// <param name="subobjectName">name of the new component </param>
 /// <param name="transient">true if the component is being assigned to a transient property</param>
 /// <returns></returns>
 public TReturnType CreateDefaultSubobject <TReturnType, TClassToConstructByDefault>(UObject outer, FName subobjectName, bool transient = false)
     where TReturnType : UObject
     where TClassToConstructByDefault : UObject
 {
     return(CreateDefaultSubobject(outer, subobjectName, UClass.GetClass <TReturnType>(),
                                   UClass.GetClass <TClassToConstructByDefault>(), true, false, transient) as TReturnType);
 }
예제 #4
0
        public TScriptInterface(T value)
        {
            IntPtr interfaceClass = UClass.GetInterfaceClassAddress <T>();

            if (interfaceClass == IntPtr.Zero)
            {
                Base = default(FScriptInterface);
                return;
            }

            IntPtr objectPointer = value.GetAddress();

            if (objectPointer == IntPtr.Zero)
            {
                Base = default(FScriptInterface);
                return;
            }

            IntPtr interfacePointer = Native_UObjectBaseUtility.GetNativeInterfaceAddress(objectPointer, interfaceClass);

            if (interfacePointer == IntPtr.Zero)
            {
                Base = default(FScriptInterface);
                return;
            }

            Base = new FScriptInterface(objectPointer, interfacePointer);
        }
예제 #5
0
        /// <summary>
        /// Gets the managed type for a given UClass
        /// </summary>
        /// <param name="unrealClass">The UClass to get the managed type for</param>
        /// <returns>The managed type</returns>
        public static Type GetType(UClass unrealClass)
        {
            Type type;

            classesByAddress.TryGetValue(unrealClass.Address, out type);
            return(type);
        }
예제 #6
0
        internal static void RegisterManagedClass(IntPtr classAddress, Type type)
        {
            UClass existingClass;

            if (classes.TryGetValue(type, out existingClass))
            {
                classes.Remove(type);
                classesByAddress.Remove(existingClass.Address);
            }
            seenClasses.Remove(type);

            classesByAddress[classAddress] = type;
            UClass unrealClass = GCHelper.Find <UClass>(classAddress);

            if (unrealClass != null)
            {
                classes[type] = unrealClass;
            }
            else
            {
                classesByAddress.Remove(classAddress);
            }

            // If this is an interface add it to UnrealInterfacePool so that we can create instances of this
            // interface which are implemented in Blueprint
            if (type.IsInterface)
            {
                UnrealInterfacePool.LoadType(type);
            }
        }
예제 #7
0
        internal static void Load()
        {
            classes.Clear();
            classesByAddress.Clear();
            seenClasses.Clear();

            // Use two passes so that classesByAddress has all available types which are needed when
            // calling GCHelper.Find() in the second pass

            // First pass to fill up classesByAddress collection
            foreach (KeyValuePair <Type, UMetaPathAttribute> nativeType in UnrealTypes.Native)
            {
                Type type = nativeType.Key;
                UMetaPathAttribute attribute = nativeType.Value;

                if (type.IsSameOrSubclassOf(typeof(UObject)) || type.IsInterface)
                {
                    IntPtr classAddress = GetClassAddress(attribute.Path);
                    if (classAddress != IntPtr.Zero)
                    {
                        classesByAddress[classAddress] = type;
                    }
                }
            }

            // It should now be safe to access GCHelper (which is required by the second pass to fill
            // in the classes collection with the managed UClass objects)
            GCHelper.Available = true;

            int unknownCount = 0;

            // Second pass fill up classes collection
            foreach (KeyValuePair <IntPtr, Type> classByAddress in classesByAddress)
            {
                IntPtr classAddress = classByAddress.Key;
                Type   type         = classByAddress.Value;

                UClass unrealClass = GCHelper.Find <UClass>(classAddress);
                if (unrealClass != null)
                {
                    classes[type] = unrealClass;
                }
                else
                {
                    unknownCount++;
                }
            }

            if (unknownCount > 0)
            {
                // sync classes/classByAddress if some failed to add to the classes collection
                foreach (KeyValuePair <IntPtr, Type> classByAddress in new Dictionary <IntPtr, Type>(classesByAddress))
                {
                    if (!classes.ContainsKey(classByAddress.Value))
                    {
                        classesByAddress.Remove(classByAddress.Key);
                    }
                }
            }
        }
        private bool CanExportStruct(UStruct unrealStruct)
        {
            // Ignore UProperty all classes
            if (unrealStruct.IsChildOf <UProperty>())
            {
                return(false);
            }

            // Skip classes which are already defined in this project
            if (projectDefinedTypes.ContainsKey(unrealStruct.GetPathName()))
            {
                return(false);
            }

            if (Settings.ExportAllStructures)
            {
                return(true);
            }

            UClass unrealClass = unrealStruct as UClass;

            if (unrealClass != null)
            {
                if (unrealClass.HasAnyClassFlags(EClassFlags.Deprecated))
                {
                    return(false);
                }
                // EClassFlags.Transient - should we be checking this
            }

            return(true);
        }
예제 #9
0
        private static T FindOrLoadObject <T>(string pathName) where T : UObject
        {
            if (typeof(T) == typeof(UPackage))
            {
                return(FindOrLoadPackage(pathName) as T);
            }

            // If there is no dot, add a dot and repeat the object name.
            int packageDelimPos = pathName.IndexOf('.');

            if (packageDelimPos == -1)
            {
                int objectNameStart = pathName.LastIndexOf('/');
                if (objectNameStart != -1)
                {
                    pathName += "." + pathName.Substring(objectNameStart + 1);
                }
            }

            UClass unrealClass = UClass.GetClass <T>();

            if (unrealClass != null)
            {
                unrealClass.GetDefaultObject();// force the CDO to be created if it hasn't already
                T obj = UObject.LoadObject <T>(null, pathName);
                if (obj != null)
                {
                    obj.AddToRoot();
                }
                return(obj);
            }
            return(null);
        }
예제 #10
0
        public static void SetMetaData <T>(IntPtr obj, string key, T value)
        {
            string valueStr    = null;
            UClass unrealClass = value as UClass;

            if (unrealClass != null)
            {
                valueStr = unrealClass.GetPathName();
            }
            else
            {
                valueStr = value.ToString();
            }

            IntPtr metadata = GetMetaDataFromObj(obj);

            if (metadata != IntPtr.Zero)
            {
                using (FStringUnsafe keyUnsafe = new FStringUnsafe(key))
                    using (FStringUnsafe valueUnsafe = new FStringUnsafe(key))
                    {
                        Native.Native_UMetaData.SetValue(metadata, obj, ref keyUnsafe.Array, ref valueUnsafe.Array);
                    }
            }
        }
예제 #11
0
        public T GetSubsystem <T>() where T : USubsystem
        {
            UClass uclass = UClass.GetClass(typeof(T));
            IntPtr system = Native_FSubsystemCollection.GetSubsystem(this.Address, uclass.Address);

            return(GCHelper.Find <T>(system));
        }
예제 #12
0
 internal static IntPtr GetStaticClass(Type type)
 {
     if (IsManagedUnrealType(type))
     {
         ManagedUnrealClass baseClass = FindClass(type);
         if (baseClass != null)
         {
             return(baseClass.StaticClass);
         }
         baseClass = CreateClass(type);
         if (baseClass != null)
         {
             return(baseClass.StaticClass);
         }
     }
     else
     {
         UMetaPathAttribute pathAttribute = type.GetCustomAttribute <UMetaPathAttribute>();
         if (pathAttribute != null)
         {
             return(UClass.FindClassAddressByPath(pathAttribute.Path));
         }
     }
     return(IntPtr.Zero);
 }
예제 #13
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
        public unsafe T GetInterface <T>() where T : class, IInterface
        {
            T result = this as T;

            if (result != null)
            {
                return(result);
            }
            if (injectedInterfaces == null)
            {
                // If the injected interfaces haven't been set up set them up now

                if (objRef == null)
                {
                    return(null);
                }

                UClass unrealClass = GetClass();
                if (unrealClass as USharpClass != null)
                {
                    // This is a C# defined type. We know if it implements the target interface or not due to the
                    // above "this as T". There isn't any need to inject interfaces into the UObject.
                    return(null);
                }

                FScriptArray *interfacesPtr = (FScriptArray *)Native_UClass.Get_InterfacesRef(unrealClass.Address);
                if (interfacesPtr->ArrayNum != 0)
                {
                    injectedInterfaces = new Dictionary <Type, IInterface>();
                    foreach (FImplementedInterface implementedInterface in unrealClass.Interfaces)
                    {
                        if (implementedInterface.InterfaceClassAddress != IntPtr.Zero)
                        {
                            Type type = UClass.GetTypeFromClassAddress(implementedInterface.InterfaceClassAddress);
                            if (type != null)
                            {
                                IInterface instance = UnrealInterfacePool.New(type, objRef);
                                if (instance != null)
                                {
                                    injectedInterfaces[type] = instance;
                                    if (type == typeof(T))
                                    {
                                        result = instance as T;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // Try and get the interface from the injected interfaces.
                IInterface instance;
                injectedInterfaces.TryGetValue(typeof(T), out instance);
                result = instance as T;
            }
            return(result);
        }
예제 #14
0
 /// <summary>
 /// Returns the class UClass if it is loaded. It is not possible to load the class if it is unloaded since we only have the short name.
 /// </summary>
 /// <returns></returns>
 public UClass GetClass()
 {
     if (!IsValid)
     {
         return(null);
     }
     return(UClass.GetClass(AssetClass.ToString()));
 }
예제 #15
0
 /// <summary>
 /// This will return whether or not this class implements the passed in class / interface
 /// </summary>
 /// <param name="someInterface">the interface to check and see if this class implements it</param>
 /// <returns></returns>
 public bool ImplementsInterface(UClass someInterface)
 {
     if (someInterface != null && someInterface.HasAnyClassFlags(EClassFlags.Interface))
     {
         return(Native_UClass.ImplementsInterface(Address, someInterface.Address));
     }
     return(false);
 }
예제 #16
0
 /// <summary>
 /// Returns an array of classes that were derived from the specified class.
 /// </summary>
 /// <param name="classToLookFor">The parent class of the classes to return.</param>
 /// <param name="recursive">If true, the results will include children of the children classes, recursively. Otherwise, only direct decedents will be included.</param>
 /// <returns></returns>
 public static UClass[] GetDerivedClasses(UClass classToLookFor, bool recursive = true)
 {
     using (TArrayUnsafe <UClass> result = new TArrayUnsafe <UClass>())
     {
         Native_UObjectHash.GetDerivedClasses(classToLookFor.Address, result.Address, recursive);
         return(result.ToArray());
     }
 }
예제 #17
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
 /// <summary>
 /// Gets all objects, including class default objects.
 /// </summary>
 public static FObjectIterator GetObjectsEx(
     UClass unrealClass,
     bool onlyGCedObjects = false,
     EObjectFlags additionalExclusionFlags       = EObjectFlags.NoFlags,
     EInternalObjectFlags internalExclusionFlags = EInternalObjectFlags.None)
 {
     return(new FObjectIterator(unrealClass, onlyGCedObjects, additionalExclusionFlags, internalExclusionFlags));
 }
예제 #18
0
 /// <summary>
 /// Returns an array of objects of a specific class. Optionally, results can include objects of derived classes as well.
 /// </summary>
 /// <param name="classToLookFor">Class of the objects to return.</param>
 /// <param name="includeDerivedClasses">If true, the results will include objects of child classes as well.</param>
 /// <param name="additionalExcludeFlags">Objects with any of these flags will be excluded from the results.</param>
 /// <param name="exclusionInternalFlags">Specifies internal flags to use as a filter for which objects to return</param>
 /// <returns></returns>
 public static UObject[] GetObjectsOfClass(UClass classToLookFor, bool includeDerivedClasses = true, EObjectFlags additionalExcludeFlags = EObjectFlags.ClassDefaultObject, EInternalObjectFlags exclusionInternalFlags = EInternalObjectFlags.None)
 {
     using (TArrayUnsafe <UObject> result = new TArrayUnsafe <UObject>())
     {
         Native_UObjectHash.GetObjectsOfClass(classToLookFor.Address, result.Address, includeDerivedClasses, additionalExcludeFlags, exclusionInternalFlags);
         return(result.ToArray());
     }
 }
        private bool IsBlueprintVisibleStruct(UStruct unrealStruct)
        {
            // All of the available macro tags at:
            // Engine\Source\Runtime\CoreUObject\Public\UObject\ObjectBase.h

            // BlueprintType = can use inside a blueprint
            // Blueprintable = can use as a new blueprint
            // Blueprintable seems to override NotBlueprintType?

            // IsBlueprintBase, BlueprintSpawnableComponent

            // All UBlueprintFunctionLibrary classes are visible in blueprint even if marked as not visible
            if (unrealStruct.IsChildOf <UBlueprintFunctionLibrary>())
            {
                return(true);
            }

            // Action classes are exposed to Blueprint as special nodes. We want the entire class.
            UClass unrealClass = unrealStruct as UClass;

            if (unrealClass != null && GetActionFactoryClass(unrealClass) != null)
            {
                return(true);
            }

            if (unrealStruct.GetBoolMetaDataHierarchical(MDClass.BlueprintSpawnableComponent))// && Struct.IsChildOf<UActorComponent>()
            {
                // Are all BlueprintSpawnableComponent classes visible even if marked not? TODO: Check this.
                return(true);
            }

            bool notBlueprintType = false;
            bool notBlueprintable = false;

            while (unrealStruct != null)
            {
                if (!notBlueprintType && unrealStruct.GetBoolMetaData(MDClass.BlueprintType))
                {
                    return(true);
                }
                if (!notBlueprintable && unrealStruct.GetBoolMetaData(MDClass.Blueprintable))
                {
                    return(true);
                }
                if (unrealStruct.GetBoolMetaData(MDClass.NotBlueprintType))
                {
                    notBlueprintType = true;
                }
                if (unrealStruct.GetBoolMetaData(MDClass.NotBlueprintable))
                {
                    notBlueprintable = true;
                }

                unrealStruct = unrealStruct.GetSuperStruct();
            }

            return(false);
        }
예제 #20
0
        public static unsafe void HackVTable(UObject obj)
        {
            // This will swap out the vtable entry and store the old one in our managed UClass

            if (!Native_UObjectBaseUtility.IsA(obj.Address, Runtime.Classes.UClass))
            {
                UClass unrealClass = obj.GetClass();
                if (unrealClass.VTableOriginalFunctions == null)
                {
                    IntPtr *vtable = *(IntPtr **)obj.Address;

                    unrealClass.VTableOriginalFunctions = new Dictionary <int, UClass.VTableOriginalFunc>();
                    foreach (FunctionRedirect redirect in vtableRedirects)
                    {
                        if (!Native_UObjectBaseUtility.IsA(obj.Address, redirect.Class))
                        {
                            continue;
                        }

                        IntPtr originalFunctionAddress = vtable[redirect.VTableIndex];

                        if (originalFunctionAddress != redirect.NativeCallback)
                        {
                            IntPtr originalOwnerClassAddress = FindOriginalVTableOwner(
                                redirect.Class, unrealClass.Address, originalFunctionAddress, redirect.VTableIndex);

                            if (originalOwnerClassAddress != unrealClass.Address)
                            {
                                UClass originalOwnerClass = GCHelper.Find <UClass>(originalOwnerClassAddress);
                                if (originalOwnerClass.VTableOriginalFunctions == null)
                                {
                                    HackVTable(originalOwnerClass.GetDefaultObject());
                                }
                            }

                            IntPtr pageAlignedPtr = FMemory.PageAlignPointer((IntPtr)(&vtable[redirect.VTableIndex]));
                            FMemory.PageProtect(pageAlignedPtr, (IntPtr)IntPtr.Size, true, true);
                            *(&vtable[redirect.VTableIndex]) = redirect.NativeCallback;
                        }
                        else
                        {
                            // The VTable has already been swapped out. Find the original function address.
                            UClass superClass = unrealClass;
                            while ((superClass = superClass.GetSuperClass()) != null && superClass.VTableOriginalFunctions == null)
                            {
                            }

                            Debug.Assert(superClass != null && superClass.VTableOriginalFunctions != null &&
                                         superClass.VTableOriginalFunctions.ContainsKey(redirect.VTableIndex));

                            originalFunctionAddress = superClass.VTableOriginalFunctions[redirect.VTableIndex].FuncAddress;
                        }

                        unrealClass.VTableOriginalFunctions.Add(redirect.VTableIndex, new UClass.VTableOriginalFunc(originalFunctionAddress));
                    }
                }
            }
        }
예제 #21
0
        /// <summary>
        /// Create a unique name by combining a base name and an arbitrary number string.
        /// The object name returned is guaranteed not to exist.
        /// </summary>
        /// <param name="outer">the outer for the object that needs to be named</param>
        /// <param name="unrealClass">the class for the object</param>
        /// <param name="baseName">optional base name to use when generating the unique object name; if not specified, the class's name is used</param>
        /// <returns>name is the form BaseName_##, where ## is the number of objects of this
        /// type that have been created since the last time the class was garbage collected.</returns>
        public static FName MakeUniqueObjectName(ObjectOuter outer, UClass unrealClass, FName baseName = default(FName))
        {
            FName result;

            Native_UObjectGlobals.MakeUniqueObjectName(outer.Address,
                                                       unrealClass == null ? IntPtr.Zero : unrealClass.Address,
                                                       ref baseName, out result);
            return(result);
        }
예제 #22
0
 /// <summary>
 /// Load a class object.
 /// </summary>
 public static UClass LoadClass(UClass baseClass, ObjectOuter outer, string name, string filename = null, ELoadFlags loadFlags = ELoadFlags.None)
 {
     using (FStringUnsafe nameUnsafe = new FStringUnsafe(name))
         using (FStringUnsafe filenameUnsafe = new FStringUnsafe(filename))
         {
             return(GCHelper.Find <UClass>(Native_UObjectGlobals.StaticLoadClass(
                                               baseClass.Address, outer.Address, ref nameUnsafe.Array, ref filenameUnsafe.Array, loadFlags, IntPtr.Zero)));
         }
 }
예제 #23
0
 public void SetClass(UClass unrealClass)
 {
     if (unrealClass != null && !unrealClass.IsA <T>())
     {
         throw new Exception("TAssetClass - tried to set class with the wrong target class type. Expected:" +
                             typeof(T) + " Actual:" + UClass.GetType(unrealClass.Address));
     }
     softObject.Value = unrealClass;
 }
예제 #24
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
        /// <summary>
        /// Returns true if this objects class implements the given IInterface derived type
        /// (call this on UObject instances; if you are working with a UClass call ImplementsInterface() instead).<para/>
        /// This is the equivalent of UKismetSystemLibrary::DoesImplementInterface().
        /// This is also the same as obj.GetClass().ImplementsInterface().
        /// </summary>
        /// <typeparam name="T">The IInterface derived type</typeparam>
        /// <returns>True if  this objects class implements the given IInterface derived type</returns>
        public bool DoesImplementInterface <T>() where T : IInterface
        {
            IntPtr interfaceClass = UClass.GetInterfaceClassAddress <T>();

            if (interfaceClass != IntPtr.Zero && Native_UClass.GetClassFlags(interfaceClass).HasFlag(EClassFlags.Interface))
            {
                return(Native_UClass.ImplementsInterface(Native_UObjectBase.GetClass(Address), interfaceClass));
            }
            return(false);
        }
예제 #25
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
        private static object DynamicInvokeInternal(UClass unrealClass, UObject obj, string functionName, params object[] parameters)
        {
            UFunction function = obj.GetClass().FindFunctionByName(new FName(functionName));

            if (function == null)
            {
                return(null);
            }
            return(function.DynamicInvoke(obj, parameters));
        }
예제 #26
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
        /// <summary>
        /// Invokes a UFunction of the given name using the CDO (class default object)
        /// </summary>
        public static object DynamicInvokeStatic <T>(string functionName, object[] parameters) where T : UObject
        {
            UClass unrealClass = UClass.GetClass <T>();

            if (unrealClass != null)
            {
                return(DynamicInvokeStatic(unrealClass, functionName, parameters));
            }
            return(null);
        }
예제 #27
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
        public bool IsA(Type type)
        {
            UClass unrealClass = UClass.GetClass(type);

            if (unrealClass == null)
            {
                return(false);
            }
            return(Native_UObjectBaseUtility.IsA(Address, unrealClass.Address));
        }
예제 #28
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
        /// <summary>
        /// Traverses the outer chain searching for the next object of a certain type.  (T must be derived from UObject)
        /// </summary>
        /// <typeparam name="T">class to search for</typeparam>
        /// <returns>a pointer to the first object in this object's Outer chain which is of the correct type.</returns>
        public UObject GetTypedOuter <T>() where T : UObject
        {
            UClass unrealClass = UClass.GetClass <T>();

            if (unrealClass != null)
            {
                return(GetTypedOuter(unrealClass));
            }
            return(null);
        }
예제 #29
0
파일: UObject.cs 프로젝트: OCEAN623/USharp
        /// <summary>
        /// Returns true if this objects class implements the given IInterface derived type
        /// (call this on UObject instances; if you are working with a UClass call ImplementsInterface() instead).<para/>
        /// This is the equivalent of UKismetSystemLibrary::DoesImplementInterface().
        /// This is also the same as obj.GetClass().ImplementsInterface().
        /// </summary>
        /// <param name="type">The IInterface derived type</param>
        /// <returns>True if  this objects class implements the given IInterface derived type</returns>
        public bool DoesImplementInterface(Type type)
        {
            UClass interfaceClass = UClass.GetClass(type);

            if (interfaceClass != null && interfaceClass.ClassFlags.HasFlag(EClassFlags.Interface))
            {
                return(Native_UClass.ImplementsInterface(Native_UObjectBase.GetClass(Address), interfaceClass.Address));
            }
            return(false);
        }
예제 #30
0
        /// <summary>
        /// Get default object of a class.
        /// </summary>
        public static T GetDefault <T>() where T : UObject
        {
            UClass unrealClass = UClass.GetClass <T>();

            if (unrealClass != null)
            {
                return(unrealClass.GetDefaultObject() as T);
            }
            return(null);
        }