Пример #1
0
        public static void Patch(DNContext context, string outputPath)
        {
            TerrariaPatcher.context = context;
            memRes = TerrariaPatcher.context.Resolver;

            TerrariaPatcher.context.PrimaryAssembly.Name = "Prism.Terraria";
            TerrariaPatcher.context.PrimaryAssembly.ManifestModule.Name = TerrariaPatcher.context.PrimaryAssembly.Name + ".dll";

            FindPlatform();

            Publicify();
            //AddInternalsVisibleToAttr();
            RemoveConsoleWriteLineInWndProcHook();

            ItemPatcher      .Patch();
            NpcPatcher       .Patch();
            ProjectilePatcher.Patch();
            PlayerPatcher    .Patch();
            MountPatcher     .Patch();
            MainPatcher      .Patch();
            TilePatcher      .Patch();
            WorldFilePatcher .Patch();
            RecipePatcher    .Patch();
            BuffPatcher      .Patch();
            // do other stuff here

            OptimizeAll();

            // Newtonsoft.Json.dll, Steamworks.NET.dll and Ionic.Zip.CF.dll are required to write the assembly (and FNA and WindowsBase on mono, too)
            TerrariaPatcher.context.PrimaryAssembly.Write(outputPath);

            memRes = null;
            TerrariaPatcher.context = null;
        }
Пример #2
0
        public static void Patch(DNContext context, string outputPath)
        {
            TerrariaPatcher.context = context;
            memRes = TerrariaPatcher.context.Resolver;

            TerrariaPatcher.context.PrimaryAssembly.Name = "Prism.Terraria";
            TerrariaPatcher.context.PrimaryAssembly.ManifestModule.Name = TerrariaPatcher.context.PrimaryAssembly.Name + ".dll";

            FindPlatform();

            Publicify();
            //AddInternalsVisibleToAttr();
            RemoveConsoleWriteLineInWndProcHook();

            ItemPatcher.Patch();
            NpcPatcher.Patch();
            ProjectilePatcher.Patch();
            PlayerPatcher.Patch();
            MountPatcher.Patch();
            MainPatcher.Patch();
            TilePatcher.Patch();
            WorldFilePatcher.Patch();
            RecipePatcher.Patch();
            BuffPatcher.Patch();
            // do other stuff here

            OptimizeAll();

            // Newtonsoft.Json.dll, Steamworks.NET.dll and Ionic.Zip.CF.dll are required to write the assembly (and FNA and WindowsBase on mono, too)
            TerrariaPatcher.context.PrimaryAssembly.Write(outputPath);

            memRes = null;
            TerrariaPatcher.context = null;
        }
Пример #3
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes ;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;

            AddZephyrFishBuffID();
        }
Пример #4
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;

            AddZephyrFishBuffID();
        }
Пример #5
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys        = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Recipe = memRes.GetType("Terraria.Recipe");

            AddGroupRecipeField();
            WrapMethods();
        }
Пример #6
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes ;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Recipe = memRes.GetType("Terraria.Recipe");

            AddGroupRecipeField();
            WrapMethods();
        }
Пример #7
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys      = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Proj = memRes.GetType("Terraria.Projectile");

            WrapMethods();
            AddFieldForBHandler();
        }
Пример #8
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes = TerrariaPatcher.memRes;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Proj = memRes.GetType("Terraria.Projectile");

            WrapMethods();
            AddFieldForBHandler();
        }
Пример #9
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes ;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Item = memRes.GetType("Terraria.Item");

            WrapSetDefaults();
            AddFieldForBHandler();
            AddFieldForSound();
        }
Пример #10
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys           = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_WorldFile = memRes.GetType("Terraria.IO.WorldFile");

            InjectSaveHook();
            InjectLoadHook();
            EnlargeFrameImportantArray();
        }
Пример #11
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes ;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Item = memRes.GetType("Terraria.Item");

            WrapSetDefaults();
            AddFieldForBHandler();
            AddFieldForSound();
        }
Пример #12
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_WorldFile = memRes.GetType("Terraria.IO.WorldFile");

            InjectSaveHook();
            InjectLoadHook();
            EnlargeFrameImportantArray();
        }
Пример #13
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes = TerrariaPatcher.memRes;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Mount = memRes.GetType("Terraria.Mount");

            WrapMethods();
            AddFieldForBHandler();
            Remove_FromFields();
            RemoveTypeLimitations();
        }
Пример #14
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys       = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Mount = memRes.GetType("Terraria.Mount");

            WrapMethods();
            AddFieldForBHandler();
            Remove_FromFields();
            RemoveTypeLimitations();
        }
Пример #15
0
        /*static bool IsGet2DArrCall(TypeReference arrayType, Instruction i)
         * {
         *  var inner = arrayType.GetElementType();
         *
         *  if (i.OpCode.Code != Code.Call)
         *      return false;
         *
         *  var mtd = i.Operand as MethodReference;
         *
         *  // for debugging
         *  //if (mtd == null)
         *  //    return false;
         *  //if (mtd.Name != "Get")
         *  //    return false;
         *  //if (mtd.DeclaringType.FullName != arrayType.FullName)
         *  //    return false;
         *  //if (!mtd.HasThis)
         *  //    return false;
         *  //if (mtd.ReturnType != inner)
         *  //    return false;
         *  //if (mtd.Parameters.Count != 2)
         *  //    return false;
         *  //if (!mtd.Parameters.All(pd => pd.ParameterType == typeSys.Int32))
         *  //    return false;
         *
         *  //return true;
         *
         *  return mtd != null && mtd.Name == "Get" && mtd.DeclaringType.FullName == arrayType.FullName && mtd.ReturnType == inner && !mtd.HasGenericParameters && mtd.Parameters.Count == 2 && mtd.Parameters.All(pd => pd.ParameterType == typeSys.Int32) && mtd.HasThis;
         * }*/
        /*static void AddExtendedWallTypeField()
         * {
         *  var wallTypeEx = new FieldDefinition("P_wallTypeEx", FieldAttributes.Assembly | FieldAttributes.Static, memRes.ReferenceOf(typeof(ushort[])));
         *
         *  var main_t = memRes.GetType("Terraria.Main");
         *
         #region add field
         *  {
         *      typeDef_Tile.Fields.Add(wallTypeEx);
         *
         *      // initialize in static ctor
         *      var cb = typeDef_Tile.GetOrCreateStaticCtor().Body;
         *      var cproc = cb.GetILProcessor();
         *
         *      var finalRet = cb.Instructions.Last();
         *
         *      cproc.InsertBefore(finalRet, Instruction.Create(OpCodes.Ldsfld, main_t.GetField("maxTilesX")));
         *      cproc.InsertBefore(finalRet, Instruction.Create(OpCodes.Ldsfld, main_t.GetField("maxTilesY")));
         *      cproc.InsertBefore(finalRet, Instruction.Create(OpCodes.Dup));
         *      cproc.InsertBefore(finalRet, Instruction.Create(OpCodes.Newarr, wallTypeEx.FieldType));
         *      cproc.InsertBefore(finalRet, Instruction.Create(OpCodes.Stsfld, wallTypeEx));
         *  }
         #endregion
         *
         #region add twodimentional getter
         *  {
         *      var getWallType = new MethodDefinition("GetWallType", MethodAttributes.Public | MethodAttributes.Static, typeSys.UInt16);
         *
         *      getWallType.Parameters.Add(new ParameterDefinition("x", 0, typeSys.Int32));
         *      getWallType.Parameters.Add(new ParameterDefinition("y", 0, typeSys.Int32));
         *
         *      var gwproc = getWallType.Body.GetILProcessor();
         *
         *      gwproc.Emit(OpCodes.Ldsfld, wallTypeEx);
         *
         *      // wallTypeEx[y * Main.maxTilesY + x]
         *      gwproc.Emit(OpCodes.Ldarg_1);
         *      //gwproc.Emit(OpCodes.Ldsfld, main_t.GetField("maxTilesY"));
         *      gwproc.Emit(OpCodes.Ldc_I4, LARGEST_WLD_Y);
         *      gwproc.Emit(OpCodes.Mul);
         *      gwproc.Emit(OpCodes.Ldarg_0);
         *      gwproc.Emit(OpCodes.Add);
         *      gwproc.Emit(OpCodes.Ldelem_Ref);
         *      gwproc.Emit(OpCodes.Ret);
         *
         *      typeDef_Tile.Methods.Add(getWallType);
         *
         *      // add an overload with a tile argument that ignores the tile, so the stack doesn't get messed up when using injected GetWallType(I) calls.
         *      {
         *          var getWallTypeI = new MethodDefinition("GetWallTypeI", MethodAttributes.Assembly | MethodAttributes.Static, typeSys.UInt16);
         *
         *          getWallTypeI.Parameters.Add(new ParameterDefinition("tile", 0, typeSys.Object));
         *          getWallTypeI.Parameters.Add(new ParameterDefinition("x", 0, typeSys.Int32));
         *          getWallTypeI.Parameters.Add(new ParameterDefinition("y", 0, typeSys.Int32));
         *
         *          var gwiproc = getWallTypeI.Body.GetILProcessor();
         *
         *          gwiproc.Emit(OpCodes.Ldsfld, wallTypeEx);
         *
         *          // wallTypeEx[y * Main.maxTilesY + x]
         *          gwiproc.Emit(OpCodes.Ldarg_2);
         *          //gwiproc.Emit(OpCodes.Ldsfld, main_t.GetField("maxTilesY"));
         *          gwiproc.Emit(OpCodes.Ldc_I4, LARGEST_WLD_Y);
         *          gwiproc.Emit(OpCodes.Mul);
         *          gwiproc.Emit(OpCodes.Ldarg_1);
         *          gwiproc.Emit(OpCodes.Add);
         *          gwiproc.Emit(OpCodes.Ldelem_Ref);
         *          gwiproc.Emit(OpCodes.Ret);
         *
         *          typeDef_Tile.Methods.Add(getWallTypeI);
         *      }
         *  }
         #endregion
         *
         #region add twodimentional setter
         *  {
         *      var setWallType = new MethodDefinition("SetWallType", MethodAttributes.Public | MethodAttributes.Static, typeSys.Void);
         *
         *      setWallType.Parameters.Add(new ParameterDefinition("x"   , 0, typeSys. Int32));
         *      setWallType.Parameters.Add(new ParameterDefinition("y"   , 0, typeSys. Int32));
         *      setWallType.Parameters.Add(new ParameterDefinition("value", 0, typeSys.UInt16));
         *
         *      var swproc = setWallType.Body.GetILProcessor();
         *
         *      swproc.Emit(OpCodes.Ldsfld, wallTypeEx);
         *
         *      // wallTypeEx[y * Main.maxTilesY + x]
         *      swproc.Emit(OpCodes.Ldarg_1);
         *      //swproc.Emit(OpCodes.Ldsfld, main_t.GetField("maxTilesY"));
         *      swproc.Emit(OpCodes.Ldc_I4, LARGEST_WLD_Y);
         *      swproc.Emit(OpCodes.Mul);
         *      swproc.Emit(OpCodes.Ldarg_0);
         *      swproc.Emit(OpCodes.Add);
         *      swproc.Emit(OpCodes.Ldarg_2);
         *      swproc.Emit(OpCodes.Stelem_Ref);
         *      swproc.Emit(OpCodes.Ret);
         *
         *      typeDef_Tile.Methods.Add(setWallType);
         *
         *      // add an overload with a tile argument that ignores the tile, so the stack doesn't get messed up when using injected SetWallType(I) calls.
         *      {
         *          var setWallTypeI = new MethodDefinition("SetWallTypeI", MethodAttributes.Assembly | MethodAttributes.Static, typeSys.Void);
         *
         *          setWallTypeI.Parameters.Add(new ParameterDefinition("tile", 0, typeDef_Tile));
         *          setWallTypeI.Parameters.Add(new ParameterDefinition("x", 0, typeSys.Int32));
         *          setWallTypeI.Parameters.Add(new ParameterDefinition("y", 0, typeSys.Int32));
         *          setWallTypeI.Parameters.Add(new ParameterDefinition("value", 0, typeSys.UInt16));
         *
         *          var swb = setWallTypeI.Body;
         *
         *          var swiproc = swb.GetILProcessor();
         *
         *          swiproc.Emit(OpCodes.Ldsfld, wallTypeEx);
         *
         *          // wallTypeEx[y * Main.maxTilesY + x]
         *          swiproc.Emit(OpCodes.Ldarg_2);
         *          //swiproc.Emit(OpCodes.Ldsfld, main_t.GetField("maxTilesY"));
         *          swiproc.Emit(OpCodes.Ldc_I4, LARGEST_WLD_Y);
         *          swiproc.Emit(OpCodes.Mul);
         *          swiproc.Emit(OpCodes.Ldarg_1);
         *          swiproc.Emit(OpCodes.Add);
         *          swiproc.Emit(OpCodes.Ldarg_3);
         *          swiproc.Emit(OpCodes.Stelem_Ref);
         *          swiproc.Emit(OpCodes.Ret);
         *
         *          typeDef_Tile.Methods.Add(setWallTypeI);
         *      }
         *  }
         #endregion
         * }*/
        /*static void ReplaceGetWallTypeCalls()
         * {
         *  var gw = typeDef_Tile.GetMethod("GetWallTypeI"); // using the internal version
         *
         *  var main_t = memRes.GetType("Terraria.Main");
         *  var main_tile = main_t.GetField("tile");
         *  var tile_wall = typeDef_Tile.GetField("wall");
         *
         *  foreach (var td in context.PrimaryAssembly.MainModule.Types)
         *      foreach (var md in td.Methods)
         *      {
         *          if (!md.HasBody)
         *              continue;
         *
         *          var body = md.Body;
         *          var ins = body.Instructions;
         *          var proc = body.GetILProcessor();
         *
         *          for (int i = 0; i < ins.Count; i++)
         *          {
         *              var n = ins[i];
         *
         *              if (IsGet2DArrCall(main_tile.FieldType, n))
         *              {
         *                  n = n.Next;
         *
         *                  if (n == null)
         *                      continue;
         *
         *                  if (n.OpCode.Code == Code.Ldfld && n.Operand == tile_wall)
         *                  {
         *                      var p = ins[i].Previous; // shouldn't be null, tile array + indices are loaded on the IL stack
         *
         *                      proc.Remove(p.Next);
         *                      proc.Remove(n);
         *
         *                      proc.InsertAfter(p, Instruction.Create(OpCodes.Call, gw));
         *
         *                      // rewire branch targets
         *                      foreach (var i_ in ins)
         *                          if (i_ != n && i_ != ins[i] && i_.Operand == ins[i])
         *                              i_.Operand = p.Next;
         *
         *                      i--;
         *                  }
         *              }
         *          }
         *      }
         * }*/
        /*static void ReplaceSetWallTypeCalls()
         * {
         *  var sw = typeDef_Tile.GetMethod("SetWallTypeI"); // using the internal version
         *
         *  var main_t = memRes.GetType("Terraria.Main");
         *  var main_tile = main_t.GetField("tile");
         *  var tile_wall = typeDef_Tile.GetField("wall");
         *
         *  foreach (var td in context.PrimaryAssembly.MainModule.Types)
         *      foreach (var md in td.Methods)
         *      {
         *          if (!md.HasBody)
         *              continue;
         *
         *          var body = md.Body;
         *          var ins = body.Instructions;
         *          var proc = body.GetILProcessor();
         *
         *          for (int i = 0; i < ins.Count; i++)
         *          {
         *              var n = ins[i];
         *
         *              if (n.OpCode.Code == Code.Stfld && n.Operand == tile_wall)
         *              {
         *                  var p = ins[i].Previous; // shouldn't be null, tile array + indices are loaded on the IL stack
         *
         *                  proc.Remove(n);
         *
         *                  proc.InsertAfter(p, Instruction.Create(OpCodes.Call, sw));
         *
         *                  // rewire branch targets
         *                  foreach (var i_ in ins)
         *                      if (i_ != n && i_.Operand == n)
         *                          i_.Operand = p.Next;
         *              }
         *          }
         *      }
         * }
         * static void HideWallField()
         * {
         *  var wall = typeDef_Tile.GetField("wall");
         *
         *  wall.Name = "P_wall";
         *
         *  wall.Attributes = FieldAttributes.Assembly;
         * }*/
        #endregion

        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys      = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Tile = memRes.GetType("Terraria.Tile");

            ChangeFieldType();
            ChangeLocalTypes();

            //AddExtendedWallTypeField();
            //ReplaceGetWallTypeCalls ();
            //ReplaceSetWallTypeCalls ();
            //HideWallField();
        }
        /// <summary>
        /// Replaces all method references with the specified reference within the specified context.
        /// </summary>
        /// <param name="context">The current <see cref="DNContext"/>.</param>
        /// <param name="targetRef">The <see cref="MethodReference"/> to replace.</param>
        /// <param name="newRef">The <see cref="MethodReference"/> to replace targetRef with.</param>
        /// <param name="exitRecursion">Excludes recursive method calls from the replacement operation (may have undesired consequences with recursive methods).</param>
        public static void ReplaceAllMethodRefs(this IMethod targetRef, IMethod newRef, DNContext context, bool exitRecursion = true)
        {
            foreach (var tDef in context.PrimaryAssembly.ManifestModule.Types)
                foreach (var mDef in tDef.Methods)
                {
                    if (!mDef.HasBody) // abstract, runtime & external, etc
                        continue;

                    if (exitRecursion && mDef == newRef) // may have undesired consequences with recursive methods
                        continue;

                    foreach (var i in mDef.Body.Instructions)
                        if (i.Operand is IMethod && comp.Equals(targetRef, (IMethod)i.Operand))
                            i.Operand = newRef;
                }
        }
Пример #17
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes ;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Tile = memRes.GetType("Terraria.Tile");

            ChangeFieldType ();
            ChangeLocalTypes();

              //AddExtendedWallTypeField();
              //ReplaceGetWallTypeCalls ();
              //ReplaceSetWallTypeCalls ();
              //HideWallField();
        }
Пример #18
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys        = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Player = memRes.GetType("Terraria.Player");

            WrapMethods();
            AddFieldForBHandler();
            AddPlaceThingHook();
            InsertSaveLoadHooks();
            RemoveBuggyPlayerLoading();
            RemoveStatCaps();
            ReplaceUseSoundCalls();
            FixOnEnterWorldBackingFieldName();
            InjectMidUpdate();
            InitBuffBHandlerArray();
        }
Пример #19
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes ;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_NPC = memRes.GetType("Terraria.NPC" );

            WrapMethods();

            AddFieldForBHandler();
            AddFieldsForAudio();

            InsertInitialize();
            ReplaceSoundHitCalls();
            ReplaceSoundKilledCalls();
            InjectBuffEffectsCall();
            InitBuffBHandlerArray();
        }
Пример #20
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Player = memRes.GetType("Terraria.Player");

            WrapMethods();
            AddFieldForBHandler();
            AddPlaceThingHook();
            InsertSaveLoadHooks();
            RemoveBuggyPlayerLoading();
            RemoveStatCaps();
            ReplaceUseSoundCalls();
            FixOnEnterWorldBackingFieldName();
            InjectMidUpdate();
            InitBuffBHandlerArray();
        }
Пример #21
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys     = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_NPC = memRes.GetType("Terraria.NPC");

            WrapMethods();

            AddFieldForBHandler();
            AddFieldsForAudio();

            InsertInitialize();
            ReplaceSoundHitCalls();
            ReplaceSoundKilledCalls();
            InjectBuffEffectsCall();
            InitBuffBHandlerArray();
        }
Пример #22
0
        internal static void Patch()
        {
            context = TerrariaPatcher.context;
            memRes  = TerrariaPatcher.memRes;

            typeSys      = context.PrimaryAssembly.ManifestModule.CorLibTypes;
            typeDef_Main = memRes.GetType("Terraria.Main");

            WrapMethods();
            RemoveVanillaNpcDrawLimitation();
            FixOnEngineLoadField();
            RemoveArmourDrawLimitations();
            AddPreDrawHook();
            AddOnUpdateKeyboardHook();
            AddPostScreenClearHook();

            //These are causing System.InvalidProgramExceptions so I'm just commenting them out (pls don't remove them)
            //AddIsChatAllowedHook();
            //AddLocalChatHook();
        }
Пример #23
0
 public UnitOfWork(DNContext context)
 => _context = context;
Пример #24
0
        static int Main(string[] args)
        {
            var toRem = new List <string>();

            try
            {
                if (!ParseRuntimeArgs(args))
                {
                    return(1);
                }

                if (MsBuild)
                {
                    Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                }

                TerrariaExecutable = Path.GetFullPath(TerrariaExecutable);

                if (!File.Exists(TerrariaExecutable))
                {
                    Console.WriteLine("Terraria.exe not found. (full path: \"" + Path.GetFullPath(TerrariaExecutable) + "\")");
                    // the file is added in the .gitignore (and so is the patched file)
                    if (MsBuild)
                    {
                        Console.WriteLine("In order to build Prism, you must place a copy of your own Terraria.exe file in the '."
                                          + Path.DirectorySeparatorChar /* be cross-platform */ + "References' directory.");
                    }

                    return(1);
                }

                var dir = Path.GetDirectoryName(TerrariaExecutable);
                if (!MsBuild)
                {
                    Environment.CurrentDirectory = dir;
                }

                // just copy the files so the assembly resolving works, they'll be removed when it finished
                if (!MsBuild)
                {
                    var fs = new[] { "Newtonsoft.Json", "Steamworks.NET", "Ionic.Zip.CF" }.Select(n => Path.Combine(dir, n + ".dll"));
                    var ufs = new[] { "WindowsBase", "FNA" }.Select(n => Path.Combine(dir, n + ".dll"));

                    foreach (var source in fs.Concat(IsWindows ? new string[0] : ufs))
                    {
                        var target = Path.Combine(Environment.CurrentDirectory, Path.GetFileName(source));

                        if (!File.Exists(target) /* don't do a useless copy (and worse, remove it afterwards, even when it could be needed later) */)
                        {
                            // unpack when file file does not exist
                            if (!File.Exists(source))
                            {
                                var dll = Assembly.GetExecutingAssembly().GetManifestResourceStream("Prism.TerrariaPatcher.RefDlls." + Path.GetFileName(source));

                                if (dll != null)
                                {
                                    using (var fstr = File.OpenWrite(source))
                                    {
                                        dll.CopyTo(fstr);
                                        fstr.Flush(true);
                                    }
                                }
                            }

                            try // #15
                            {
                                File.Copy(source, target, false);
                                toRem.Add(target);
                            }
                            catch (IOException) { } // well f**k
                        }
                    }
                }

                var c = new DNContext(TerrariaExecutable);

                dir = Path.GetDirectoryName(PrismAssembly);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                // this will stop the build process if the patcher fails, because a reference in Prism.csproj will be missing
                if (MsBuild && File.Exists(PrismAssembly))
                {
                    File.Delete(PrismAssembly);
                }

                try
                {
                    Console.Write("Patching, please wait... ");

                    Patcher.Patch(c, PrismAssembly);
                }
                catch (Exception e) when(!Debugger.IsAttached)
                {
                    Console.WriteLine("Something went wrong while patching " + Path.GetFileName(TerrariaExecutable) + ":");
                    Console.WriteLine(e);

                    return(1);
                }

                Console.WriteLine("Patching finished.");

                return(0);
            }
            finally
            {
                if (!MsBuild)
                {
                    Console.WriteLine("Press any key to exit...");
                    Console.ReadKey(true);
                }

                foreach (var s in toRem)
                {
                    File.Delete(s);
                }
            }
        }
Пример #25
0
        public static TypeDef CreateDelegate(this DNContext context, string @namespace, string name, TypeSig returnType, out MethodDef invoke, params TypeSig[] parameters)
        {
            var cResolver = context.Resolver;
            var typeSys   = context.PrimaryAssembly.ManifestModule.CorLibTypes;

            var delegateType = new TypeDefUser(@namespace, name, cResolver.ReferenceOf(typeof(MulticastDelegate)));

            delegateType.Attributes = TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.Sealed;

            var ctor = new MethodDefUser(".ctor", MethodSig.CreateInstance(typeSys.Void, typeSys.Object, typeSys.IntPtr),
                                         MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

            ctor.ImplAttributes |= MethodImplAttributes.Runtime;
            // param 0 is 'this'
            ctor.Parameters[1].CreateParamDef();
            ctor.Parameters[1].ParamDef.Name = "object";
            ctor.Parameters[2].CreateParamDef();
            ctor.Parameters[2].ParamDef.Name = "method";

            delegateType.Methods.Add(ctor);

            invoke = new MethodDefUser("Invoke", MethodSig.CreateInstance(returnType, parameters), MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual);
            invoke.ImplAttributes |= MethodImplAttributes.Runtime;
            for (int i = 1; i <= parameters.Length; i++)
            {
                invoke.Parameters[i].CreateParamDef();
                invoke.Parameters[i].ParamDef.Name = "arg" + (i - 1);
            }

            delegateType.Methods.Add(invoke);

            var beginInvoke = new MethodDefUser("BeginInvoke", MethodSig.CreateInstance(cResolver.ReferenceOf(typeof(IAsyncResult)).ToTypeSig(),
                                                                                        parameters.Concat(new[] { cResolver.ReferenceOf(typeof(AsyncCallback)).ToTypeSig(), typeSys.Object }).ToArray()),
                                                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual);

            beginInvoke.ImplAttributes |= MethodImplAttributes.Runtime;
            for (int i = 0; i < parameters.Length; i++)
            {
                beginInvoke.Parameters[i + 1].CreateParamDef();
                beginInvoke.Parameters[i + 1].ParamDef.Name = "arg" + i;
            }
            beginInvoke.Parameters[beginInvoke.Parameters.Count - 2].CreateParamDef();
            beginInvoke.Parameters[beginInvoke.Parameters.Count - 2].ParamDef.Name = "callback";
            beginInvoke.Parameters[beginInvoke.Parameters.Count - 1].CreateParamDef();
            beginInvoke.Parameters[beginInvoke.Parameters.Count - 1].ParamDef.Name = "object";

            delegateType.Methods.Add(beginInvoke);

            var endInvoke = new MethodDefUser("EndInvoke", MethodSig.CreateInstance(typeSys.Void, cResolver.ReferenceOf(typeof(IAsyncResult)).ToTypeSig()),
                                              MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual);

            endInvoke.ImplAttributes |= MethodImplAttributes.Runtime;
            endInvoke.Parameters[1].CreateParamDef();
            endInvoke.Parameters[1].ParamDef.Name = "result";

            delegateType.Methods.Add(endInvoke);

            context.PrimaryAssembly.ManifestModule.Types.Add(delegateType);

            return(delegateType);
        }
 public DNReflectionComparer(DNContext context)
 {
     c_wr = new WeakReference(context);
 }
Пример #27
0
 public ProductRepository(DNContext context)
 => _context = context;
Пример #28
0
        /// <summary>
        /// Replaces all method references with the specified reference within the specified context.
        /// </summary>
        /// <param name="context">The current <see cref="DNContext"/>.</param>
        /// <param name="targetRef">The <see cref="MethodReference"/> to replace.</param>
        /// <param name="newRef">The <see cref="MethodReference"/> to replace targetRef with.</param>
        /// <param name="exitRecursion">Excludes recursive method calls from the replacement operation (may have undesired consequences with recursive methods).</param>
        public static void ReplaceAllMethodRefs(this IMethod targetRef, IMethod newRef, DNContext context, bool exitRecursion = true)
        {
            foreach (var tDef in context.PrimaryAssembly.ManifestModule.Types)
            {
                foreach (var mDef in tDef.Methods)
                {
                    if (!mDef.HasBody) // abstract, runtime & external, etc
                    {
                        continue;
                    }

                    if (exitRecursion && mDef == newRef) // may have undesired consequences with recursive methods
                    {
                        continue;
                    }

                    foreach (var i in mDef.Body.Instructions)
                    {
                        if (i.Operand is IMethod && comp.Equals(targetRef, (IMethod)i.Operand))
                        {
                            i.Operand = newRef;
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Wraps a method using a fancy delegate. Replaces all references of the method with the wrapped one and creates an "On[MethodName]" hook which passes the method's parent type followed by the type parameters of the original method.
 /// </summary>
 /// <param name="context">The current Cecil context.</param>
 /// <param name="origMethod">The method to wrap.</param>
 public static void Wrap(this MethodDef method, DNContext context)
 {
     var delTypeName = DefDelTypeName(method);
     method.Wrap(context, delTypeName[0], delTypeName[1], "P_On" + GetOverloadedName(method));
 }
        /// <summary>
        /// Wraps a method using a fancy delegate. Replaces all references of the method with the wrapped one and creates an "On[MethodName]" hook which passes the method's parent type followed by the type parameters of the original method.
        /// </summary>
        /// <param name="context">The current Cecil context.</param>
        /// <param name="delegateNS">The namespace of the delegate type to create.</param>
        /// <param name="delegateTypeName">The name of the delegate type to create.</param>
        /// <param name="origMethod">The method to wrap.</param>
        public static void Wrap(this MethodDef origMethod, DNContext context, string delegateNS, string delegateTypeName, string fieldName)
        {
            MethodDef invokeDelegate;

            //SingletonTRArr[0] = origMethod.DeclaringType.ToTypeSig();

            ////If anyone knows a better way to insert one element at the beginning of an array and scoot
            ////all the other elements down one index then go ahead and do it lol. I dunno how2array.
            var delegateArgs = origMethod.Parameters.Select(p => p.Type).ToArray();

            var newDelegateType = context.CreateDelegate(delegateNS, delegateTypeName, origMethod.ReturnType, out invokeDelegate, delegateArgs);

            var newMethod = origMethod.ReplaceAndHook(invokeDelegate, origMethod, fieldName);

            // you're not special anymore!
            if ((origMethod.Attributes & MethodAttributes.SpecialName) != 0)
                origMethod.Attributes ^= MethodAttributes.SpecialName;
            if ((origMethod.Attributes & MethodAttributes.RTSpecialName) != 0)
                origMethod.Attributes ^= MethodAttributes.RTSpecialName;

            origMethod.ReplaceAllMethodRefs(newMethod, context);
        }
Пример #31
0
        static int Main(string[] args)
        {
            var toRem = new List<string>();

            try
            {
                if (!ParseRuntimeArgs(args))
                    return 1;

                if (MsBuild)
                    Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

                TerrariaExecutable = Path.GetFullPath(TerrariaExecutable);

                if (!File.Exists(TerrariaExecutable))
                {
                    Console.WriteLine("Terraria.exe not found. (full path: \"" + Path.GetFullPath(TerrariaExecutable) + "\")");
                    // the file is added in the .gitignore (and so is the patched file)
                    if (MsBuild)
                        Console.WriteLine("In order to build Prism, you must place a copy of your own Terraria.exe file in the '."
                            + Path.DirectorySeparatorChar /* be cross-platform */ + "References' directory.");

                    return 1;
                }

                var dir = Path.GetDirectoryName(TerrariaExecutable);
                if (!MsBuild)
                    Environment.CurrentDirectory = dir;

                // just copy the files so the assembly resolving works, they'll be removed when it finished
                if (!MsBuild)
                {
                    var  fs = new[] { "Newtonsoft.Json", "Steamworks.NET", "Ionic.Zip.CF" }.Select(n => Path.Combine(dir, n + ".dll"));
                    var ufs = new[] { "WindowsBase"    , "FNA"                            }.Select(n => Path.Combine(dir, n + ".dll"));

                    foreach (var source in fs.Concat(IsWindows ? new string[0] : ufs))
                    {
                        var target = Path.Combine(Environment.CurrentDirectory, Path.GetFileName(source));

                        if (!File.Exists(target) /* don't do a useless copy (and worse, remove it afterwards, even when it could be needed later) */)
                        {
                            // unpack when file file does not exist
                            if (!File.Exists(source))
                            {
                                var dll = Assembly.GetExecutingAssembly().GetManifestResourceStream("Prism.TerrariaPatcher.RefDlls." + Path.GetFileName(source));

                                if (dll != null)
                                    using (var fstr = File.OpenWrite(source))
                                    {
                                        dll.CopyTo(fstr);
                                        fstr.Flush(true);
                                    }
                            }

                            try // #15
                            {
                                File.Copy(source, target, false);
                                toRem.Add(target);
                            }
                            catch (IOException) { } // well f**k
                        }
                    }
                }

                var c = new DNContext(TerrariaExecutable);

                dir = Path.GetDirectoryName(PrismAssembly);
                if (!Directory.Exists(dir))
                    Directory.CreateDirectory(dir);

                // this will stop the build process if the patcher fails, because a reference in Prism.csproj will be missing
                if (MsBuild && File.Exists(PrismAssembly))
                    File.Delete(PrismAssembly);

                try
                {
                    Console.Write("Patching, please wait... ");

                    Patcher.Patch(c, PrismAssembly);
                }
                catch (Exception e) when (!Debugger.IsAttached)
                {
                    Console.WriteLine("Something went wrong while patching " + Path.GetFileName(TerrariaExecutable) + ":");
                    Console.WriteLine(e);

                    return 1;
                }

                Console.WriteLine("Patching finished.");

                return 0;
            }
            finally
            {
                if (!MsBuild)
                {
                    Console.WriteLine("Press any key to exit...");
                    Console.ReadKey(true);
                }

                foreach (var s in toRem)
                    File.Delete(s);
            }
        }