Beispiel #1
0
        public static void TryRegister()
        {
            if (!Instance.IsActive)
            {
                return;
            }

            try
            {
                if (!Instance.GetField <bool>("enabled"))
                {
                    return;
                }

                var registerSyncMethod = AccessTools.FirstMethod(Instance.Integrator, method => method.Name == "RegisterSyncMethod" && method.GetParameters()[0].ParameterType == typeof(Type));
                registerSyncMethod.Invoke(Instance.MainAssembly, new object[] { typeof(Mod_Multiplayer), nameof(SetSelfTend), null });
                registerSyncMethod.Invoke(Instance.MainAssembly, new object[] { typeof(Mod_Multiplayer), nameof(SetFoodRestriction), null });
                registerSyncMethod.Invoke(Instance.MainAssembly, new object[] { typeof(Mod_Multiplayer), nameof(SetAssignment), null });
                registerSyncMethod.Invoke(Instance.MainAssembly, new object[] { typeof(Mod_Multiplayer), nameof(SetArea), null });
                registerSyncMethod.Invoke(Instance.MainAssembly, new object[] { typeof(Mod_Multiplayer), nameof(SetOutfit), null });

                Mod.Log("Multiplayer ready with API " + Instance.GetField <string>("API"));
            }
            catch (Exception exception) { Instance.FailInitialization(exception); }
        }
Beispiel #2
0
            public static MethodBase TargetMethod()
            {
                var type = AccessTools.FirstInner(typeof(PotionDropControl), t => t.Name.Contains("<RefinePotion>d__21"));

                LogF($"TargetMethod {type}");
                return(AccessTools.FirstMethod(type, method => method.Name.Contains("MoveNext")));
            }
Beispiel #3
0
        private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            foreach (CodeInstruction instruction in instructions)
            {
                if (instruction.opcode == OpCodes.Call)
                {
                    if (instruction.operand != null &&
                        instruction.operand is MethodBase methodBase &&
                        methodBase.Name != nameof(RoundSummary._ProcessServerSideCode))
                    {
                        yield return(instruction);
                    }
                    else
                    {
                        yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(RoundEnd), nameof(Process))));

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

                        yield return(new CodeInstruction(OpCodes.Call, AccessTools.FirstMethod(typeof(MECExtensionMethods2), (m) =>
                        {
                            var generics = m.GetGenericArguments();
                            var paramseters = m.GetParameters();
                            return m.Name == "CancelWith" &&
                            generics.Length == 1 &&
                            paramseters.Length == 2 &&
                            paramseters[0].ParameterType == typeof(IEnumerator <float>) &&
                            paramseters[1].ParameterType == generics[0];
                        }).MakeGenericMethod(typeof(RoundSummary))));
                    }
                }
        static Garam_RaceAddon()
        {
            var harmony = new Harmony("com.rimworld.Dalrae.Garam_RaceAddon");

            harmony.PatchAll();
            harmony.Patch(AccessTools.FirstMethod(AccessTools.FirstInner(typeof(CharacterCardUtility), x => x.Name.Contains("14_1")), x => x.Name.Contains("b__23")), null, null, new HarmonyMethod(typeof(HarmonyPathces_DrawCharacterCard), "Transpiler"));

            //==================== Recipe Import ====================//
            foreach (var thingDef in DefDatabase <RaceAddonThingDef> .AllDefs)
            {
                if (thingDef.raceAddonSettings.basicSetting.humanRecipeImport)
                {
                    ThingDef human = DefDatabase <ThingDef> .AllDefs.First((ThingDef def) => def.defName == "Human");

                    foreach (RecipeDef recipe in human.AllRecipes)
                    {
                        if (!recipe.targetsBodyPart ||
                            recipe.appliedOnFixedBodyParts.NullOrEmpty() ||
                            recipe.appliedOnFixedBodyParts.Any((BodyPartDef def) => thingDef.race.body.AllParts.Any((BodyPartRecord bpr) => bpr.def == def)))
                        {
                            if (!thingDef.recipes.Contains(recipe))
                            {
                                thingDef.recipes.Add(recipe);
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
0
        static Mod()
        {
            Harmony harmony = new Harmony("com.rimworld.Dalrae.Garam_RaceAddon");

            harmony.PatchAll();
            harmony.Patch(AccessTools.FirstMethod(AccessTools.FirstInner(typeof(CharacterCardUtility), x => x.Name.Contains("14_1")), x => x.Name.Contains("b__21")), null, null, new HarmonyMethod(typeof(DrawCharacterCard), "Transpiler"));
            foreach (var type in typeof(WorkGiver).AllSubclasses())
            {
                if (AccessTools.DeclaredMethod(type, "ShouldSkip") is var methodInfo && methodInfo != null)
                {
                    harmony.Patch(methodInfo, null, new HarmonyMethod(typeof(ShouldSkip), "Postfix"), null, null);
                }
            }
            foreach (var thingDef in DefDatabase <RaceAddonThingDef> .AllDefsListForReading)
            {
                if (thingDef.raceAddonSettings.basicSetting.recipeImportTarget != null)
                {
                    // Recipe Import
                    ThingDef targetThingDef = DefDatabase <ThingDef> .AllDefs.First((ThingDef def) => def == thingDef.raceAddonSettings.basicSetting.recipeImportTarget);

                    thingDef.recipes = thingDef.recipes ?? new List <RecipeDef>();
                    foreach (RecipeDef recipe in targetThingDef.AllRecipes)
                    {
                        if (RecipeImport(recipe, thingDef.race.body))
                        {
                            thingDef.recipes.AddDistinct(recipe);
                        }
                    }
                }
            }

            foreach (var customPawnKindDef in DefDatabase <CustomPawnKindDef> .AllDefsListForReading)
            {
                foreach (var setting in customPawnKindDef.pawnKindDefReplaceSettings)
                {
                    if (!RaceAddon.PawnKindDefReplaceSettings.ContainsKey(setting.originalPawnKindDef))
                    {
                        RaceAddon.PawnKindDefReplaceSettings.Add(setting.originalPawnKindDef, new List <Pair <PawnKindDef, float> >());
                    }
                    if (RaceAddon.PawnKindDefReplaceSettings[setting.originalPawnKindDef].Count > 0)
                    {
                        for (int i = 0; i < RaceAddon.PawnKindDefReplaceSettings[setting.originalPawnKindDef].Count; i++)
                        {
                            if (setting.originalWeight < RaceAddon.PawnKindDefReplaceSettings[setting.originalPawnKindDef][i].Second)
                            {
                                RaceAddon.PawnKindDefReplaceSettings[setting.originalPawnKindDef][i] = new Pair <PawnKindDef, float>(setting.originalPawnKindDef, setting.originalWeight);
                            }
                        }
                    }
                    else
                    {
                        RaceAddon.PawnKindDefReplaceSettings[setting.originalPawnKindDef].Add(new Pair <PawnKindDef, float>(setting.originalPawnKindDef, setting.originalWeight));
                    }
                    RaceAddon.PawnKindDefReplaceSettings[setting.originalPawnKindDef].Add(new Pair <PawnKindDef, float>(setting.replacedPawnKindDef, setting.replacedWeight));
                }
            }
        }
Beispiel #6
0
            // here, inside the patch class, you can place the auxilary patch methods
            // for example TargetMethod:

            public MethodBase TargetMethod()
            {
                // use normal reflection or helper methods in <AccessTools> to find the method/constructor
                // you want to patch and return its MethodInfo/ConstructorInfo
                //
                var type = AccessTools.FirstInner(typeof(TheClass), t => t.Name.Contains("Stuff"));

                return(AccessTools.FirstMethod(type, method => method.Name.Contains("SomeMethod")));
            }
Beispiel #7
0
        internal static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instrs, ILGenerator il)
        {
            MethodInfo LPayAttention = AccessTools.Method(typeof(JobDriver_PayAttention), nameof(JobDriver_PayAttention.ForcePayAttention));
            FieldInfo  Ltoil         = AccessTools.Field(dc19_0, "toil");
            MethodInfo Lget_CurJob   = AccessTools.Method(typeof(Pawn), "get_CurJob");
            FieldInfo  LtameeInd     = AccessTools.Field(dc19_0, "tameeInd");
            MethodInfo LGetActor     = AccessTools.Method(typeof(Toil), nameof(Toil.GetActor));
            MethodInfo LGetTarget    = AccessTools.Method(typeof(Job), nameof(Job.GetTarget));
            MethodInfo Lop_Explicit  = AccessTools.FirstMethod(typeof(LocalTargetInfo), m => m.Name == "op_Explicit" && m.ReturnType == typeof(Thing));

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

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

            yield return(new CodeInstruction(OpCodes.Callvirt, LGetActor));

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

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

            yield return(new CodeInstruction(OpCodes.Callvirt, Lget_CurJob));

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

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

            yield return(new CodeInstruction(OpCodes.Callvirt, LGetTarget));

            yield return(new CodeInstruction(OpCodes.Call, Lop_Explicit));

            yield return(new CodeInstruction(OpCodes.Castclass, typeof(Pawn)));

            yield return(new CodeInstruction(OpCodes.Ldc_I4, 270));

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

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

            yield return(new CodeInstruction(OpCodes.Call, LPayAttention));

            foreach (var i in instrs)
            {
                yield return(i);
            }
        }
Beispiel #8
0
        public static IEnumerable <CodeInstruction> draw_Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator)
        {
            LinkedList <CodeInstruction> newInstructions = new LinkedList <CodeInstruction>(instructions);
            CodeInstruction codeInstruction = newInstructions.FirstOrDefault(c => c.opcode == OpCodes.Call && c.operand?.ToString() == "Microsoft.Xna.Framework.Vector2 getScale()");
            LinkedListNode <CodeInstruction> linkedListNode = newInstructions.Find(codeInstruction);

            if (linkedListNode != null && codeInstruction != null)
            {
                linkedListNode.Value = new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ObjectOverrides), "getScale", new Type[] { typeof(Object) }));
            }

            codeInstruction = newInstructions.FirstOrDefault(c => c.opcode == OpCodes.Callvirt && c.operand?.ToString() == "Void Draw(Microsoft.Xna.Framework.Graphics.Texture2D, Microsoft.Xna.Framework.Rectangle, System.Nullable`1[Microsoft.Xna.Framework.Rectangle], Microsoft.Xna.Framework.Color, Single, Microsoft.Xna.Framework.Vector2, Microsoft.Xna.Framework.Graphics.SpriteEffects, Single)");
            linkedListNode  = newInstructions.Find(codeInstruction);
            if (linkedListNode != null && codeInstruction != null)
            {
                newInstructions.AddBefore(linkedListNode, new CodeInstruction(OpCodes.Ldarg_0, null));
                linkedListNode.Value = new CodeInstruction(OpCodes.Call, AccessTools.FirstMethod(typeof(ObjectOverrides), m => m.Name == "DrawAnimation"));
            }

            return(newInstructions);
        }
Beispiel #9
0
 public static MethodInfo TargetMethod() =>
 // "IsEdificeOverNonEdifice" Isn't compiled away? Okay I'll use that
 AccessTools.FirstMethod(typeof(GenConstruct), method => method.Name.Contains("IsEdificeOverNonEdifice"));
            public static MethodInfo TargetMethod()
            {
                var type = AccessTools.FirstInner(typeof(DebugToolsSpawning), t => t.Name.Contains("DisplayClass1_0"));

                return(AccessTools.FirstMethod(type, method => method.Name.Contains("SpawnPawn")));
            }
Beispiel #11
0
        public void InitializeSingletons(Type wrapperType, ManualLogSource logger)
        {
            var fieldsSeen       = new HashSet <FieldInfo>();
            var propertiesSeen   = new HashSet <PropertyInfo>();
            var methodsSeen      = new HashSet <MethodInfo>();
            var constructorsSeen = new HashSet <ConstructorInfo>();

            var staticFieldRefAccessMethod = AccessTools.FirstMethod(typeof(AccessTools), f => f.Name == nameof(AccessTools.StaticFieldRefAccess) && f.GetParameters().Length == 1 && f.GetParameters().Single().ParameterType == typeof(FieldInfo) && f.ContainsGenericParameters && f.GetGenericArguments().Length == 1);
            var fieldRefAccessMethod       = AccessTools.Method(typeof(AccessTools), nameof(AccessTools.FieldRefAccess), new Type[] { typeof(FieldInfo) });

            foreach (var field in wrapperType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (field.FieldType.IsGenericType && (typeof(AccessTools.FieldRef <object, object>).GetGenericTypeDefinition() == field.FieldType.GetGenericTypeDefinition() || typeof(AccessTools.FieldRef <object>).GetGenericTypeDefinition() == field.FieldType.GetGenericTypeDefinition()) && field.GetValue(null) == null)
                {
                    var wrapperMember = field.GetCustomAttribute <WrapperField>();
                    if (wrapperMember != null)
                    {
                        var fieldInfo = WrappedType.GetField(wrapperMember.ObfuscatedName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        if (fieldInfo != null)
                        {
                            if (field.FieldType.GenericTypeArguments.Length == 1)
                            {
                                //TODO: Figure out how to do statics.
                                field.SetValue(null, staticFieldRefAccessMethod.MakeGenericMethod(field.FieldType.GenericTypeArguments).Invoke(null, new object[] { fieldInfo }));
                            }
                            else if (field.FieldType.GenericTypeArguments.Length == 2)
                            {
                                field.SetValue(null, fieldRefAccessMethod.MakeGenericMethod(field.FieldType.GenericTypeArguments).Invoke(null, new object[] { fieldInfo }));
                            }
                            else
                            {
                                logger.LogError($"Field {wrapperType.Name}.{field.Name} has an incorrect number of generic arguments! Panic!");
                                Environment.Exit(1);
                            }
                            fieldsSeen.Add(fieldInfo);
                            logger.LogDebug($"Loaded field {wrapperType.Name}.{field.Name}");
                        }
                    }
                }
                else if (field.FieldType == typeof(FieldInfo) && field.GetValue(null) == null)
                {
                    var wrapperMember = field.GetCustomAttribute <WrapperField>();
                    if (wrapperMember != null)
                    {
                        var fieldInfo = WrappedType.GetField(wrapperMember.ObfuscatedName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        if (fieldInfo != null)
                        {
                            field.SetValue(null, fieldInfo);
                            fieldsSeen.Add(fieldInfo);
                            logger.LogDebug($"Loaded field {wrapperType.Name}.{field.Name}");
#if DEBUG
                            if (!fieldInfo.IsStatic)
                            {
                                logger.LogWarning($"This is a FieldInfo field, please replace it with a FieldRefAccess version!");
                            }
#endif
                        }
                    }
                }
                else if (field.FieldType == typeof(PropertyInfo) && field.GetValue(null) == null)
                {
                    var wrapperProperty = field.GetCustomAttribute <WrapperProperty>();
                    if (wrapperProperty != null)
                    {
                        var propertyInfo = WrappedType.GetProperty(wrapperProperty.ObfuscatedName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        if (propertyInfo != null)
                        {
                            field.SetValue(null, propertyInfo);
                            propertiesSeen.Add(propertyInfo);
                            logger.LogDebug($"Loaded property {wrapperType.Name}.{field.Name}");
                        }
                    }
                }
                else if (field.FieldType == typeof(FastInvokeHandler) && field.GetValue(null) == null)
                {
                    var wrapperMethod = field.GetCustomAttribute <WrapperMethod>();
                    if (wrapperMethod != null)
                    {
                        var methodInfo = wrapperMethod.GetMethodInfo(WrappedType);
                        if (methodInfo != null)
                        {
                            field.SetValue(null, MethodInvoker.GetHandler(methodInfo));
                            methodsSeen.Add(methodInfo);
                            logger.LogDebug($"Loaded method {wrapperType.Name}.{field.Name}");
                        }
                    }
                }
                else if (field.FieldType == typeof(ConstructorInfo) && field.GetValue(null) == null)
                {
                    var wrapperConstructor = field.GetCustomAttribute <WrapperConstructor>();
                    if (wrapperConstructor != null)
                    {
                        var constructorInfo = WrappedType.GetConstructor(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, wrapperConstructor.Types, null);
                        if (constructorInfo != null)
                        {
                            field.SetValue(null, constructorInfo);
                            constructorsSeen.Add(constructorInfo);
                            logger.LogDebug($"Loaded constructor {wrapperType.Name}.{field.Name}");
                        }
                    }
                }
                if ((field.FieldType == typeof(FieldInfo) || (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(AccessTools.FieldRef <,>)) || field.FieldType == typeof(PropertyInfo) || field.FieldType == typeof(MethodInfo) || field.FieldType == typeof(FastInvokeHandler) || field.FieldType == typeof(ConstructorInfo)) && field.GetValue(null) == null)
                {
                    logger.LogError($"Uh oh! {wrapperType.Name}.{field.Name} was null!");
#if DEBUG
                    logger.LogError($"Program terminating until this wrapper is fixed!");
                    Environment.Exit(1);
#endif
                }
            }
#if DEBUG
            var remainingFields       = WrappedType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Except(fieldsSeen).ToList();
            var remainingProperties   = WrappedType.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Except(propertiesSeen).ToList();
            var remainingMethods      = WrappedType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Except(methodsSeen).ToList();
            var remainingConstructors = WrappedType.GetConstructors(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Except(constructorsSeen).ToList();

            if (remainingFields.Count > 0)
            {
                logger.LogWarning($"Wrapper {wrapperType.Name} is missing {remainingFields.Count} fields, first is {remainingFields.First().Name.DecodeUnicode()}.");
            }
            if (remainingProperties.Count > 0)
            {
                logger.LogWarning($"Wrapper {wrapperType.Name} is missing {remainingProperties.Count} properties, first is {remainingProperties.First().Name.DecodeUnicode()}.");
            }
            if (remainingMethods.Count > 0)
            {
                logger.LogWarning($"Wrapper {wrapperType.Name} is missing {remainingMethods.Count} methods (unless there's method duplication), first is {remainingMethods.First().Name.DecodeUnicode()}.");
            }
            if (remainingConstructors.Count > 0)
            {
                logger.LogWarning($"Wrapper {wrapperType.Name} is missing {remainingConstructors.Count} constructors, first is {remainingConstructors.First().Name.DecodeUnicode()}.");
            }
            if (remainingFields.Count == 0 && remainingProperties.Count == 0 && remainingMethods.Count == 0 && remainingConstructors.Count == 0)
            {
                logger.LogDebug($"Wrapper {wrapperType.Name} is fully defined.");
            }
#endif
        }
Beispiel #12
0
 private static MethodBase GetSandboxMethod(Type typ) =>
 AccessTools.FirstMethod(typ,
                         info => info.IsAssembly && info.ReturnType == typeof(void) && info.GetParameters().FirstOrDefault()?.ParameterType.Name == "TypeDefinition");