source: binary-improvements/NamePatcher/NamePatcher.cs @ 77

Last change on this file since 77 was 77, checked in by alloc, 7 years ago

NamePatcher

File size: 8.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using Mono.Cecil;
6using System.Reflection;
7
8namespace NamePatcher
9{
10        class NamePatcher
11        {
12                static void DrawUsage ()
13                {
14                        Console.WriteLine ("Usage :");
15                        Console.WriteLine ("NamePatcher [input file]    Patches an Assembly and creates a backup of the original file.");
16                }
17
18                static bool TryArgs (string[] args)
19                {
20                        return args.Length == 1 && (File.Exists (args [0]));
21                }
22
23                static bool makeBackup (string input)
24                {
25                        string backupFile_base = input + ".bck";
26                        string backupFile = backupFile_base;
27                        int backupIndex = 0;
28                        while (File.Exists(backupFile)) {
29                                backupFile = backupFile_base + "." + (++backupIndex);
30                                if (backupIndex > 10) {
31                                        return false;
32                                }
33                        }
34                        try {
35                                File.Copy (input, backupFile);
36                        } catch (Exception e) {
37                                Console.WriteLine ("Unable to create backup file : ");
38                                Console.WriteLine (e.ToString ());
39                                return false;
40                        }
41                        return true;
42                }
43
44                static DefaultAssemblyResolver getAssemblyResolver (string path)
45                {
46                        DefaultAssemblyResolver resolver = null;
47                        int lastSlash = path.LastIndexOf ("\\");
48                        if (lastSlash == -1)
49                                lastSlash = path.LastIndexOf ("/");
50                        if (lastSlash != -1) {
51                                string inputPath = path.Substring (0, lastSlash);
52                                resolver = new DefaultAssemblyResolver ();
53                                resolver.AddSearchDirectory (inputPath);
54                        }
55                        return resolver;
56                }
57
58                static void applyManualPatches (ModuleDefinition mainModule)
59                {
60                        foreach (FieldDefinition fd in mainModule.GetType ("World").Fields) {
61                                TypeReference fdType = fd.FieldType;
62                                if (fdType.FullName.Equals ("System.UInt64")) {
63                                        Console.WriteLine ("Renaming world field -> gameTime");
64                                        NameNormalizer.setName (fd, "gameTime");
65                                }
66                        }
67
68                        foreach (FieldDefinition fd in mainModule.GetType ("GameManager").Fields) {
69                                TypeReference fdType = fd.FieldType;
70                                if (fdType.FullName.Equals ("ConnectionManager")) {
71                                        Console.WriteLine ("Renaming and making public GameMananger field -> connectionManager");
72                                        fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
73                                        NameNormalizer.setName (fd, "connectionManager");
74                                }
75                        }
76
77                        foreach (FieldDefinition fd in mainModule.GetType ("ConnectionManager").Fields) {
78                                TypeReference fdType = fd.FieldType;
79                                if (fdType.FullName.Contains ("Dictionary") && fdType.FullName.Contains ("ClientInfo")) {
80                                        Console.WriteLine ("Renaming and making public ConnectionManager field -> connectedClients");
81                                        fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
82                                        NameNormalizer.setName (fd, "connectedClients");
83                                }
84                                if (fdType.FullName.Contains ("Dictionary") && fdType.FullName.Contains ("System.Int32,System.Int32")) {
85                                        Console.WriteLine ("Renaming and making public ConnectionManager field -> mapClientToEntity");
86                                        fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
87                                        NameNormalizer.setName (fd, "mapClientToEntity");
88                                }
89                        }
90
91                        string consoleTypeName = string.Empty;
92                        TypeDefinition typeTelnetServer = mainModule.GetType ("NetTelnetServer");
93                        foreach (FieldDefinition fd in typeTelnetServer.Fields) {
94                                if (NameNormalizer.makeValidName (fd.FieldType.Name) != null) {
95                                        Console.WriteLine ("Renaming console class -> ConsoleSdtd");
96                                        consoleTypeName = fd.FieldType.Name;
97                                        NameNormalizer.setName (fd.FieldType.Resolve (), "ConsoleSdtd");
98                                        NameNormalizer.setName (fd, "console");
99                                }
100                        }
101
102                        if (consoleTypeName.Length > 0) {
103                                TypeDefinition typeConsole = mainModule.GetType (consoleTypeName);
104                                string consoleCommandTypeName = string.Empty;
105                                foreach (FieldDefinition fd in typeConsole.Fields) {
106                                        TypeReference fdType = fd.FieldType;
107                                        if (fdType.FullName.Contains ("Generic.List")) {
108                                                if (fdType.IsGenericInstance) {
109                                                        GenericInstanceType genType = (GenericInstanceType)fdType;
110                                                        TypeReference genRef = genType.GenericArguments [0];
111                                                        if (genRef.Name.Length < 2) {
112                                                                Console.WriteLine ("Renaming console command class -> ConsoleCommand");
113                                                                NameNormalizer.setName (genRef.Resolve (), "ConsoleCommand");
114                                                                NameNormalizer.setName (fd, "commands");
115                                                                consoleCommandTypeName = genRef.Name;
116                                                        }
117                                                }
118                                        }
119                                        if (fdType.FullName.Equals ("GameManager")) {
120                                                Console.WriteLine ("Renaming and making public console field -> gameManager");
121                                                fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
122                                                NameNormalizer.setName (fd, "gameManager");
123                                        }
124                                }
125
126                                if (consoleCommandTypeName.Length > 0) {
127                                        foreach (MethodDefinition md in typeConsole.Methods) {
128                                                if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.Name.Equals (consoleCommandTypeName)) {
129                                                        Console.WriteLine ("Renaming console method -> AddCommand");
130                                                        NameNormalizer.setName (md, "AddCommand");
131                                                }
132                                        }
133
134                                        TypeDefinition typeConsoleCommand = mainModule.GetType (consoleCommandTypeName);
135                                        foreach (MethodDefinition md in typeConsoleCommand.Methods) {
136                                                if (!md.IsConstructor) {
137                                                        if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.Name.Equals (consoleTypeName)) {
138                                                                Console.WriteLine ("Renaming console command method -> Help");
139                                                                NameNormalizer.setName (md, "Help");
140                                                        }
141                                                        if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("Int32")) {
142                                                                Console.WriteLine ("Renaming console command method -> Timeout");
143                                                                NameNormalizer.setName (md, "Timeout");
144                                                        }
145                                                        if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("String[]")) {
146                                                                Console.WriteLine ("Renaming console command method -> Names");
147                                                                NameNormalizer.setName (md, "Names");
148                                                        }
149                                                        if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("String")) {
150                                                                Console.WriteLine ("Renaming console command method -> Description");
151                                                                NameNormalizer.setName (md, "Description");
152                                                        }
153                                                        if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.IsArray) {
154                                                                Console.WriteLine ("Renaming console command method -> Run");
155                                                                NameNormalizer.setName (md, "Run");
156                                                        }
157                                                }
158                                        }
159                                }
160                        }
161                }
162
163                static void Main (string[] args)
164                {
165                        Console.WriteLine ("NamePatcher for 7dtd's Assembly-CSharp.dll [by DerPopo, modified by Alloc] for Dedi build 320404");
166                        if (!TryArgs (args)) {
167                                DrawUsage ();
168                                return;
169                        }
170                        string dllPath = args [0];
171
172                        if (!makeBackup (dllPath)) {
173                                Console.WriteLine ("Could not create a backup file (maybe too many old backups?)");
174                                return;
175                        }
176
177
178                        AssemblyDefinition input;
179                        try {
180                                input = AssemblyDefinition.ReadAssembly (dllPath, new ReaderParameters { AssemblyResolver = getAssemblyResolver(dllPath), });
181                        } catch (Exception e) {
182                                Console.WriteLine ("Unable to load the input file : ");
183                                Console.WriteLine (e.ToString ());
184                                return;
185                        }
186                        Console.WriteLine ();
187                        Console.WriteLine ("Patching assembly " + dllPath + " (" + input.Modules.Count + " module[s]) ...");
188
189
190
191                        applyManualPatches (input.MainModule);
192
193
194                        try {
195                                foreach (ModuleDefinition mdef in input.Modules) {
196                                        Console.WriteLine ("Patching module " + mdef.Name + " (" + mdef.Types.Count + " type[s]) ...");
197                                        foreach (TypeDefinition tdef in mdef.Types) {
198                                                NameNormalizer.CheckNames (tdef);
199                                        }
200                                }
201                        } catch (Exception e) {
202                                Console.WriteLine ();
203                                Console.WriteLine ("Unable to patch the assembly : ");
204                                Console.WriteLine (e.ToString ());
205                                return;
206                        }
207                        Console.WriteLine ("Finalizing patches...");
208
209                        try {
210                                NameNormalizer.FinalizeNormalizing ();
211                        } catch (Exception e) {
212                                Console.WriteLine ();
213                                Console.WriteLine ("Unable to finalize patching : ");
214                                Console.WriteLine (e.ToString ());
215                                return;
216                        }
217                        NameNormalizer.clnamestomod.Clear ();
218                        NameNormalizer.vclasses.Clear ();
219                        Console.WriteLine ("Saving the patched assembly ...");
220
221                        try {
222                                input.Write (dllPath);
223                        } catch (Exception e) {
224                                Console.WriteLine ();
225                                Console.WriteLine ("Unable to save the assembly : ");
226                                Console.WriteLine (e.ToString ());
227                                return;
228                        }
229
230                        Console.WriteLine ();
231                        Console.WriteLine ("Success.");
232                }
233        }
234}
Note: See TracBrowser for help on using the repository browser.