示例#1
0
        /// <summary>
        /// Generates a wrapper function for an individual virtual function table entry
        /// in a virtual function table.
        /// </summary>
        /// <typeparam name="TFunction">Delegate type marked with complete ReloadedFunction Attribute/X64 Reloaded Function Attribute that defines the individual function properties.</typeparam>
        /// <param name="tableEntry">The individual Virtual function table entry to create a wrapper function for.</param>
        /// <returns>Delegate to assign back to ReloadedFunction marked game function.</returns>
        public static TFunction CreateWrapperFunction <TFunction>(this VirtualFunctionTable.TableEntry tableEntry)
        {
            // Create X86/X64 wrapper conditionally.
            if (IntPtr.Size == 4)
            {
                return(FunctionWrapper.CreateWrapperFunction <TFunction>((long)tableEntry.FunctionPointer));
            }
            if (IntPtr.Size == 8)
            {
                return(X64FunctionWrapper.CreateWrapperFunction <TFunction>((long)tableEntry.FunctionPointer));
            }

            // Null case
            return(default(TFunction));
        }
        /// <summary>
        /// Retrieves an instance of the delegate which can be used to call the function behind the function pointer.
        /// </summary>
        /// <returns>False if the pointer to call is invalid, else true.</returns>
        public TDelegate GetDelegate()
        {
            // Return false if pointer points to invalid address.
            if (FunctionAddress == IntPtr.Zero)
            {
                return(null);
            }

            // Get the pointer to the function.
            // Our pointer is dereferenced here, see "Pointer" Property.
            IntPtr functionPointer = FunctionAddress;

            // [Performance] Fast return if the pointer is the same as the last value.
            if (functionPointer == _lastFunctionPointer)
            {
                return(_delegate);
            }

            // Try to get the cached function wrapper.
            if (_methodCache.TryGetValue(functionPointer, out var cachedDelegate))
            {
                return(cachedDelegate);
            }

            // Cached delegate not found.
            else
            {
                // Create wrapper if nonexisting.
                if (IntPtr.Size == 4)
                {
                    _delegate = FunctionWrapper.CreateWrapperFunction <TDelegate>((long)functionPointer);
                }
                else
                {
                    _delegate = X64FunctionWrapper.CreateWrapperFunction <TDelegate>((long)functionPointer);
                }

                // Cache the function wrapper.
                _methodCache[functionPointer] = _delegate;

                // Cache last function pointer.
                _lastFunctionPointer = functionPointer;

                // Return new Delegate
                return(_delegate);
            }
        }