コード例 #1
0
ファイル: Extensions.cs プロジェクト: walterhcain/Harmony
 public static bool Is(this CodeInstruction code, OpCode opcode, MemberInfo operand)
 {
     return(code.opcode == opcode && code.OperandIs(operand));
 }
            // Token: 0x0600002A RID: 42 RVA: 0x00002156 File Offset: 0x00000356
            public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
            {
                //Log.Message("FluffyResearchTree.ResearchNode.manual_Draw transpiler start (1 match todo)", false);
                List <CodeInstruction> instructionList     = instructions.ToList <CodeInstruction>();
                MethodInfo             buildingPresentInfo = AccessTools.Method(Patch_FluffyResearchTree_ResearchNode.instanceType, "BuildingPresent", null, null);
                FieldInfo  ResearchInfo             = AccessTools.Field(Patch_FluffyResearchTree_ResearchNode.instanceType, "Research");
                MethodInfo canQueueResearchesInfo   = AccessTools.Method(typeof(Patch_FluffyResearchTree_ResearchNode.manual_Draw), "CanQueueResearches", null, null);
                int        buildingPresentCallCount = instructionList.Count((CodeInstruction i) => i.opcode == OpCodes.Call && i.OperandIs(buildingPresentInfo));
                int        buildingPresentCalls     = 0;
                int        num;

                for (int j = 0; j < instructionList.Count; j = num + 1)
                {
                    CodeInstruction instruction = instructionList[j];
                    bool            flag        = instruction.opcode == OpCodes.Call && instruction.OperandIs(buildingPresentInfo);
                    if (flag)
                    {
                        //Log.Message("FluffyResearchTree.ResearchNode.manual_Draw match 1 of 1", false);
                        num = buildingPresentCalls;
                        buildingPresentCalls = num + 1;
                        bool flag2 = buildingPresentCalls == buildingPresentCallCount;
                        if (flag2)
                        {
                            //Log.Message("FluffyResearchTree.ResearchNode.manual_Draw finalise", false);
                            yield return(instruction);

                            yield return(new CodeInstruction(OpCodes.Ldarg_0, null));

                            yield return(new CodeInstruction(OpCodes.Ldfld, ResearchInfo));

                            instruction = new CodeInstruction(OpCodes.Call, canQueueResearchesInfo);
                        }
                    }
                    yield return(instruction);

                    instruction = null;
                    num         = j;
                }
                yield break;
            }
コード例 #3
0
 public static bool Is(this CodeInstruction i, OpCode opCode, object operand)
 {
     return(i.OpCodeIs(opCode) && i.OperandIs(operand));
 }
コード例 #4
0
            public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
            {
                List <CodeInstruction> codes = instructions.ToList();
                Label l1 = generator.DefineLabel();
                Label l2 = generator.DefineLabel();

                for (int i = 0; i < codes.Count; i++)
                {
                    CodeInstruction code = codes[i];

                    /*
                     * Replace ApparelLayerDef::lastLayer != ApparelLayerDefOf::Shell with IsPreShellLayer(ApparelLayerDef::lastLayer)
                     * by poping the first part and replacin the second part and changing != to brtrue
                     */
                    if (code.opcode == OpCodes.Ldsfld && code.OperandIs(fShell))
                    {
                        yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Harmony_PawnRenderer_DrawBodyApparel), nameof(Harmony_PawnRenderer_DrawBodyApparel.IsVisibleLayer), parameters: new[] { typeof(ApparelLayerDef) })));

                        i++;
                        yield return(new CodeInstruction(OpCodes.Brfalse_S, codes[i].operand));

                        continue;
                    }

                    /*
                     * Add the offset to loc before calling mDrawMeshNowOrLater
                     */
                    if (code.opcode == OpCodes.Call && code.OperandIs(mDrawMeshNowOrLater))
                    {
                        yield return(new CodeInstruction(OpCodes.Ldloca_S, 5)
                        {
                            labels = code.labels
                        });

                        yield return(new CodeInstruction(OpCodes.Dup));

                        yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(Vector3), nameof(Vector3.y))));

                        yield return(new CodeInstruction(OpCodes.Ldarg_0));

                        yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Harmony_PawnRenderer_DrawBodyApparel), nameof(GetPostShellOffset))));

                        yield return(new CodeInstruction(OpCodes.Add));

                        yield return(new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(Vector3), nameof(Vector3.y))));

                        code.labels = new List <Label>();
                    }

                    /*
                     * Find and add a condition to utilityLoc to make backpacks render behind hair
                     */
                    if (code.opcode == OpCodes.Ldarg_2)
                    {
                        /*
                         * Load apparelGraphicRecord from for(int i = 0....) { ApparelGraphicRecord apparelGraphicRecord = apparelGraphics[i];
                         * From the start of the function
                         */
                        yield return(new CodeInstruction(OpCodes.Ldloc_3).MoveLabelsFrom(code));

                        yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ApparelGraphicRecord), nameof(ApparelGraphicRecord.sourceApparel))));

                        yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(Thing), nameof(Thing.def))));

                        yield return(new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(ThingDef), nameof(ThingDef.apparel))));

                        yield return(new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(ApparelProperties), nameof(ApparelProperties.LastLayer)))); // Load current apparel last layer

                        yield return(new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(CE_ApparelLayerDefOf), nameof(CE_ApparelLayerDefOf.Backpack))));       // Load backpack

                        yield return(new CodeInstruction(OpCodes.Bne_Un_S, l1));                                                                                         // Compare value

                        yield return(new CodeInstruction(OpCodes.Ldarg_1));                                                                                              // shellloc

                        yield return(new CodeInstruction(OpCodes.Ldarg_S, 5));                                                                                           // bodyFacing

                        yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Harmony_PawnRenderer_DrawBodyApparel), nameof(GetBackpackOffset))));    // shellloc

                        yield return(new CodeInstruction(OpCodes.Br_S, l2));                                                                                             // continue;

                        code.labels = new List <Label>()
                        {
                            l1
                        };
                        yield return(code);

                        codes[i + 1].labels.Add(l2);
                        continue;
                    }
                    yield return(code);
                }
            }
コード例 #5
0
ファイル: HarmonyUtils.cs プロジェクト: severd8/Valheim
 /// <summary>
 /// Compares code instructions. If compared operands are null returns true (default .Is() method throws exception)
 /// </summary>
 /// <param name="self"></param>
 /// <param name="other"></param>
 /// <returns></returns>
 public static bool Is(this CodeInstruction self, CodeInstruction other)
 {
     return(self.opcode == other.opcode &&
            (self.operand == null && other.operand == null || self.OperandIs(other.operand)));
 }
コード例 #6
0
            // Token: 0x0600000E RID: 14 RVA: 0x000020AA File Offset: 0x000002AA
            public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
            {
                //Log.Message("ArmorUtility.ApplyArmor transpiler start (1 match todo)", false);
                List <CodeInstruction> instructionList        = instructions.ToList <CodeInstruction>();
                MethodInfo             allDefsInfo            = AccessTools.Property(typeof(DefDatabase <FactionDef>), "AllDefs").GetGetMethod();
                MethodInfo             allowedFactionDefsInfo = AccessTools.Method(typeof(Patch_FactionGenerator.GenerateFactionsIntoWorld), "AllowedFactionDefs", null, null);
                int num;

                for (int i = 0; i < instructionList.Count; i = num + 1)
                {
                    CodeInstruction instruction = instructionList[i];
                    bool            flag        = instruction.opcode == OpCodes.Call && instruction.OperandIs(allDefsInfo);
                    if (flag)
                    {
                        //Log.Message("FactionGenerator.GenerateFactionsIntoWorld match 1 of 1", false);
                        yield return(instruction);

                        instruction = new CodeInstruction(OpCodes.Call, allowedFactionDefsInfo);
                    }
                    yield return(instruction);

                    instruction = null;
                    num         = i;
                }
                yield break;
            }