Example #1
0
        private static void InitializeUnityVersion()
        {
            string unityVersion = string.Copy(MelonUtils.GetUnityVersion());

            if (string.IsNullOrEmpty(unityVersion))
            {
                return;
            }
            string[] unityVersionSplit = unityVersion.Split('.');
            if ((unityVersionSplit == null) || (unityVersionSplit.Length < 2))
            {
                return;
            }
            int major = int.Parse(unityVersionSplit[0]);
            int minor = int.Parse(unityVersionSplit[1]);
            int patch = 0;

            if (unityVersionSplit.Length > 2)
            {
                string patchString  = unityVersionSplit[2];
                char   firstBadChar = patchString.FirstOrDefault(it => it <'0' || it> '9');
                patch = int.Parse(firstBadChar == 0 ? patchString : patchString.Substring(0, patchString.IndexOf(firstBadChar)));
            }
            UnityVersionHandler.Initialize(major, minor, patch);
        }
Example #2
0
        static Mesh()
        {
            InternalClassPointerStore <Mesh> .NativeClassPtr = UnityInternals.GetClass("UnityEngine.CoreModule.dll", "UnityEngine", "Mesh");
            UnityInternals.runtime_class_init(InternalClassPointerStore <Mesh> .NativeClassPtr);

            m_ctor = UnityInternals.GetMethod(InternalClassPointerStore <Mesh> .NativeClassPtr, ".ctor", "System.Void");

            m_set_triangles     = UnityInternals.GetMethod(InternalClassPointerStore <Mesh> .NativeClassPtr, "set_triangles", "System.Void", "System.Int32[]");
            m_RecalculateBounds = UnityInternals.GetMethod(InternalClassPointerStore <Mesh> .NativeClassPtr, "RecalculateBounds", "System.Void");

            if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2020.1.0" }))
            {
                m_SetArrayForChannelImpl_2020 = UnityInternals.ResolveICall <SetArrayForChannelImpl_2020>("UnityEngine.Mesh::SetArrayForChannelImpl");
                type_SetArrayForChannelImpl   = 2;
            }
            else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2019.3.0" }))
            {
                m_SetArrayForChannelImpl_2019 = UnityInternals.ResolveICall <SetArrayForChannelImpl_2019>("UnityEngine.Mesh::SetArrayForChannelImpl");
                type_SetArrayForChannelImpl   = 1;
            }
            else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2017.1.0" }))
            {
                m_SetArrayForChannelImpl_2017 = UnityInternals.ResolveICall <SetArrayForChannelImpl_2017>("UnityEngine.Mesh::SetArrayForChannelImpl");
                type_SetArrayForChannelImpl   = 0;
            }
        }
Example #3
0
        unsafe static Graphics()
        {
            InternalClassPointerStore <Graphics> .NativeClassPtr = UnityInternals.GetClass("UnityEngine.CoreModule.dll", "UnityEngine", "Graphics");
            fd_Internal_DrawTexture = UnityInternals.ResolveICall <Internal_DrawTextureDelegate>("UnityEngine.Graphics::Internal_DrawTexture");

            if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2018.2.0", "2019.1.0" }))
            {
                fd_Internal_DrawMeshNow1_Injected = UnityInternals.ResolveICall <Internal_DrawMeshNow1_InjectedDelegate>("UnityEngine.Graphics::Internal_DrawMeshNow1_Injected");
            }
            else
            {
                fd_Internal_DrawMeshNow1_Injected = UnityInternals.ResolveICall <Internal_DrawMeshNow1_InjectedDelegate>("UnityEngine.Graphics::INTERNAL_CALL_Internal_DrawMeshNow1");
            }

            if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2019.3.0", "2020.1.0" }))
            {
                m_DrawTexture_Internal_struct = 3;
            }
            else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2018.2.0", "2019.1.0" }))
            {
                m_DrawTexture_Internal_struct = 2;
            }
            else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2017.3.0", "2018.1.0" }))
            {
                m_DrawTexture_Internal_struct = 1;
            }
            else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2017.2.0" }))
            {
                m_DrawTexture_Internal_struct = 0;
            }
        }
Example #4
0
 internal UnityDependencies()
 {
     Version = MelonLaunchOptions.Il2CppAssemblyGenerator.ForceVersion_UnityDependencies;
     if (string.IsNullOrEmpty(Version) || Version.Equals("0.0.0.0"))
     {
         Version = string.Copy(MelonUtils.GetUnityVersion());
     }
     URL         = "https://github.com/LavaGang/Unity-Runtime-Libraries/raw/master/" + Version + ".zip";
     Destination = Path.Combine(Core.BasePath, "UnityDependencies");
 }
Example #5
0
 static GfxDevice()
 {
     if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new[] { "2020.2.7", "2020.3.0", "2021.1.0" }))
     {
         // `FrameTimingManager_CUSTOM_CaptureFrameTimings()` calls `GetRealGfxDevice()` after 4 bytes.
         m_GetRealGfxDevice = (GetRealGfxDeviceDelegate)Marshal.GetDelegateForFunctionPointer(
             CppUtils.ResolveRelativeInstruction(
                 (IntPtr)((long)UnityInternals.ResolveICall("UnityEngine.FrameTimingManager::CaptureFrameTimings") + (MelonUtils.IsGame32Bit() ? 0 : 4))),
             typeof(GetRealGfxDeviceDelegate));
     }
 }
Example #6
0
        static Texture()
        {
            InternalClassPointerStore <Texture> .NativeClassPtr = UnityInternals.GetClass("UnityEngine.CoreModule.dll", "UnityEngine", "Texture");

            if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2018.1.0" }))
            {
                getDataWidth  = UnityInternals.ResolveICall <GetDataWidthDelegate>("UnityEngine.Texture::GetDataWidth");
                getDataHeight = UnityInternals.ResolveICall <GetDataHeightDelegate>("UnityEngine.Texture::GetDataHeight");
            }
            else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2017.1.0" }))
            {
                getDataWidth  = UnityInternals.ResolveICall <GetDataWidthDelegate>("UnityEngine.Texture::Internal_GetWidth");
                getDataHeight = UnityInternals.ResolveICall <GetDataHeightDelegate>("UnityEngine.Texture::Internal_GetHeight");
            }
            set_filterMode_ = UnityInternals.ResolveICall <set_filterModeDelegate>("UnityEngine.Texture::set_filterMode");
        }
Example #7
0
        unsafe static UnityInternals()
        {
            if (MelonUtils.IsGameIl2Cpp())
            {
                domain = il2cpp_domain_get();

                uint    assemblyCount = 0;
                IntPtr *assemblyArray = il2cpp_domain_get_assemblies(domain, ref assemblyCount);
                for (int i = 0; i < assemblyCount; ++i)
                {
                    assemblies.Add(new InternalAssembly(il2cpp_assembly_get_image(*(assemblyArray + i))));
                }
            }
            else
            {
                domain = mono_domain_get();

                string unityVersion = MelonUtils.GetUnityVersion();

                MonoClass *testclass = (MonoClass *)Marshal.AllocHGlobal(sizeof(MonoClass));
                testclass->applyZeroes();
                testclass->nested_in_0x04 = (IntPtr)0x1234;
                testclass->nested_in_0x08 = (IntPtr)0x5678;
                testclass->nested_in_0x0C = (IntPtr)0x9012;
                long returnedName = (long)mono_class_get_name((IntPtr)testclass);
                MelonDebug.Msg($"returnedName {returnedName:X}");
                Marshal.FreeHGlobal((IntPtr)testclass);
                if (returnedName == 0x1234)
                {
                    monoClassOffset = 0;
                }
                else if (returnedName == 0x5678)
                {
                    monoClassOffset = (uint)IntPtr.Size * 1;
                }
                else if (returnedName == 0x9012)
                {
                    monoClassOffset = (uint)IntPtr.Size * 2;
                }
                else
                {
                    throw new Exception("Failed to find MonoClass name offset");
                }

                MelonDebug.Msg("monoClassOffset? " + monoClassOffset);
            }
        }
Example #8
0
        internal static void Init()
        {
            if (disabled)
            {
                return;
            }

            MelonDebug.Msg("Initializing UIStyleValues");
            UIStyleValues.Init();
            MelonDebug.Msg("UIStyleValues Initialized");

            if (UICustomization.VersionText.Enabled)
            {
                TextGenerationSettings settings = new TextGenerationSettings();
                settings.textAnchor        = TextAnchor.MiddleCenter;
                settings.color             = UICustomization.VersionText.TextColor;
                settings.generationExtents = new Vector2(540, 47.5f);
                settings.richText          = true;
                settings.font             = UIStyleValues.TextFont;
                settings.pivot            = new Vector2(0.5f, 0.5f);
                settings.fontSize         = 24;
                settings.fontStyle        = FontStyle.Bold;
                settings.verticalOverflow = VerticalWrapMode.Overflow;
                settings.scaleFactor      = 1f;
                settings.lineSpacing      = 1f;
                MelonDebug.Msg("TextGenerationSettings settings set");

                string melonloaderText = (MelonLaunchOptions.Console.Mode == MelonLaunchOptions.Console.DisplayMode.LEMON)
                    ? "<color=#FFCC4D>LemonLoader</color>"
                    : "<color=#78f764>Melon</color><color=#ff3c6a>Loader</color>";
                melonloaderversionTextmesh = TextMeshGenerator.Generate($"{melonloaderText} v{BuildInfo.Version} Open-Beta", settings);
            }

            if (UICustomization.ProgressBar.Enabled ||
                UICustomization.ProgressText.Enabled)
            {
                progressBar = new ProgressBar(width: 540, height: 36);
            }

            uint graphicsDeviceType = SystemInfo.GetGraphicsDeviceType();

            MelonDebug.Msg("Graphics Device Type: " + graphicsDeviceType);
            shouldCallWFLPAGT = NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new[] { "2020.2.7", "2020.3.0", "2021.1.0" }) &&
                                (graphicsDeviceType == /*DX11*/ 2 || graphicsDeviceType == /*DX12*/ 18)
                ? graphicsDeviceType : 0;
        }
Example #9
0
 unsafe static UIVertexWrapper()
 {
     if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2020.2.0", "2021.1.0" }))
     {
         mode          = 2;
         sizeOfElement = sizeof(UIVertex_2020);
     }
     else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2018.1.0" }))
     {
         mode          = 1;
         sizeOfElement = sizeof(UIVertex_2018);
     }
     else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2017.2.0" }))
     {
         mode          = 0;
         sizeOfElement = sizeof(UIVertex_2017);
     }
 }
Example #10
0
        internal static int LoadAndRun(LemonFunc <int> functionToWaitForAsync)
        {
            // We don't support Unity versions under 2017.2.0 (yet?)
            if (!MelonLaunchOptions.Core.StartScreen || !MelonUtils.GetUnityVersion().StartsWith("20") || MelonUtils.GetUnityVersion().StartsWith("2017.1"))
            {
                return(functionToWaitForAsync());
            }

            if (!Load())
            {
                return(functionToWaitForAsync());
            }

            if (LoadAndRunMethod != null)
            {
                return((int)LoadAndRunMethod.Invoke(null, new object[] { functionToWaitForAsync }));
            }

            return(-1);
        }
Example #11
0
        static Texture2D()
        {
            InternalClassPointerStore <Texture2D> .NativeClassPtr = UnityInternals.GetClass("UnityEngine.CoreModule.dll", "UnityEngine", "Texture2D");
            UnityInternals.runtime_class_init(InternalClassPointerStore <Texture2D> .NativeClassPtr);

            m_ctor = UnityInternals.GetMethod(InternalClassPointerStore <Texture2D> .NativeClassPtr, ".ctor", "System.Void", "System.Int32", "System.Int32");

            m_get_whiteTexture = UnityInternals.GetMethod(InternalClassPointerStore <Texture2D> .NativeClassPtr, "get_whiteTexture", "UnityEngine.Texture2D");

            if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2018.1.0" }))
            {
                type_SetPixelsImpl   = 1;
                m_SetPixelsImpl_2018 = UnityInternals.ResolveICall <SetPixelsImplDelegate_2018>("UnityEngine.Texture2D::SetPixelsImpl");
            }
            else if (NativeSignatureResolver.IsUnityVersionOverOrEqual(MelonUtils.GetUnityVersion(), new string[] { "2017.1.0" }))
            {
                type_SetPixelsImpl   = 0;
                m_SetPixelsImpl_2017 = UnityInternals.ResolveICall <SetPixelsImplDelegate_2017>("UnityEngine.Texture2D::SetPixels");
            }

            m_Apply = UnityInternals.GetMethod(InternalClassPointerStore <Texture2D> .NativeClassPtr, "Apply", "System.Void");
        }
Example #12
0
        internal static bool Apply()
        {
            NativeSignatureFlags currentFlags = default;

            currentFlags |= MelonUtils.IsGame32Bit() ? NativeSignatureFlags.X86 : NativeSignatureFlags.X64;
            currentFlags |= MelonUtils.IsGameIl2Cpp() ? NativeSignatureFlags.Il2Cpp : NativeSignatureFlags.Mono;
            MelonDebug.Msg("Current Unity flags: " + (uint)currentFlags);

            string currentUnityVersion = MelonUtils.GetUnityVersion();
            int    splitIndex          = currentUnityVersion.IndexOf('f');

            if (splitIndex == -1)
            {
                splitIndex = currentUnityVersion.IndexOf('p');
            }
            if (splitIndex > 0)
            {
                currentUnityVersion = currentUnityVersion.Substring(0, splitIndex);
            }
            MelonDebug.Msg("Unity version: " + currentUnityVersion);



            string moduleName = "UnityPlayer.dll";

#if LINUX
            // TODO
#elif OSX
            // TODO
#elif ANDROID
            // TODO
#else
            if (!currentUnityVersion.StartsWith("20") || currentUnityVersion.StartsWith("2017.1"))
            {
                moduleName = "player_win.exe";
            }
#endif


            IntPtr moduleAddress = IntPtr.Zero;
            int    moduleSize    = 0;

            foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
            {
                if (module.ModuleName == moduleName)
                {
                    moduleAddress = module.BaseAddress;
                    moduleSize    = module.ModuleMemorySize;
                    break;
                }
            }

            if (moduleAddress == IntPtr.Zero)
            {
                MelonLogger.Error($"Failed to find module \"{moduleName}\"");
                return(false);
            }

            bool success = true;
            foreach (Type type in typeof(NativeSignatureResolver).Assembly.GetTypes())
            {
                foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    bool hasAttribute           = false;
                    bool signaturefound         = false;
                    bool optionalOnEarlyVersion = false;
                    IOrderedEnumerable <NativeSignatureAttribute> nativeSignatureAttributes = fi.GetCustomAttributes(false)
                                                                                              .Where(attr => attr is NativeSignatureAttribute)
                                                                                              .Select(attr => (NativeSignatureAttribute)attr)
                                                                                              .OrderByDescending(attr => attr.LookupIndex);
                    foreach (NativeSignatureAttribute attribute in nativeSignatureAttributes)
                    {
                        hasAttribute = true;
                        if ((attribute.Flags & currentFlags) != attribute.Flags)
                        {
                            continue;
                        }

                        if (!IsUnityVersionOverOrEqual(currentUnityVersion, attribute.MinimalUnityVersions))
                        {
                            continue;
                        }

                        signaturefound = true;

                        if (attribute.Signature == null)
                        {
                            optionalOnEarlyVersion = true;
                            break;
                        }

                        IntPtr ptr = CppUtils.Sigscan(moduleAddress, moduleSize, attribute.Signature);
                        if (ptr == IntPtr.Zero)
                        {
                            success = false;
                            MelonLogger.Error("Failed to find the signature for field " + fi.Name + " in module. Signature: " + attribute.Signature);
                            break;
                        }

                        if (typeof(Delegate).IsAssignableFrom(fi.FieldType))
                        {
                            fi.SetValue(null, Marshal.GetDelegateForFunctionPointer(ptr, fi.FieldType));
                        }
                        else if (typeof(IntPtr).IsAssignableFrom(fi.FieldType))
                        {
                            fi.SetValue(null, ptr);
                        }
                        else
                        {
                            MelonLogger.Error($"Invalid target type for field \"{fi.FieldType} {fi.Name}\"");
                        }

                        MelonDebug.Msg("Signature for " + fi.Name + ": " + attribute.Signature);
                        break;
                    }

                    if (hasAttribute && !signaturefound && !optionalOnEarlyVersion)
                    {
                        MelonLogger.Error("Failed to find a signature for field " + fi.Name + " for this version of Unity");
                        success = false;
                    }

                    hasAttribute   = false;
                    signaturefound = false;
                    IOrderedEnumerable <NativeFieldValueAttribute> nativeFieldValueAttributes = fi.GetCustomAttributes(false)
                                                                                                .Where(attr => attr is NativeFieldValueAttribute)
                                                                                                .Select(attr => (NativeFieldValueAttribute)attr)
                                                                                                .OrderByDescending(attr => attr.LookupIndex);
                    foreach (NativeFieldValueAttribute attribute in nativeFieldValueAttributes)
                    {
                        hasAttribute = true;
                        if ((attribute.Flags & currentFlags) != attribute.Flags)
                        {
                            continue;
                        }

                        if (!IsUnityVersionOverOrEqual(currentUnityVersion, attribute.MinimalUnityVersions))
                        {
                            continue;
                        }

                        signaturefound = true;

                        fi.SetValue(null, attribute.Value);

                        MelonDebug.Msg("Value for " + fi.Name + ": " + attribute.Value);
                        break;
                    }

                    if (hasAttribute && !signaturefound)
                    {
                        MelonLogger.Error("Failed to find a value for field " + fi.Name + " for this version of Unity");
                        success = false;
                    }
                }
            }

            return(success);
        }
 public static string GetUnityVersion() => MelonUtils.GetUnityVersion();