public static IEnumerable <CodeInstruction> _OnUpdate_Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            try {
                int         pos1, pos2;
                CodeMatcher matcher = new CodeMatcher(instructions);

                matcher.MatchForward(false, new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(DysonNode), "color")));
                pos1 = matcher.Pos;
                matcher.MatchBack(false, new CodeMatch(OpCodes.Ldloc_S));
                pos2 = matcher.Pos;
                matcher.Advance(pos1 - pos2 + 1)
                .Insert(
                    new CodeInstruction(matcher.InstructionAt(pos2 - pos1 - 1)),
                    new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(UIDysonBrush_Paint_Transpiler), "SendNodePacket"))
                    );

                matcher.MatchForward(false, new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(DysonFrame), "color")));
                pos1 = matcher.Pos;
                matcher.MatchBack(false, new CodeMatch(OpCodes.Ldloc_S));
                pos2 = matcher.Pos;
                matcher.Advance(pos1 - pos2 + 1)
                .Insert(
                    new CodeInstruction(matcher.InstructionAt(pos2 - pos1 - 1)),
                    new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(UIDysonBrush_Paint_Transpiler), "SendFramePacket"))
                    );

                matcher.MatchForward(false, new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(DysonShell), "color")));
                pos1 = matcher.Pos;
                matcher.MatchBack(false, new CodeMatch(OpCodes.Ldloc_S));
                pos2 = matcher.Pos;
                matcher.Advance(pos1 - pos2 + 1)
                .Insert(
                    new CodeInstruction(matcher.InstructionAt(pos2 - pos1 - 1)),
                    new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(UIDysonBrush_Paint_Transpiler), "SendShellPacket"))
                    );

                return(matcher.InstructionEnumeration());
            }
            catch
            {
                NebulaModel.Logger.Log.Error("UIDysonBrush_Paint._OnUpdate_Transpiler failed. Mod version not compatible with game version.");
                return(instructions);
            }
        }
Exemple #2
0
        private static IEnumerable <CodeInstruction> CreatePrebuilds_Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator il)
        {
            /*
             * Inserts
             *  if(!Multiplayer.IsActive)
             * Before trying to take items, so that all prebuilds are assumed to require items while in MP
             */
            CodeMatcher matcher = new CodeMatcher(instructions, il)
                                  .MatchForward(true,
                                                new CodeMatch(i => i.IsLdloc()), // count
                                                new CodeMatch(OpCodes.Ldc_I4_1),
                                                new CodeMatch(OpCodes.Ceq),
                                                new CodeMatch(OpCodes.Brfalse)
                                                );

            if (matcher.IsInvalid)
            {
                NebulaModel.Logger.Log.Error("BuildTool_BlueprintPaste.CreatePrebuilds_Transpiler failed. Mod version not compatible with game version.");
                return(instructions);
            }

            object jumpOperand = matcher.Instruction.operand;

            matcher = matcher
                      .MatchBack(false,
                                 new CodeMatch(i => i.IsLdloc()),
                                 new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "item"),
                                 new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "ID"),
                                 new CodeMatch(i => i.IsStloc())
                                 );

            if (matcher.IsInvalid)
            {
                NebulaModel.Logger.Log.Error("BuildTool_BlueprintPaste.CreatePrebuilds_Transpiler 2 failed. Mod version not compatible with game version.");
                return(instructions);
            }

            return(matcher
                   .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate <Func <bool> >(() =>
            {
                return Multiplayer.IsActive;
            }))
                   .InsertAndAdvance(new CodeInstruction(OpCodes.Brtrue, jumpOperand))
                   .InstructionEnumeration());
        }
Exemple #3
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            CodeMatcher codeMatcher = new CodeMatcher(instructions);
            object      label;

            // CodeMatcher needs some better label manipulating methods
            // replace rotation stuff
            codeMatcher
            .MatchForward(
                false,
                new CodeMatch(OpCodes.Callvirt, _localRotationSetter))
            .Advance(1);
            int endPos = codeMatcher.Pos;

            label = codeMatcher.Labels.First();
            codeMatcher
            .MatchBack(
                false,
                new CodeMatch(null, label))
            .Advance(1)
            .RemoveInstructions(endPos - codeMatcher.Pos)
            .InsertAndAdvance(
                new CodeInstruction(OpCodes.Ldloc_1),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, _startRotationField),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, _middleRotationField),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, _endRotationField),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, _playerTransformsField),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, _rotatedObjectField),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Call, _getTransform),
                new CodeInstruction(OpCodes.Ldarg_0),
                new CodeInstruction(OpCodes.Ldfld, _inverseWorldRotationField),
                new CodeInstruction(OpCodes.Call, _doNoteLook))

            // Add addition check to our quirky little variable to skip end position offset when we are using definitePosition
            .MatchForward(
                true,
                new CodeMatch(OpCodes.Ldfld, _threeQuartersMarkReportedField),
                new CodeMatch(OpCodes.Brfalse));
            label = codeMatcher.Operand;
            codeMatcher
            .Advance(1)
            .Insert(
                new CodeInstruction(OpCodes.Ldsfld, _definitePositionField),
                new CodeInstruction(OpCodes.Brtrue_S, label))
            .Start();

            return(codeMatcher

                   // time adjust
                   .MatchForward(false, new CodeMatch(OpCodes.Stloc_0))
                   .InsertAndAdvance(
                       new CodeInstruction(OpCodes.Ldarg_0),
                       new CodeInstruction(OpCodes.Ldfld, _jumpDurationField),
                       new CodeInstruction(OpCodes.Call, _noteJumpTimeAdjust))

                   // final position
                   .MatchForward(false, new CodeMatch(OpCodes.Stind_R4))
                   .Advance(2)
                   .InsertAndAdvance(
                       new CodeInstruction(OpCodes.Ldarg_0),
                       new CodeInstruction(OpCodes.Ldarg_0),
                       new CodeInstruction(OpCodes.Ldfld, _localPositionField),
                       new CodeInstruction(OpCodes.Ldloc_1),
                       new CodeInstruction(OpCodes.Call, _definiteNoteJump),
                       new CodeInstruction(OpCodes.Stfld, _localPositionField))

                   .InstructionEnumeration());
        }