예제 #1
0
        private static IEnumerable <CodeInstruction> PatchRequirementAmountIndicator(
            IEnumerable <CodeInstruction> instructions)
        {
            HarmonyUtils.LogDebugBuildOnly("Transpiler patch: SetupRequirement");

            var searchTemplate = new List <Tuple <int, CodeInstruction> >
            {
                new Tuple <int, CodeInstruction>(0, new CodeInstruction(OpCodes.Call,
                                                                        AccessTools.Method(typeof(InventoryGui), "HideRequirement",
                                                                                           new[] { typeof(Transform) }))),
                new Tuple <int, CodeInstruction>(3, new CodeInstruction(OpCodes.Ldloc_2)),
                new Tuple <int, CodeInstruction>(5, new CodeInstruction(OpCodes.Call,
                                                                        AccessTools.Method(typeof(int), "ToString"))),
                new Tuple <int, CodeInstruction>(6, new CodeInstruction(OpCodes.Callvirt,
                                                                        AccessTools.PropertySetter(typeof(Text), "text")))
            };

            var patchCount       = 0;
            var instructionsList = instructions.ToList();

            for (var i = 0; i < instructionsList.Count; i++)
            {
                if (!instructionsList.DoInstructionsMatchTemplate(i, searchTemplate))
                {
                    continue;
                }
                HarmonyUtils.LogDebugBuildOnly("Template matched!");
                // ok, we sure we are kinda sure we are patching the right thing
                var numOperandReference    = instructionsList[i + 7].operand;
                var amountOperandReference = instructionsList[i + 8].operand;
                instructionsList.RemoveRange(i + 4, 2);
                instructionsList.InsertRange(i + 4, new List <CodeInstruction>
                {
                    new CodeInstruction(OpCodes.Ldstr, "{0}/{1}"),
                    new CodeInstruction(OpCodes.Ldloc_S, numOperandReference),
                    new CodeInstruction(OpCodes.Box, typeof(int)),
                    new CodeInstruction(OpCodes.Ldloc_S, amountOperandReference),
                    new CodeInstruction(OpCodes.Box, typeof(int)),
                    new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(string), "Format",
                                                                         new[] { typeof(string), typeof(object), typeof(object) }))
                });
                HarmonyUtils.LogDebugBuildOnly("Patch OK");
                patchCount = 1;
            }

            HarmonyUtils.LogDebugBuildOnly($"Patch count {patchCount}");
            if (patchCount == 0)
            {
                Plugin.Log.LogError(
                    "Crafting amount indicator won't work properly");
            }
            return(instructionsList);
        }
예제 #2
0
        private static IEnumerable <CodeInstruction> CountItemsHaveItemsReferencesPatch(MethodBase method,
                                                                                        IEnumerable <CodeInstruction> instructions)
        {
            HarmonyUtils.LogDebugBuildOnly($"Transpiler patching {method.DeclaringType.Name}::{method}");
            var instructionsList = instructions.ToList();
            var patchCount       = 0;

            for (var i = instructionsList.Count - 1; i >= 0; i--)
            {
                var ins = instructionsList[i];
                if (ins.opcode != OpCodes.Callvirt)
                {
                    continue;
                }
                var patchPair = methodPatchMap
                                .SingleOrDefault(pair => ins.Is(pair.Item1));
                if (patchPair == null)
                {
                    continue;
                }
                HarmonyUtils.LogDebugBuildOnly("Patching:");
                instructionsList[i] = patchPair.Item2;
                HarmonyUtils.LogDebugBuildOnly("Post patch instruction is:");
                HarmonyUtils.LogDebugBuildOnly($"{i} - {instructionsList[i]}");
                patchCount += 1;
            }

            HarmonyUtils.LogDebugBuildOnly($"Patch count {patchCount}");
            if (patchCount == 0)
            {
                Plugin.Log.LogError(
                    "Counting/deducting patching was not successful. CratingWithContainers will not work properly if at all.\n" +
                    $"Dumping initial instruction list:\n{string.Join("\n", instructionsList.Select((instruction, i) => $" {i} - {instruction}"))}");
            }

            return(instructionsList);
        }