static void FindPlatform() { if (memRes.GetType("Terraria.WindowsLaunch") != null) { Platform = Platform.Windows; } if (memRes.GetType("Terraria.LinuxLaunch") != null) { Platform = Platform.Linux; } if (memRes.GetType("Terraria.MacLaunch") != null) { Platform = Platform.OSX; } switch (Environment.OSVersion.Platform) { case PlatformID.MacOSX: Platform = Platform.OSX; break; case PlatformID.Unix: Platform = Platform.Linux; break; default: Platform = Platform.Windows; break; } }
static void WrapMethods() { typeDef_Player.GetMethod("GetFileData", MethodFlags.Public | MethodFlags.Static, typeSys.String, typeSys.Boolean).Wrap(context); typeDef_Player.GetMethod("ItemCheck", MethodFlags.Public | MethodFlags.Instance).Wrap(context); typeDef_Player.GetMethod("KillMe", MethodFlags.Public | MethodFlags.Instance).Wrap(context); typeDef_Player.GetMethod("Update", MethodFlags.Public | MethodFlags.Instance, typeSys.Int32).Wrap(context); typeDef_Player.GetMethod("UpdateEquips", MethodFlags.Public | MethodFlags.Instance, typeSys.Int32).Wrap(context); typeDef_Player.GetMethod("UpdateArmorSets", MethodFlags.Public | MethodFlags.Instance, typeSys.Int32).Wrap(context); typeDef_Player.GetMethod("WingMovement", MethodFlags.Public | MethodFlags.Instance).Wrap(context); typeDef_Player.GetMethod("UpdateBuffs", MethodFlags.Public | MethodFlags.Instance, typeSys.Int32).Wrap(context); typeDef_Player.GetMethod("AddBuff", MethodFlags.Public | MethodFlags.Instance).Wrap(context); var typeDef_uiCharSelect = memRes.GetType("Terraria.GameContent.UI.States.UICharacterSelect"); typeDef_uiCharSelect.GetMethod("NewCharacterClick").Wrap(context); }
internal static void Patch() { c = TerrariaPatcher.c; r = TerrariaPatcher.r; ts = c.PrimaryAssembly.MainModule.TypeSystem; player_t = r.GetType("Terraria.Player"); RemoveBuggyPlayerLoading(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes; typeDef_Recipe = memRes.GetType("Terraria.Recipe"); AddGroupRecipeField(); WrapMethods(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Proj = memRes.GetType("Terraria.Projectile"); WrapMethods(); AddFieldForBHandler(); }
internal static void Patch() { c = TerrariaPatcher.c; r = TerrariaPatcher.r; ts = c.PrimaryAssembly.MainModule.TypeSystem; npc_t = r.GetType("Terraria.NPC"); WrapSetDefaults(); AddFieldForBHandler(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_WorldFile = memRes.GetType("Terraria.IO.WorldFile"); InjectSaveHook(); InjectLoadHook(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes; typeDef_Proj = memRes.GetType("Terraria.Projectile"); WrapMethods(); AddFieldForBHandler(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_WorldFile = memRes.GetType("Terraria.IO.WorldFile"); InjectSaveHook(); InjectLoadHook(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes ; typeSys = context.PrimaryAssembly.ManifestModule.CorLibTypes; typeDef_Recipe = memRes.GetType("Terraria.Recipe"); AddGroupRecipeField(); WrapMethods(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Item = memRes.GetType("Terraria.Item"); WrapSetDefaults(); AddFieldForBHandler(); AddFieldForSound(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Item = memRes.GetType("Terraria.Item"); WrapSetDefaults(); AddFieldForBHandler(); AddFieldForSound(); }
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(); }
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(); }
internal static void Patch() { c = TerrariaPatcher.c; r = TerrariaPatcher.r; ts = c.PrimaryAssembly.MainModule.TypeSystem; main_t = r.GetType("Terraria.Main"); RemoveNetModeCheckFromChat(); RemoveVanillaNpcDrawLimitation(); InsertMusicHook(); }
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(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Mount = memRes.GetType("Terraria.Mount"); WrapMethods(); AddFieldForBHandler(); Remove_FromFields(); RemoveTypeLimitations(); }
static void AddZephyrFishBuffID() { var buffId_t = memRes.GetType("Terraria.ID.BuffID"); if (buffId_t.GetField("ZephyrFish") != null) { return; } buffId_t.Fields.Add(new FieldDefUser("ZephyrFish", new FieldSig(typeSys.Int32), FieldAttributes.Literal | FieldAttributes.Public | FieldAttributes.Static) { Constant = new ConstantUser(127, ElementType.I4) }); }
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(); }
/*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(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Player = memRes.GetType("Terraria.Player"); WrapMethods(); AddFieldForBHandler(); InsertSaveLoadHooks(); RemoveBuggyPlayerLoading(); ReplaceUseSoundCalls(); FixOnEnterWorldField(); InjectMidUpdate(); InitBuffBHandlerArray(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Player = memRes.GetType("Terraria.Player"); WrapMethods(); AddFieldForBHandler(); InsertSaveLoadHooks(); RemoveBuggyPlayerLoading(); ReplaceUseSoundCalls(); FixOnEnterWorldField(); InjectMidUpdate(); InitBuffBHandlerArray(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Main = memRes.GetType("Terraria.Main"); WrapMethods(); RemoveVanillaNpcDrawLimitation(); FixOnEngineLoadField(); RemoveArmourDrawLimitations(); AddOnUpdateKeyboardHook(); //These are causing System.InvalidProgramExceptions so I'm just commenting them out (pls don't remove them) //AddIsChatAllowedHook(); //AddLocalChatHook(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_Main = memRes.GetType("Terraria.Main"); WrapMethods(); RemoveVanillaNpcDrawLimitation(); FixOnEngineLoadField(); RemoveArmourDrawLimitations(); AddOnUpdateKeyboardHook(); //These are causing System.InvalidProgramExceptions so I'm just commenting them out (pls don't remove them) //AddIsChatAllowedHook(); //AddLocalChatHook(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_NPC = memRes.GetType("Terraria.NPC"); WrapMethods(); AddFieldForBHandler(); AddFieldsForAudio(); InsertInitialize(); ReplaceSoundHitCalls(); ReplaceSoundKilledCalls(); InjectBuffEffectsCall(); InitBuffBHandlerArray(); }
internal static void Patch() { context = TerrariaPatcher.context; memRes = TerrariaPatcher.memRes; typeSys = context.PrimaryAssembly.MainModule.TypeSystem; typeDef_NPC = memRes.GetType("Terraria.NPC" ); WrapMethods(); AddFieldForBHandler(); AddFieldsForAudio(); InsertInitialize(); ReplaceSoundHitCalls(); ReplaceSoundKilledCalls(); InjectBuffEffectsCall(); InitBuffBHandlerArray(); }
static void EnlargeFrameImportantArray() { var saveHeader = typeDef_WorldFile.GetMethod("SaveFileFormatHeader"); if ((int)saveHeader.Body.Instructions[0].Operand != 446) { Console.WriteLine("WARNING! max tile type is not 446, SaveFileFormatHeader might've changed!"); } using (var shp = saveHeader.Body.GetILProcessor()) { var first = saveHeader.Body.Instructions[0]; shp.InsertBefore(first, Instruction.Create(OpCodes.Ldsfld, memRes.GetType("Terraria.Main").GetField("tileFrameImportant"))); shp.InsertAfter(saveHeader.Body.Instructions[0] /* do NOT use 'first' here */, Instruction.Create(OpCodes.Ldlen)); shp.Remove(first); //saveHeader.Body.Instructions[0].Operand = 0x7FFF; // should be enough & cannot be more: is read as a short in LoadFileFormatHeader } }