[LIB] Harmony v1.2.0.1

Started by Brrainz, January 13, 2017, 04:59:21 PM

Previous topic - Next topic

themadgunman

Thanks hugely sir, I stared at that for hours with no clue although im sure it was blindingly obvious, added the flags and its now overwriting the code how it should. Now I just have to figure out how to write the actual code i need to fix my problem :)

Brrainz



I made a new Harmony version and release it as beta. Please use, report problems and enjoy:
https://github.com/pardeike/Harmony/releases/tag/v1.1.1b

The plan is to stress test this before RimWorld 1.0 comes out. Hopefully it just works but usually suggestions and bug reports come in and I will put them into the final 1.1.1 that will be release at the same time as Rimworld 1.0.


ENJOY

Kiame

I can't remember if i've said this and even if i have it's worth repeating.

Every mod I've made is possible because of this amazing utility. Thank you Brrainz.

Off to add the newest version to my mods!

Brrainz

Those of you who value my work: please consider supporting me as a Patreon:
https://www.patreon.com/pardeike

Brrainz

HARMONY v1.2 RELEASE
https://github.com/pardeike/Harmony
Now with less bugs and a nuget package "Lib.Harmony"
ENJOY

As always, support me at https://www.patreon.com/pardeike

Brrainz

After a serious bug was found in 1.2 I am planing to release it again today or tomorrow. So stay tuned and if you want you can try the branch that will become the release candidate:

https://github.com/pardeike/Harmony/tree/DeepCopy

Stay tuned!

Brrainz

HARMONY v1.2.0.1 RELEASE
_______________________


This new release of Harmony combines all the small changes and improvements made and found while testing v1.1:

       
  • logging ldstr with format strings no longer corrupts the output
  • Traverse has direct value manipulation with .Value property
  • fixed a casting error in inlineswitch
  • make MethodInvoker call restricted methods
  • the project got updated to the new package format
  • fix for RuntimeMethodHandle/IRuntimeMethodInfo error
  • better error reporting for exceptions during patching
  • AccessTools can now return declared methods, properties and constructors
  • improvements in removal of patches
  • creation of a nuget package for several .NET frameworks
  • make Type[].Description null reference safe
  • Transpilers.MethodReplacer now adapts to call types dynamically
  • patch attributes got a better API while keeping backwards compatibility
  • fixed access control on getters and setters
  • new super cool read-write access to private instance fields
  • specify arguments and injected fields by naming them with index
  • much improved self patching
It is strongly recommened to upgrade to this version.

GitHub:
https://github.com/pardeike/Harmony/releases/tag/v1.2.0.1
nuget: https://www.nuget.org/packages/Lib.Harmony/1.2.0.1

My patreon page: https://www.patreon.com/pardeike

Enjoy!

LWM

Thanks, Roolo!  I have been hitting my head on a related problem since yesterday - how to access the delegate() function created inside Verse.AI.Toils_Haul.cs's StartCarryThing().  I suspect this will work for what I need!

I only saw this because I gave up looking and was going to ask if there was some possible way to get at the problem.

Quote from: Roolo on June 26, 2018, 02:27:31 PM
I managed to get patching iterator methods with transpilers working a while a go with your help. Below is an example (for readers also interested in patching methods returning IEnumerable). With your help it wasn't too hard to figure this all out, but I can imagine many modders aren't aware of the hidden objects in for example iterator methods, so they don't know how to patch the concerning methods. Maybe it's a good idea to add some documentation about this on GitHub?


  //example transpiler patch of Pawn.GetGizmos, which is an iterator method which isn't accessible the regular way
  [HarmonyPatch]
  public static class Pawn_GetGizmos_Transpiler {
        static MethodBase TargetMethod()//The target method is found using the custom logic defined here
        {
            var predicateClass = typeof(Pawn).GetNestedTypes(AccessTools.all)
                .FirstOrDefault(t => t.FullName.Contains("c__Iterator2"));//c__Iterator2 is the hidden object's name, the number at the end of the name may vary. View the IL code to find out the name
            return predicateClass.GetMethods(AccessTools.all).FirstOrDefault(m => m.Name.Contains("MoveNext")); //Look for the method MoveNext inside the hidden iterator object
        }
        static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
        {
         //transpiler code here
        }
  }


Khaligufzel

Any ideas why this doesn't work in B19?


[HarmonyPatch(typeof(Pawn))]
[HarmonyPatch("Kill")]

    static class ColonistDied
    {
        static void Prefix(Pawn __instance)
        {
            Log.Message("Pawn died");
        }
    }


Same with all my Harmony patches...

:(

Brrainz

I don't have my disassembler in front of me, but could it be that Kill() was overloaded and has extra argument and/or multiple versions in b19?

Khaligufzel

NVM, I just forgot to do Harmony instance ;) Sorry about that.

Nightinggale

Can somebody explain why I can't get v1.2.0.1 to work when v1.1 works?

More specifically, ModCheck (GitHub) currently has 1.1, but if I update to 1.2.0.1, I get the following:
ReflectionTypeLoadException getting types in assembly 0Harmony: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in <filename unknown>:0
  at Verse.ModAssemblyHandler.AssemblyIsUsable (System.Reflection.Assembly asm) [0x00000] in <filename unknown>:0

Loader exceptions:
   => System.TypeLoadException: Could not load type 'Harmony.Traverse' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.CodeTranspiler+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.CodeTranspiler+<ConvertToOurInstructions>d__7' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.Patches+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyInstance+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyMethod+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyMethod+<>c__DisplayClass13_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyMethod+<>c__DisplayClass13_1' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyMethod+<>c__DisplayClass14_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyMethodExtensions+<>c__DisplayClass0_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyMethodExtensions+<>c__DisplayClass2_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonyMethodExtensions+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.HarmonySharedState+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.MethodPatcher+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.PatchFunctions+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.PatchProcessor+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.AccessTools+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.AccessTools+<>c__DisplayClass21_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.AccessTools+<>c__DisplayClass22_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.AccessTools+<>c__DisplayClass23_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.AccessTools+<>c__DisplayClass24_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.AccessTools+<>c__DisplayClass36_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.GeneralExtensions+<>c__DisplayClass0_0`1[T]' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.GeneralExtensions+<>c__0`1[T]' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.GeneralExtensions+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.PatchTools+<>c__2`1[T]' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.Tools.SelfPatching+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.ILCopying.Emitter+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type 'Harmony.ILCopying.MethodBodyReader+<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type '<>c' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type '<>c__DisplayClass36_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type '<>c__DisplayClass37_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type '<>c__DisplayClass38_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type '<>c__DisplayClass39_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type '<>c__DisplayClass40_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.
   => System.TypeLoadException: Could not load type '<>c__DisplayClass41_0' from assembly '0Harmony, Version=1.2.0.1, Culture=neutral, PublicKeyToken=null'.

At first I thought I got hold of the wrong DLL, but even copying 0Harmony.dll from InfiniteStorage fails. Running with those errors results in the same as not including 0Harmony.dll at all (not surprising), meaning it completely breaks my mod.

Any idea on what I can do to fix this?
ModCheck - boost your patch loading times and include patchmods in your main mod.

Brrainz

Try to put at least one Harmony 1.2.0.1 enabled mod up highest in the mod list (above even HugsLib). Maybe one that does not need Hugslib (like any of my mods, i.e Camera+) and see if running Harmony 1.2.0.1 FIRST solves all the mod problems later with any Harmony 1.1 enabled mod.

No guarantees but worth a try to learn more about the problem.

bigheadzach

Quote from: Brrainz on September 14, 2018, 12:58:46 PM
Try to put at least one Harmony 1.2.0.1 enabled mod up highest in the mod list (above even HugsLib). Maybe one that does not need Hugslib (like any of my mods, i.e Camera+) and see if running Harmony 1.2.0.1 FIRST solves all the mod problems later with any Harmony 1.1 enabled mod.

No guarantees but worth a try to learn more about the problem.

Wait, that's a thing that makes a difference? We can frontload the latest Harmony by putting a mod that uses it up top and then all uses of Harmony further down will use it?

Nightinggale

Now it works :D

Testing with another mod was a good idea. Released mods using 1.2.0.1 works, but it didn't fix the problem with ModCheck specifically. However it started making the log complain about failing to locate Harmony 1.1.0.0. I went into Project->Add reference and tried to replace/update the harmony reference, but it didn't work for some weird reason. I then ended up deleting all references and start over adding all dll files again and that fixed the problem. Somehow I must have had a reference to 1.1 hiding somewhere, though I'm not sure how and now that it's fixed, it's a little tricky to go back to investigate.
ModCheck - boost your patch loading times and include patchmods in your main mod.