public static CIEnumerable _codeForCfgVar <T, C>(T val, string cfgVarName, ILGenerator ilg) where C : Component
        {
            $"HarmonyHelper._codeForCfgVar: injecting {val} => {cfgVarName} ({typeof(C)})".logDbg();
            var cfgVarCI = getCfgVarCI(cfgVarName);

            Debug.assert(cfgVarCI != null, $"_codeForCfgVar: member for {cfgVarName} is not found");

            if (cfgVarCI == null)
            {
                yield break;
            }

            Label lb1 = ilg.DefineLabel();
            Label lb2 = ilg.DefineLabel();

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

            yield return(new CodeInstruction(OpCodes.Callvirt, typeof(Component).method("GetComponent", new Type[0]).MakeGenericMethod(typeof(C))));

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

            yield return(new CodeInstruction(OpCodes.Call, typeof(UnityEngine.Object).method("op_Inequality")));

            yield return(new CodeInstruction(OpCodes.Brtrue_S, lb1));

            yield return(new CodeInstruction(LdcOpCode.get <T>(), val));

            yield return(new CodeInstruction(OpCodes.Br_S, lb2));

            yield return(new CodeInstruction(OpCodes.Call, mainConfig)
            {
                labels = new List <Label> {
                    lb1
                }
            });

            yield return(cfgVarCI);

            yield return(new CodeInstruction(OpCodes.Nop)
            {
                labels = new List <Label> {
                    lb2
                }
            });
        }
Example #2
0
        public static CIEnumerable _codeForCfgVar <T, C>(T val, string cfgVarName, ILGenerator ilg) where C : Component
        {
            $"HarmonyHelper._codeForCfgVar: injecting {val} => {cfgVarName} ({typeof(C)})".logDbg();
            if (getCfgVarCI(cfgVarName) is not CodeInstruction cfgVarCI)
            {
                yield break;
            }

            Label lb1 = ilg.DefineLabel();
            Label lb2 = ilg.DefineLabel();

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

            yield return(new CodeInstruction(OpCodes.Callvirt, typeof(Component).method <C>("GetComponent", new Type[0])));

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

            yield return(new CodeInstruction(OpCodes.Call, typeof(UnityEngine.Object).method("op_Inequality")));

            yield return(new CodeInstruction(OpCodes.Brtrue_S, lb1));

            yield return(new CodeInstruction(LdcOpCode.get <T>(), val));

            yield return(new CodeInstruction(OpCodes.Br_S, lb2));

            yield return(new CodeInstruction(OpCodes.Call, mainConfig)
            {
                labels = { lb1 }
            });

            yield return(cfgVarCI);

            yield return(new CodeInstruction(OpCodes.Nop)
            {
                labels = { lb2 }
            });
        }
 public static bool isLDC <T>(this CodeInstruction ci, T val) => ci.isOp(LdcOpCode.get <T>(), val);