Exemple #1
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();
        }
Exemple #2
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);
        }
Exemple #3
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);
        }
Exemple #4
0
        private static FunctionRedirect AddVTableRedirect(IntPtr unrealClass, string dummyName, Delegate callback)
        {
            using (FStringUnsafe dummyNameUnsafe = new FStringUnsafe(dummyName))
            {
                Native_VTableHacks.Set_VTableCallback(ref dummyNameUnsafe.Array, Marshal.GetFunctionPointerForDelegate(callback));
            }
            FunctionRedirect redirect = new FunctionRedirect(unrealClass, dummyName, callback);

            vtableRedirects.Add(redirect);
            return(redirect);
        }
Exemple #5
0
        private static void OnGetLifetimeReplicatedProps(IntPtr address, IntPtr arrayAddress)
        {
            UObject obj = GCHelper.Find(address);

            IntPtr original = repProps.GetOriginal(obj);

            Native_VTableHacks.CallOriginal_GetLifetimeReplicatedProps(original, address, arrayAddress);

            using (TArrayUnsafeRef <FLifetimeProperty> lifetimePropsUnsafe = new TArrayUnsafeRef <FLifetimeProperty>(arrayAddress))
            {
                FLifetimePropertyCollection lifetimeProps = new FLifetimePropertyCollection(address, lifetimePropsUnsafe);
                obj.GetLifetimeReplicatedProps(lifetimeProps);
            }
        }
Exemple #6
0
        public static unsafe void Unload()
        {
            foreach (FunctionRedirect redirect in vtableRedirects)
            {
                using (FStringUnsafe dummyNameUnsafe = new FStringUnsafe(redirect.DummyName))
                {
                    Native_VTableHacks.Set_VTableCallback(ref dummyNameUnsafe.Array, IntPtr.Zero);
                }
            }

            // Restore the old vtable entry on hotreload. This is important as otherwise we would lose the original function address
            // which is stored in the managed UClass (which gets destroyed on hotreload)
            foreach (IntPtr objAddress in new NativeReflection.NativeObjectIterator(Runtime.Classes.UObject, EObjectFlags.NoFlags))
            {
                foreach (FunctionRedirect redirect in vtableRedirects)
                {
                    if (!Native_UObjectBaseUtility.IsA(objAddress, redirect.Class))
                    {
                        continue;
                    }

                    IntPtr *vtable = *(IntPtr **)objAddress;
                    if (vtable[redirect.VTableIndex] == redirect.NativeCallback)
                    {
                        UObject obj = GCHelper.Find(objAddress);
                        Debug.Assert(obj != null);

                        UClass unrealClass = obj.GetClass();
                        Debug.Assert(unrealClass != null);

                        UClass.VTableOriginalFunc originalFunc;
                        if (unrealClass.VTableOriginalFunctions != null &&
                            unrealClass.VTableOriginalFunctions.TryGetValue(redirect.VTableIndex, out originalFunc))
                        {
                            IntPtr pageAlignedPtr = FMemory.PageAlignPointer((IntPtr)(&vtable[redirect.VTableIndex]));
                            FMemory.PageProtect(pageAlignedPtr, (IntPtr)IntPtr.Size, true, true);
                            *(&vtable[redirect.VTableIndex]) = originalFunc.FuncAddress;
                        }
                    }
                }
            }
        }