Beispiel #1
0
        /// <summary>
        /// Retrieves the current game version from the Klei code.
        /// </summary>
        /// <returns>The change list version of the game, or 0 if it cannot be determined.</returns>
        private static uint GetGameVersion()
        {
            /*
             * KleiVersion.ChangeList is a const which is substituted at compile time; if
             * accessed directly, PLib would have a version "baked in" and would never
             * update depending on the game version in use.
             */
            var field = PPatchTools.GetFieldSafe(typeof(KleiVersion), nameof(KleiVersion.
                                                                             ChangeList), true);
            uint ver = 0U;

            if (field != null && field.GetValue(null) is uint newVer)
            {
                ver = newVer;
            }
            return(ver);
        }
Beispiel #2
0
        /// <summary>
        /// Checks to see if the conditions for a method running are met.
        /// </summary>
        /// <param name="assemblyName">The assembly name that must be present, or null if none is required.</param>
        /// <param name="typeName">The type full name that must be present, or null if none is required.</param>
        /// <param name="requiredType">The type that was required, if typeName was not null or empty.</param>
        /// <returns>true if the requirements are met, or false otherwise.</returns>
        internal static bool CheckConditions(string assemblyName, string typeName,
                                             out Type requiredType)
        {
            bool ok = false, emptyType = string.IsNullOrEmpty(typeName);

            if (string.IsNullOrEmpty(assemblyName))
            {
                if (emptyType)
                {
                    requiredType = null;
                    ok           = true;
                }
                else
                {
                    requiredType = PPatchTools.GetTypeSafe(typeName);
                    ok           = requiredType != null;
                }
            }
            else if (emptyType)
            {
                requiredType = null;
                // Search for assembly only, by name
                foreach (var candidate in AppDomain.CurrentDomain.GetAssemblies())
                {
                    if (candidate.GetName().Name == assemblyName)
                    {
                        ok = true;
                        break;
                    }
                }
            }
            else
            {
                requiredType = PPatchTools.GetTypeSafe(typeName, assemblyName);
                ok           = requiredType != null;
            }
            return(ok);
        }
Beispiel #3
0
        /// <summary>
        /// Applies all patches.
        /// </summary>
        /// <param name="instance">The Harmony instance to use when patching.</param>
        private static void PatchAll(HarmonyInstance instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            // ColonyAchievementStatus
            instance.Patch(typeof(ColonyAchievementStatus), "Serialize",
                           PatchMethod(nameof(Serialize_Prefix)), null);

            // Db
            instance.Patch(typeof(Db), "Initialize", PatchMethod(nameof(Initialize_Prefix)),
                           PatchMethod(nameof(Initialize_Postfix)));

            // Game
            instance.Patch(typeof(Game), "DestroyInstances", null, PatchMethod(nameof(
                                                                                   Game_DestroyInstances_Postfix)));
            instance.Patch(typeof(Game), "OnPrefabInit", null, PatchMethod(nameof(
                                                                               Game_OnPrefabInit_Postfix)));

            // GameInputMapping
            instance.Patch(typeof(GameInputMapping), "SetDefaultKeyBindings", null,
                           PatchMethod(nameof(SetDefaultKeyBindings_Postfix)));

            // GameUtil
            instance.Patch(typeof(GameUtil), "GetKeycodeLocalized",
                           PatchMethod(nameof(GetKeycodeLocalized_Prefix)), null);

            // KInputController
            instance.PatchConstructor(typeof(KInputController.KeyDef), new Type[] {
                typeof(KKeyCode), typeof(Modifier)
            }, null, PatchMethod(nameof(CKeyDef_Postfix)));
            instance.Patch(typeof(KInputController), "IsActive",
                           PatchMethod(nameof(IsActive_Prefix)), null);
            instance.Patch(typeof(KInputController), "QueueButtonEvent",
                           PatchMethod(nameof(QueueButtonEvent_Prefix)), null);

            if (PLightManager.InitInstance())
            {
                // DiscreteShadowCaster
                instance.Patch(typeof(DiscreteShadowCaster), "GetVisibleCells",
                               PatchMethod(nameof(GetVisibleCells_Prefix)), null);

                // Light2D
                instance.Patch(typeof(Light2D), "AddToScenePartitioner",
                               PatchMethod(nameof(AddToScenePartitioner_Prefix)), null);
                instance.Patch(typeof(Light2D), "RefreshShapeAndPosition", null,
                               PatchMethod(nameof(RefreshShapeAndPosition_Postfix)));

                // LightGridEmitter
                instance.Patch(typeof(LightGridEmitter), "AddToGrid", null,
                               PatchMethod(nameof(AddToGrid_Postfix)));
                instance.Patch(typeof(LightGridEmitter), "ComputeLux",
                               PatchMethod(nameof(ComputeLux_Prefix)), null);
                instance.Patch(typeof(LightGridEmitter), "RemoveFromGrid",
                               null, PatchMethod(nameof(RemoveFromGrid_Postfix)));
                instance.Patch(typeof(LightGridEmitter), "UpdateLitCells",
                               PatchMethod(nameof(UpdateLitCells_Prefix)), null);

                // LightGridManager
                instance.Patch(typeof(LightGridManager), "CreatePreview",
                               PatchMethod(nameof(CreatePreview_Prefix)), null);

                // LightShapePreview
                instance.Patch(typeof(LightShapePreview), "Update",
                               PatchMethod(nameof(LightShapePreview_Update_Prefix)), null);

                // Rotatable
                instance.Patch(typeof(Rotatable), "OrientVisualizer", null,
                               PatchMethod(nameof(OrientVisualizer_Postfix)));
            }

            // MainMenu
            instance.Patch(typeof(MainMenu), "OnSpawn", null, PatchMethod(
                               nameof(MainMenu_OnSpawn_Postfix)));

            // PBuilding
            instance.Patch(typeof(BuildingTemplates), "CreateBuildingDef", null,
                           PatchMethod(nameof(CreateBuildingDef_Postfix)));
            instance.Patch(typeof(EquipmentTemplates), "CreateEquipmentDef", null,
                           PatchMethod(nameof(CreateEquipmentDef_Postfix)));
            if (PBuilding.CheckBuildings())
            {
                instance.Patch(typeof(GeneratedBuildings), "LoadGeneratedBuildings",
                               PatchMethod(nameof(LoadGeneratedBuildings_Prefix)), null);
            }

            // PCodex
            instance.Patch(typeof(CodexCache), "CollectEntries", null,
                           PatchMethod(nameof(CollectEntries_Postfix)));
            instance.Patch(typeof(CodexCache), "CollectSubEntries", null,
                           PatchMethod(nameof(CollectSubEntries_Postfix)));

            // PLocalization
            var locale = Localization.GetLocale();

            if (locale != null)
            {
                PLocalization.LocalizeAll(locale);
            }

            // ModsScreen
            POptions.Init();
            instance.Patch(typeof(ModsScreen), "BuildDisplay", null,
                           PatchMethod(nameof(BuildDisplay_Postfix)));

            // SteamUGCService
            var ugc = PPatchTools.GetTypeSafe("SteamUGCService", "Assembly-CSharp");

            if (ugc != null)
            {
                try {
                    instance.PatchTranspile(ugc, "LoadPreviewImage", PatchMethod(nameof(
                                                                                     LoadPreviewImage_Transpile)));
                } catch (Exception e) {
                    PUtil.LogExcWarn(e);
                }
            }

            // TMPro.TMP_InputField
            try {
                instance.Patch(typeof(TMPro.TMP_InputField), "OnEnable", null,
                               PatchMethod(nameof(OnEnable_Postfix)));
            } catch (Exception) {
                PUtil.LogWarning("Unable to patch TextMeshPro bug, text fields may display " +
                                 "improperly inside scroll areas");
            }

            // Postload, legacy and normal
            PPatchManager.ExecuteLegacyPostload();
            PPatchManager.RunAll(RunAt.AfterModsLoad);
        }
Beispiel #4
0
 /// <summary>
 /// Applied to modify SteamUGCService to silence "Preview image load failed".
 /// </summary>
 private static IEnumerable <CodeInstruction> LoadPreviewImage_Transpile(
     IEnumerable <CodeInstruction> body)
 {
     return(PPatchTools.ReplaceMethodCall(body, typeof(Debug).GetMethodSafe(nameof(
                                                                                Debug.LogFormat), true, typeof(string), typeof(object[]))));
 }