예제 #1
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);
            }
        }
예제 #2
0
 public override void OnWorldAdded(IntPtr world)
 {
     if (GetDefaultValue != null)
     {
         values[world] = GetDefaultValue(GCHelper.Find(world));
     }
 }
예제 #3
0
        public bool MoveNext()
        {
            if (objectArrayPtr == IntPtr.Zero)
            {
                return(false);
            }

            //checkSlow(IsInAsyncLoadingThread() || int32(InternalExclusionFlags & EInternalObjectFlags::AsyncLoading));

            //@todo UE4 check this for LHS on Index on consoles
            currentObject = null;
            while (++index < Native_FUObjectArray.GetObjectArrayNum(objectArrayPtr))
            {
                UObject obj = GCHelper.Find(Native_FUObjectArray.GetObjectAtIndex(objectArrayPtr, index));
                if (obj != null)
                {
                    if (!obj.HasAnyFlags(exclusionFlags) ||
                        (unrealClass != null && unrealClass != uobjectClass && !obj.IsA(unrealClass)) ||
                        obj.HasAnyInternalFlags(internalExclusionFlags))
                    {
                        continue;
                    }

                    currentObject = obj;
                    return(true);
                }
            }
            return(false);
        }
예제 #4
0
        public WorldStaticVar(GetDefaultValueHandler getDefaultValue, params EWorldType[] worldTypes)
        {
            GetDefaultValue = getDefaultValue;
            foreach (EWorldType worldType in worldTypes)
            {
                worldTypeFlags |= (1 << (int)worldType);
            }

            // Initialize the value for already created worlds
            FWorldContext[] worldContexts = FWorldContext.GetWorldContexts();
            foreach (FWorldContext worldContext in worldContexts)
            {
                if (worldContext.CurrentWorld != IntPtr.Zero)
                {
                    int worldType = (1 << (int)worldContext.WorldType);
                    if ((worldTypeFlags & worldType) == worldType)
                    {
                        UObject world = GCHelper.Find(worldContext.CurrentWorld);
                        if (world != null)
                        {
                            Set(world, GetDefaultValue(world));
                        }
                    }
                }
            }
        }
예제 #5
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));
        }
예제 #6
0
        internal static void OnReload()
        {
            EngineLoop.OnReload();
            GCHelper.OnReload();

            try
            {
                if (ReloadBegin != null)
                {
                    ReloadBegin();
                }
            }
            catch (Exception e)
            {
                FMessage.Log(ELogVerbosity.Error, "HotReload.ReloadBegin failed. Exception: " + Environment.NewLine + e);
            }

            try
            {
                if (ReloadEnd != null)
                {
                    ReloadEnd();
                }
            }
            catch (Exception e)
            {
                FMessage.Log(ELogVerbosity.Error, "HotReload.ReloadEnd failed. Exception: " + Environment.NewLine + e);
            }

            Data        = null;
            IsReloading = false;
        }
예제 #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);
                    }
                }
            }
        }
예제 #8
0
 /// <summary>
 /// Find an existing package by name or create it if it doesn't exist
 /// </summary>
 /// <param name="outer">The Outer object to search inside</param>
 /// <param name="packageName"></param>
 /// <returns>The existing package or a newly created one</returns>
 public static UPackage CreatePackage(ObjectOuter outer, string packageName)
 {
     using (FStringUnsafe packageNameUnsafe = new FStringUnsafe(packageName))
     {
         return(GCHelper.Find <UPackage>(Native_UObjectGlobals.CreatePackage(outer.Address, ref packageNameUnsafe.Array)));
     }
 }
예제 #9
0
 /// <summary>
 /// Finds the common base class that parents the array of classes passed in.
 /// </summary>
 /// <param name="inClasses">the array of classes to find the common base for</param>
 /// <returns>the common base class or NULL</returns>
 public static UClass FindCommonBase(UClass[] inClasses)
 {
     using (TArrayUnsafe <UClass> inClassesUnsafe = new TArrayUnsafe <UClass>())
     {
         inClassesUnsafe.AddRange(inClasses);
         return(GCHelper.Find <UClass>(Native_UClass.FindCommonBaseMany(inClassesUnsafe.Address)));
     }
 }
예제 #10
0
 /// <summary>
 /// Gets the UClass for the given UObject address
 /// </summary>
 /// <param name="objectAddress">The address of the UObject</param>
 /// <returns>The UClass for the given UObject address</returns>
 public static UClass GetClass(IntPtr objectAddress)
 {
     if (objectAddress == IntPtr.Zero)
     {
         return(null);
     }
     return(GCHelper.Find <UClass>(Native_UObjectBase.GetClass(objectAddress)));
 }
예제 #11
0
 /// <summary>
 /// Create a component or subobject only to be used with the editor.
 /// </summary>
 /// <param name="outer">outer to construct the subobject in</param>
 /// <param name="subobjectName">name of the new component</param>
 /// <param name="returnType">type of the new component</param>
 /// <param name="transient">true if the component is being assigned to a transient property</param>
 /// <returns></returns>
 public UObject CreateEditorOnlyDefaultSubobject(UObject outer, FName subobjectName, UClass returnType, bool transient)
 {
     return(GCHelper.Find(Native_FObjectInitializer.CreateEditorOnlyDefaultSubobject(NativeObjectInitializer,
                                                                                     outer == null ? IntPtr.Zero : outer.Address,
                                                                                     ref subobjectName,
                                                                                     returnType == null ? IntPtr.Zero : returnType.Address,
                                                                                     transient)));
 }
예제 #12
0
 /// <summary>
 /// Loads a package and all contained objects that match context flags.
 /// </summary>
 /// <param name="outer">Package to load new package into (usually NULL or ULevel->GetOuter())</param>
 /// <param name="longPackageName">Long package name to load</param>
 /// <param name="loadFlags">Flags controlling loading behavior</param>
 /// <returns>Loaded package if successful, NULL otherwise</returns>
 public static UPackage LoadPackage(UPackage outer, string longPackageName, ELoadFlags loadFlags)
 {
     using (FStringUnsafe longPackageNameUnsafe = new FStringUnsafe(longPackageName))
     {
         return(GCHelper.Find <UPackage>(Native_UObjectGlobals.LoadPackage(
                                             outer == null ? IntPtr.Zero : outer.Address, ref longPackageNameUnsafe.Array, loadFlags)));
     }
 }
예제 #13
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));
                    }
                }
            }
        }
예제 #14
0
 public UObject[] GetObjects()
 {
     UObject[] result = new UObject[objArray.Count];
     for (int i = 0; i < objArray.Count; i++)
     {
         result[i] = GCHelper.Find(objArray[i]);
     }
     return(result);
 }
예제 #15
0
            private void NativeCallback(IntPtr objectBeingModified)
            {
                var evnt = managed.Delegate;

                if (evnt != null)
                {
                    evnt(GCHelper.Find(objectBeingModified));
                }
            }
예제 #16
0
            private void NativeCallback(IntPtr savedObject)
            {
                var evnt = managed.Delegate;

                if (evnt != null)
                {
                    evnt(GCHelper.Find(savedObject));
                }
            }
예제 #17
0
            private void NativeCallback(IntPtr loadedWorld)
            {
                var evnt = managed.Delegate;

                if (evnt != null)
                {
                    evnt(GCHelper.Find(loadedWorld));
                }
            }
예제 #18
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)));
         }
 }
예제 #19
0
            private void ConsoleCommandWithWorldDelegate(IntPtr world)
            {
                var command = Command as FConsoleCommandWithWorldDelegate;

                if (command != null)
                {
                    command(GCHelper.Find(world));
                }
            }
예제 #20
0
        private static void OnActorEndPlay(IntPtr address, byte endPlayReason)
        {
            UObject obj = GCHelper.Find(address);

            IntPtr original = actorEndPlay.GetOriginal(obj);

            Native_VTableHacks.CallOriginal_ActorEndPlay(original, address, endPlayReason);

            obj.EndPlayInternal(endPlayReason);
        }
예제 #21
0
        private static void OnActorComponentBeginPlay(IntPtr address)
        {
            UObject obj = GCHelper.Find(address);

            IntPtr original = actorComponentBeginPlay.GetOriginal(obj);

            Native_VTableHacks.CallOriginal_ActorComponentBeginPlay(original, address);

            obj.BeginPlayInternal();
        }
예제 #22
0
        /// <summary>
        /// Gets the UEnum for the given path (e.g. "/Script/CoreUObject.ESearchCase")
        /// </summary>
        /// <param name="path">The path of the UEnum</param>
        /// <returns>The UEnum for the given path</returns>
        public static UEnum GetEnum(string path)
        {
            IntPtr address = GetEnumAddress(path);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UEnum>(address));
            }
            return(null);
        }
예제 #23
0
        private static void OnSetupPlayerInputComponent(IntPtr address, IntPtr inputComponentAddress)
        {
            UObject obj = GCHelper.Find(address);

            IntPtr original = setupPlayerInput.GetOriginal(obj);

            Native_VTableHacks.CallOriginal_SetupPlayerInputComponent(original, address, inputComponentAddress);

            obj.SetupPlayerInputComponent(inputComponentAddress);
        }
예제 #24
0
        /// <summary>
        /// Gets the UClass (interface) for the given interface type (defined in managed code)
        /// </summary>
        /// <param name="type">The interface type</param>
        /// <returns>The UClass (interface) for the given type</returns>
        public static UClass GetInterface(Type type)
        {
            IntPtr address = GetInterfaceAddress(type);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UClass>(address));
            }
            return(null);
        }
예제 #25
0
        /// <summary>
        /// Loads the UScriptStruct for the given path (e.g. "/Script/CoreUObject.Guid")
        /// </summary>
        /// <param name="path">The path of the UScriptStruct</param>
        /// <returns>The UScriptStruct for the given path</returns>
        public static UScriptStruct LoadStruct(string path)
        {
            IntPtr address = LoadStructAddress(path);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UScriptStruct>(address));
            }
            return(null);
        }
예제 #26
0
        /// <summary>
        /// Gets the UFunction for the given delegate type (defined in managed code)
        /// </summary>
        /// <param name="type">The type of the delegate</param>
        /// <returns>The UFunction for the given type</returns>
        public static UFunction GetDelegateSignature(Type type)
        {
            IntPtr address = GetDelegateSignatureAddress(type);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UFunction>(address));
            }
            return(null);
        }
예제 #27
0
        /// <summary>
        /// Gets the UScriptStruct for the given struct type (defined in managed code)
        /// </summary>
        /// <param name="type">The type of the struct</param>
        /// <returns>The UScriptStruct for the given type</returns>
        public static UScriptStruct GetStruct(Type type)
        {
            IntPtr address = GetStructAddress(type);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UScriptStruct>(address));
            }
            return(null);
        }
예제 #28
0
        /// <summary>
        /// Gets the UEnum for the given enum type (defined in managed code)
        /// </summary>
        /// <param name="type">The type of the enum</param>
        /// <returns>The UEnum for the given type</returns>
        public static UEnum GetEnum(Type type)
        {
            IntPtr address = GetEnumAddress(type);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UEnum>(address));
            }
            return(null);
        }
예제 #29
0
        /// <summary>
        /// Gets the UFunction for the given path (e.g. "/Script/Engine.Actor:SetOwner")
        /// </summary>
        /// <param name="path">The path of the UFunction</param>
        /// <returns>The UFunction for the given path</returns>
        public static UFunction GetFunction(string path)
        {
            IntPtr address = GetFunctionAddress(path);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UFunction>(address));
            }
            return(null);
        }
예제 #30
0
        /// <summary>
        /// Gets the UProperty for the given path (e.g. "/Script/Engine.Actor:bReplicates")
        /// </summary>
        /// <param name="path">The path of the UProperty</param>
        /// <returns>The UProperty for the given path</returns>
        public static UProperty GetProperty(string path)
        {
            IntPtr address = GetPropertyAddress(path);

            if (address != IntPtr.Zero)
            {
                return(GCHelper.Find <UProperty>(address));
            }
            return(null);
        }