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

Last change on this file since 84 was 84, checked in by alloc, 6 years ago

fixes

File size: 8.9 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 ("AdminTools").Fields) {
61                                TypeReference fdType = fd.FieldType;
62                                if (fdType.FullName.Contains ("List") && fdType.FullName.Contains ("AdminToolsCommandPermissions")) {
63                                        Console.WriteLine ("Renaming and making public admin tools field -> commandPermissions");
64                                        fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
65                                        NameNormalizer.setName (fd, "commandPermissions");
66                                }
67                        }
68
69                        foreach (FieldDefinition fd in mainModule.GetType ("World").Fields) {
70                                TypeReference fdType = fd.FieldType;
71                                if (fdType.FullName.Equals ("System.UInt64")) {
72                                        Console.WriteLine ("Renaming world field -> gameTime");
73                                        NameNormalizer.setName (fd, "gameTime");
74                                }
75                        }
76
77                        foreach (FieldDefinition fd in mainModule.GetType ("GameManager").Fields) {
78                                TypeReference fdType = fd.FieldType;
79                                if (fdType.FullName.Equals ("ConnectionManager")) {
80                                        Console.WriteLine ("Renaming and making public GameMananger field -> connectionManager");
81                                        fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
82                                        NameNormalizer.setName (fd, "connectionManager");
83                                }
84                        }
85
86                        foreach (FieldDefinition fd in mainModule.GetType ("ConnectionManager").Fields) {
87                                TypeReference fdType = fd.FieldType;
88                                if (fdType.FullName.Contains ("Dictionary") && fdType.FullName.Contains ("ClientInfo")) {
89                                        Console.WriteLine ("Renaming and making public ConnectionManager field -> connectedClients");
90                                        fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
91                                        NameNormalizer.setName (fd, "connectedClients");
92                                }
93                                if (fdType.FullName.Contains ("Dictionary") && fdType.FullName.Contains ("System.Int32,System.Int32")) {
94                                        Console.WriteLine ("Renaming and making public ConnectionManager field -> mapClientToEntity");
95                                        fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
96                                        NameNormalizer.setName (fd, "mapClientToEntity");
97                                }
98                        }
99
100                        string consoleTypeName = string.Empty;
101                        TypeDefinition typeTelnetServer = mainModule.GetType ("NetTelnetServer");
102                        foreach (FieldDefinition fd in typeTelnetServer.Fields) {
103                                if (NameNormalizer.makeValidName (fd.FieldType.Name) != null) {
104                                        Console.WriteLine ("Renaming console class -> ConsoleSdtd");
105                                        consoleTypeName = fd.FieldType.Name;
106                                        NameNormalizer.setName (fd.FieldType.Resolve (), "ConsoleSdtd");
107                                        NameNormalizer.setName (fd, "console");
108                                }
109                        }
110
111                        if (consoleTypeName.Length > 0) {
112                                TypeDefinition typeConsole = mainModule.GetType (consoleTypeName);
113                                string consoleCommandTypeName = string.Empty;
114                                foreach (MethodDefinition md in typeConsole.Methods) {
115                                        if (!md.IsConstructor) {
116                                                if (md.Parameters.Count == 3 && md.Parameters [0].ParameterType.Name.Equals ("NetworkPlayer")) {
117                                                        Console.WriteLine ("Renaming console method -> ExecuteCmdFromClient");
118                                                        NameNormalizer.setName (md, "ExecuteCmdFromClient");
119                                                }
120                                        }
121                                }
122                                foreach (FieldDefinition fd in typeConsole.Fields) {
123                                        TypeReference fdType = fd.FieldType;
124                                        if (fdType.FullName.Contains ("Generic.List")) {
125                                                if (fdType.IsGenericInstance) {
126                                                        GenericInstanceType genType = (GenericInstanceType)fdType;
127                                                        TypeReference genRef = genType.GenericArguments [0];
128                                                        if (genRef.Name.Length < 2) {
129                                                                Console.WriteLine ("Renaming console command class -> ConsoleCommand");
130                                                                NameNormalizer.setName (genRef.Resolve (), "ConsoleCommand");
131                                                                NameNormalizer.setName (fd, "commands");
132                                                                consoleCommandTypeName = genRef.Name;
133                                                        }
134                                                }
135                                        }
136                                        if (fdType.FullName.Equals ("GameManager")) {
137                                                Console.WriteLine ("Renaming and making public console field -> gameManager");
138                                                fd.Attributes = fd.Attributes & (~Mono.Cecil.FieldAttributes.Private) | Mono.Cecil.FieldAttributes.Public;
139                                                NameNormalizer.setName (fd, "gameManager");
140                                        }
141                                }
142
143                                if (consoleCommandTypeName.Length > 0) {
144                                        foreach (MethodDefinition md in typeConsole.Methods) {
145                                                if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.Name.Equals (consoleCommandTypeName)) {
146                                                        Console.WriteLine ("Renaming console method -> AddCommand");
147                                                        NameNormalizer.setName (md, "AddCommand");
148                                                }
149                                        }
150
151                                        TypeDefinition typeConsoleCommand = mainModule.GetType (consoleCommandTypeName);
152                                        foreach (MethodDefinition md in typeConsoleCommand.Methods) {
153                                                if (!md.IsConstructor) {
154                                                        if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.Name.Equals (consoleTypeName)) {
155                                                                Console.WriteLine ("Renaming console command method -> Help");
156                                                                NameNormalizer.setName (md, "Help");
157                                                        }
158                                                        if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("Int32")) {
159                                                                Console.WriteLine ("Renaming console command method -> Timeout");
160                                                                NameNormalizer.setName (md, "Timeout");
161                                                        }
162                                                        if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("String[]")) {
163                                                                Console.WriteLine ("Renaming console command method -> Names");
164                                                                NameNormalizer.setName (md, "Names");
165                                                        }
166                                                        if (md.Parameters.Count == 0 && md.ReturnType.Name.Equals ("String")) {
167                                                                Console.WriteLine ("Renaming console command method -> Description");
168                                                                NameNormalizer.setName (md, "Description");
169                                                        }
170                                                        if (md.Parameters.Count == 1 && md.Parameters [0].ParameterType.IsArray) {
171                                                                Console.WriteLine ("Renaming console command method -> Run");
172                                                                NameNormalizer.setName (md, "Run");
173                                                        }
174                                                }
175                                        }
176                                }
177                        }
178                }
179
180                static void Main (string[] args)
181                {
182                        Console.WriteLine ("NamePatcher for 7dtd's Assembly-CSharp.dll [by DerPopo, modified by Alloc] for Dedi build 320404");
183                        if (!TryArgs (args)) {
184                                DrawUsage ();
185                                return;
186                        }
187                        string dllPath = args [0];
188
189                        if (!makeBackup (dllPath)) {
190                                Console.WriteLine ("Could not create a backup file (maybe too many old backups?)");
191                                return;
192                        }
193
194
195                        AssemblyDefinition input;
196                        try {
197                                input = AssemblyDefinition.ReadAssembly (dllPath, new ReaderParameters { AssemblyResolver = getAssemblyResolver(dllPath), });
198                        } catch (Exception e) {
199                                Console.WriteLine ("Unable to load the input file : ");
200                                Console.WriteLine (e.ToString ());
201                                return;
202                        }
203                        Console.WriteLine ();
204                        Console.WriteLine ("Patching assembly " + dllPath + " (" + input.Modules.Count + " module[s]) ...");
205
206
207
208                        applyManualPatches (input.MainModule);
209
210
211                        try {
212                                foreach (ModuleDefinition mdef in input.Modules) {
213                                        Console.WriteLine ("Patching module " + mdef.Name + " (" + mdef.Types.Count + " type[s]) ...");
214                                        foreach (TypeDefinition tdef in mdef.Types) {
215                                                NameNormalizer.CheckNames (tdef);
216                                        }
217                                }
218                        } catch (Exception e) {
219                                Console.WriteLine ();
220                                Console.WriteLine ("Unable to patch the assembly : ");
221                                Console.WriteLine (e.ToString ());
222                                return;
223                        }
224                        Console.WriteLine ("Finalizing patches...");
225
226                        try {
227                                NameNormalizer.FinalizeNormalizing ();
228                        } catch (Exception e) {
229                                Console.WriteLine ();
230                                Console.WriteLine ("Unable to finalize patching : ");
231                                Console.WriteLine (e.ToString ());
232                                return;
233                        }
234                        NameNormalizer.clnamestomod.Clear ();
235                        NameNormalizer.vclasses.Clear ();
236                        Console.WriteLine ("Saving the patched assembly ...");
237
238                        try {
239                                input.Write (dllPath);
240                        } catch (Exception e) {
241                                Console.WriteLine ();
242                                Console.WriteLine ("Unable to save the assembly : ");
243                                Console.WriteLine (e.ToString ());
244                                return;
245                        }
246
247                        Console.WriteLine ();
248                        Console.WriteLine ("Success.");
249                }
250        }
251}
Note: See TracBrowser for help on using the repository browser.