using System; using System.Collections.Generic; using System.IO; using System.Text; using Mono.Cecil; using System.Reflection; namespace NamePatcher { class NamePatcher { static void DrawUsage () { Console.WriteLine ("Usage :"); Console.WriteLine ("NamePatcher [input file] Patches an Assembly and creates a backup of the original file."); } static bool TryArgs (string[] args) { return args.Length == 1 && (File.Exists (args [0])); } static bool makeBackup (string input) { string backupFile_base = input + ".bck"; string backupFile = backupFile_base; int backupIndex = 0; while (File.Exists(backupFile)) { backupFile = backupFile_base + "." + (++backupIndex); if (backupIndex > 10) { return false; } } try { File.Copy (input, backupFile); } catch (Exception e) { Console.WriteLine ("Unable to create backup file : "); Console.WriteLine (e.ToString ()); return false; } return true; } static DefaultAssemblyResolver getAssemblyResolver (string path) { DefaultAssemblyResolver resolver = null; int lastSlash = path.LastIndexOf ("\\"); if (lastSlash == -1) lastSlash = path.LastIndexOf ("/"); if (lastSlash != -1) { string inputPath = path.Substring (0, lastSlash); resolver = new DefaultAssemblyResolver (); resolver.AddSearchDirectory (inputPath); } return resolver; } static void applyManualPatches (ModuleDefinition mainModule) { foreach (FieldDefinition fd in mainModule.GetType ("AdminTools").Fields) { TypeReference fdType = fd.FieldType; if (fdType.FullName.Contains ("List") && fdType.FullName.Contains ("AdminToolsCommandPermissions")) { Console.WriteLine ("Renaming and making public admin tools field -> commandPermissions"); fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public; NameNormalizer.setName (fd, "commandPermissions"); } } foreach (FieldDefinition fd in mainModule.GetType ("World").Fields) { TypeReference fdType = fd.FieldType; if (fdType.FullName.Equals ("System.UInt64")) { Console.WriteLine ("Renaming world field -> gameTime"); NameNormalizer.setName (fd, "gameTime"); } } foreach (FieldDefinition fd in mainModule.GetType ("GameManager").Fields) { TypeReference fdType = fd.FieldType; if (fdType.FullName.Equals ("ConnectionManager")) { Console.WriteLine ("Renaming and making public GameMananger field -> connectionManager"); fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public; NameNormalizer.setName (fd, "connectionManager"); } } foreach (FieldDefinition fd in mainModule.GetType ("ConnectionManager").Fields) { TypeReference fdType = fd.FieldType; if (fdType.FullName.Contains ("Dictionary") && fdType.FullName.Contains ("ClientInfo")) { Console.WriteLine ("Renaming and making public ConnectionManager field -> connectedClients"); fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public; NameNormalizer.setName (fd, "connectedClients"); } if (fdType.FullName.Contains ("Dictionary") && fdType.FullName.Contains ("System.Int32,System.Int32")) { Console.WriteLine ("Renaming and making public ConnectionManager field -> mapClientToEntity"); fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public; NameNormalizer.setName (fd, "mapClientToEntity"); } } string consoleTypeName = string.Empty; TypeDefinition typeTelnetServer = mainModule.GetType ("NetTelnetServer"); foreach (FieldDefinition fd in typeTelnetServer.Fields) { if (NameNormalizer.makeValidName (fd.FieldType.Name) != null) { Console.WriteLine ("Renaming console class -> ConsoleSdtd"); consoleTypeName = fd.FieldType.Name; NameNormalizer.setName (fd.FieldType.Resolve (), "ConsoleSdtd"); NameNormalizer.setName (fd, "console"); } } if (consoleTypeName.Length > 0) { TypeDefinition typeConsole = mainModule.GetType (consoleTypeName); string consoleCommandTypeName = string.Empty; foreach (MethodDefinition md in typeConsole.Methods) { if (!md.IsConstructor) { if (md.Parameters.Count == 3 && md.Parameters [0].ParameterType.Name.Equals ("NetworkPlayer")) { Console.WriteLine ("Renaming console method -> ExecuteCmdFromClient"); NameNormalizer.setName (md, "ExecuteCmdFromClient"); } } } foreach (FieldDefinition fd in typeConsole.Fields) { TypeReference fdType = fd.FieldType; if (fdType.FullName.Contains ("Generic.List")) { if (fdType.IsGenericInstance) { GenericInstanceType genType = (GenericInstanceType)fdType; TypeReference genRef = genType.GenericArguments [0]; if (genRef.Name.Length < 2) { Console.WriteLine ("Renaming console command class -> ConsoleCommand"); NameNormalizer.setName (genRef.Resolve (), "ConsoleCommand"); NameNormalizer.setName (fd, "commands"); consoleCommandTypeName = genRef.Name; } } } if (fdType.FullName.Equals ("GameManager")) { Console.WriteLine ("Renaming and making public console field -> gameManager"); fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public; NameNormalizer.setName (fd, "gameManager"); } } if (consoleCommandTypeName.Length > 0) { foreach (MethodDefinition md in typeConsole.Methods) { if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.Name.Equals (consoleCommandTypeName)) { Console.WriteLine ("Renaming console method -> AddCommand"); NameNormalizer.setName (md, "AddCommand"); } } TypeDefinition typeConsoleCommand = mainModule.GetType (consoleCommandTypeName); foreach (MethodDefinition md in typeConsoleCommand.Methods) { if (!md.IsConstructor) { if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.Name.Equals (consoleTypeName)) { Console.WriteLine ("Renaming console command method -> Help"); NameNormalizer.setName (md, "Help"); } if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("Int32")) { Console.WriteLine ("Renaming console command method -> Timeout"); NameNormalizer.setName (md, "Timeout"); } if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("String[]")) { Console.WriteLine ("Renaming console command method -> Names"); NameNormalizer.setName (md, "Names"); } if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("String")) { Console.WriteLine ("Renaming console command method -> Description"); NameNormalizer.setName (md, "Description"); } if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.IsArray) { Console.WriteLine ("Renaming console command method -> Run"); NameNormalizer.setName (md, "Run"); } } } } } } static void Main (string[] args) { Console.WriteLine ("NamePatcher for 7dtd's Assembly-CSharp.dll [by DerPopo, modified by Alloc] for Dedi build 320404"); if (!TryArgs (args)) { DrawUsage (); return; } string dllPath = args [0]; if (!makeBackup (dllPath)) { Console.WriteLine ("Could not create a backup file (maybe too many old backups?)"); return; } AssemblyDefinition input; try { input = AssemblyDefinition.ReadAssembly (dllPath, new ReaderParameters { AssemblyResolver = getAssemblyResolver(dllPath), }); } catch (Exception e) { Console.WriteLine ("Unable to load the input file : "); Console.WriteLine (e.ToString ()); return; } Console.WriteLine (); Console.WriteLine ("Patching assembly " + dllPath + " (" + input.Modules.Count + " module[s]) ..."); applyManualPatches (input.MainModule); try { foreach (ModuleDefinition mdef in input.Modules) { Console.WriteLine ("Patching module " + mdef.Name + " (" + mdef.Types.Count + " type[s]) ..."); foreach (TypeDefinition tdef in mdef.Types) { NameNormalizer.CheckNames (tdef); } } } catch (Exception e) { Console.WriteLine (); Console.WriteLine ("Unable to patch the assembly : "); Console.WriteLine (e.ToString ()); return; } Console.WriteLine ("Finalizing patches..."); try { NameNormalizer.FinalizeNormalizing (); } catch (Exception e) { Console.WriteLine (); Console.WriteLine ("Unable to finalize patching : "); Console.WriteLine (e.ToString ()); return; } NameNormalizer.clnamestomod.Clear (); NameNormalizer.vclasses.Clear (); Console.WriteLine ("Saving the patched assembly ..."); try { input.Write (dllPath); } catch (Exception e) { Console.WriteLine (); Console.WriteLine ("Unable to save the assembly : "); Console.WriteLine (e.ToString ()); return; } Console.WriteLine (); Console.WriteLine ("Success."); } } }