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

Last change on this file since 104 was 104, checked in by alloc, 10 years ago

fixes

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