/[RomCheater]/trunk/RomCheater.PluginFramework/Core/PluginLoader.cs
ViewVC logotype

Contents of /trunk/RomCheater.PluginFramework/Core/PluginLoader.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 711 - (show annotations) (download)
Tue Jun 18 08:36:08 2013 UTC (7 years, 3 months ago) by william
File size: 26438 byte(s)
+ add ability to find a plugin by guid or name
** will be adding (in next commit) a static class that can get the value(s) like an enum of plugins

1 #region Logging Defines
2 // include this any class or method that required logging, and comment-out what is not needed
3
4 #region Enabled logging levels
5 #define LOGGING_ENABLE_INFO
6 #define LOGGING_ENABLE_WARN
7 #define LOGGING_ENABLE_DEBUG
8 #define LOGGING_ENABLE_VERBOSEDEBUG
9 #define LOGGING_ENABLE_ERROR
10 #define LOGGING_ENABLE_VERBOSEERROR
11 #define LOGGING_ENABLE_PROFILER
12 #endregion
13 #endregion
14 using System;
15 using System.Collections.Generic;
16 using System.Linq;
17 using System.Text;
18 using RomCheater.Logging;
19 using System.IO;
20 using System.Reflection;
21 using RomCheater.Core;
22 using System.Runtime.Serialization;
23 using System.Security;
24
25 namespace RomCheater.PluginFramework.Core
26 {
27 #region plugin loader execeptions
28 public class PluginNotFoundException : System.Exception
29 {
30 public PluginNotFoundException() : base() { }
31 public PluginNotFoundException(string message) : base(message) { }
32 public PluginNotFoundException(string message, Exception innerException) : base(message, innerException) { }
33 [SecuritySafeCritical]
34 protected PluginNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { }
35 }
36 public class InvalidPluginException : System.Exception
37 {
38 public InvalidPluginException() : base() { }
39 public InvalidPluginException(string message) : base(message) { }
40 public InvalidPluginException(string message, Exception innerException) : base(message, innerException) { }
41 [SecuritySafeCritical]
42 protected InvalidPluginException(SerializationInfo info, StreamingContext context) : base(info, context) { }
43 }
44 public class InvalidPluginTypeException : System.Exception
45 {
46 public InvalidPluginTypeException() : base() { }
47 public InvalidPluginTypeException(string message) : base(message) { }
48 public InvalidPluginTypeException(string message, Exception innerException) : base(message, innerException) { }
49 [SecuritySafeCritical]
50 protected InvalidPluginTypeException(SerializationInfo info, StreamingContext context) : base(info, context) { }
51 }
52 #endregion
53
54 public class PluginLoader : IPluginLoader
55 {
56
57 public PluginLoader()
58 {
59 LoadedConfigPlugins = new List<IConfigPlugin>();
60 LoadedInputPlugins = new List<IInputPlugin>();
61 LoadedWindowPlugins = new List<IWindowPlugin>();
62 LoadedUserControlPlugins = new List<IUserControlPlugin>();
63 }
64 #region IPluginLoader Members
65
66 public T GetPluginByName<T>(string name) where T : IPluginBase
67 {
68 T plugin = default(T);
69 if (string.IsNullOrEmpty(name))
70 {
71 throw new ArgumentException("name cannot be null or an empty string", "name");
72 }
73
74 bool known = IsKnownPluginName<T>(name, out plugin);
75 if (known)
76 {
77 if (plugin != null)
78 {
79 return plugin;
80 }
81 else
82 {
83 throw new InvalidPluginException(string.Format("Plugin name: '{0}' is known, but the returned plugin was null", name));
84 }
85 }
86 else
87 {
88 if (LoadedConfigPlugins.Count > 0)
89 {
90 foreach (var p in LoadedConfigPlugins)
91 {
92 if (p.Name.ToLower() == name.ToLower())
93 {
94 plugin = (T)p;
95 known = true;
96 break;
97 }
98 }
99 }
100 if (LoadedInputPlugins.Count > 0)
101 {
102 foreach (var p in LoadedInputPlugins)
103 {
104 if (p.Name.ToLower() == name.ToLower())
105 {
106 plugin = (T)p;
107 known = true;
108 break;
109 }
110 }
111 }
112 if (LoadedWindowPlugins.Count > 0)
113 {
114 foreach (var p in LoadedWindowPlugins)
115 {
116 if (p.Name.ToLower() == name.ToLower())
117 {
118 plugin = (T)p;
119 known = true;
120 break;
121 }
122 }
123 }
124 if (LoadedUserControlPlugins.Count > 0)
125 {
126 foreach (var p in LoadedUserControlPlugins)
127 {
128 if (p.Name.ToLower() == name.ToLower())
129 {
130 plugin = (T)p;
131 known = true;
132 break;
133 }
134 }
135 }
136 if (known)
137 {
138 return plugin;
139 }
140 else
141 {
142 throw new PluginNotFoundException(string.Format("Could not find a plugin with name: '{0}'", name));
143 }
144 }
145 }
146 public T GetPluginByGuid<T>(string plugin_guid) where T : IPluginBase
147 {
148 T plugin = default(T);
149
150 if (string.IsNullOrEmpty(plugin_guid))
151 {
152 throw new ArgumentException("plugin_plugin cannot be null or an empty string", "plugin_guid");
153 }
154
155 bool known = IsKnownPluginGuid<T>(plugin_guid, out plugin);
156 if (known)
157 {
158 if (plugin != null)
159 {
160 return plugin;
161 }
162 else
163 {
164 throw new InvalidPluginException(string.Format("Plugin guid: '{0}' is known, but the returned plugin was null", plugin_guid));
165 }
166 }
167 else
168 {
169 if (LoadedConfigPlugins.Count > 0)
170 {
171 foreach (var p in LoadedConfigPlugins)
172 {
173 if (p.ID == new Guid(plugin_guid))
174 {
175 plugin = (T)p;
176 known = true;
177 break;
178 }
179 }
180 }
181 if (LoadedInputPlugins.Count > 0)
182 {
183 foreach (var p in LoadedInputPlugins)
184 {
185 if (p.ID == new Guid(plugin_guid))
186 {
187 plugin = (T)p;
188 known = true;
189 break;
190 }
191 }
192 }
193 if (LoadedWindowPlugins.Count > 0)
194 {
195 foreach (var p in LoadedWindowPlugins)
196 {
197 if (p.ID == new Guid(plugin_guid))
198 {
199 plugin = (T)p;
200 known = true;
201 break;
202 }
203 }
204 }
205 if (LoadedUserControlPlugins.Count > 0)
206 {
207 foreach (var p in LoadedUserControlPlugins)
208 {
209 if (p.ID == new Guid(plugin_guid))
210 {
211 plugin = (T)p;
212 known = true;
213 break;
214 }
215 }
216 }
217 }
218 if (known)
219 {
220 return plugin;
221 }
222 else
223 {
224 throw new PluginNotFoundException(string.Format("Could not find a plugin with guid: '{0}'", plugin_guid));
225 }
226 }
227 public string[] GetKnownPluginGuids<T>() where T : IPluginBase
228 {
229 Type t = typeof(T);
230 string name = t.Name.ToLower();
231
232 List<string> guids = new List<string>();
233 guids.Add(new Guid().ToString().ToLower()); // add null guids
234 switch (name)
235 {
236 case "iconfigplugin":
237 guids.Add(new Guid("478e225b-c3e8-9280-57ca-384b884fc4cc").ToString().ToLower()); // generic config
238 break;
239 case "iinputplugin":
240 // no known plugins (other than null at this time)
241 break;
242 case "iwindowplugin":
243 // no known plugins (other than null at this time)
244 break;
245 case "iusercontrolplugin":
246 guids.RemoveAt(0); // userplugins should not have a null plugin guid
247 guids.Add(new Guid("09d0c77b-e0d1-47ca-907e-997d19f2c8c2").ToString().ToLower()); // cheat code converter plugin
248 guids.Add(new Guid("7b0b9c38-8774-491a-8d9b-3255eddf1407").ToString().ToLower()); // emulator memory map plugin
249 guids.Add(new Guid("bbd24cd2-5ab0-470c-9e32-6a9458025855").ToString().ToLower()); // rva calculator plugin
250 guids.Add(new Guid("de686ea8-3f5f-479b-b742-5b13d93cb579").ToString().ToLower()); // scrathpad plugin
251 break;
252 default:
253 throw new InvalidPluginTypeException(string.Format("'{0}' is not a valid plugin type", t.Name));
254 }
255
256
257 return guids.ToArray();
258 }
259
260 public bool IsKnownPluginName<T>(string plugin_name, out T plugin) where T : IPluginBase
261 {
262 plugin = default(T);
263 bool known = false;
264
265 Type t = typeof(T);
266 string name = t.Name.ToLower();
267 switch (name)
268 {
269 case "iconfigplugin":
270 if (LoadedConfigPlugins.Count > 0)
271 {
272 foreach (var p in LoadedConfigPlugins)
273 {
274 if (p.Name.ToLower() == plugin_name.ToLower())
275 {
276 plugin = (T)p;
277 known = true;
278 break;
279 }
280 }
281 }
282 break;
283 case "iinputplugin":
284 if (LoadedInputPlugins.Count > 0)
285 {
286 foreach (var p in LoadedInputPlugins)
287 {
288 if (p.Name.ToLower() == plugin_name.ToLower())
289 {
290 plugin = (T)p;
291 known = true;
292 break;
293 }
294 }
295 }
296 break;
297 case "iwindowplugin":
298 if (LoadedWindowPlugins.Count > 0)
299 {
300 foreach (var p in LoadedWindowPlugins)
301 {
302 if (p.Name.ToLower() == plugin_name.ToLower())
303 {
304 plugin = (T)p;
305 known = true;
306 break;
307 }
308 }
309 }
310 break;
311 case "iusercontrolplugin":
312 if (LoadedUserControlPlugins.Count > 0)
313 {
314 foreach (var p in LoadedUserControlPlugins)
315 {
316 if (p.Name.ToLower() == plugin_name.ToLower())
317 {
318 plugin = (T)p;
319 known = true;
320 break;
321 }
322 }
323 }
324 break;
325 default:
326 throw new InvalidPluginTypeException(string.Format("'{0}' is not a valid plugin type", t.Name));
327 }
328
329
330 return known;
331 }
332 public bool IsKnownPluginGuid<T>(string plugin_guid, out T plugin) where T : IPluginBase
333 {
334 plugin = default(T);
335 bool known = false;
336 var guids = GetKnownPluginGuids<T>();
337 known = guids.ToList().Contains(plugin_guid.ToLower());
338
339 if (known)
340 {
341 Type t = typeof(T);
342 string name = t.Name.ToLower();
343 switch (name)
344 {
345 case "iconfigplugin":
346 if (LoadedConfigPlugins.Count > 0)
347 {
348 foreach (var p in LoadedConfigPlugins)
349 {
350 if (p.ID == new Guid(plugin_guid))
351 {
352 plugin = (T)p;
353 break;
354 }
355 }
356 }
357 break;
358 case "iinputplugin":
359 if (LoadedInputPlugins.Count > 0)
360 {
361 foreach (var p in LoadedInputPlugins)
362 {
363 if (p.ID == new Guid(plugin_guid))
364 {
365 plugin = (T)p;
366 break;
367 }
368 }
369 }
370 break;
371 case "iwindowplugin":
372 if (LoadedWindowPlugins.Count > 0)
373 {
374 foreach (var p in LoadedWindowPlugins)
375 {
376 if (p.ID == new Guid(plugin_guid))
377 {
378 plugin = (T)p;
379 break;
380 }
381 }
382 }
383 break;
384 case "iusercontrolplugin":
385 if (LoadedUserControlPlugins.Count > 0)
386 {
387 foreach (var p in LoadedUserControlPlugins)
388 {
389 if (p.ID == new Guid(plugin_guid))
390 {
391 plugin = (T)p;
392 break;
393 }
394 }
395 }
396 break;
397 default:
398 throw new InvalidPluginTypeException(string.Format("'{0}' is not a valid plugin type", t.Name));
399 }
400 }
401
402 return known;
403 }
404
405 public void LoadPlugins() { LoadPlugins(false); }
406 public void LoadPlugins(bool silent)
407 {
408 try
409 {
410 if (!silent)
411 logger.Info.WriteLine("Loading Plugins...");
412
413 string PluginPath = string.Format(@"{0}\Plugins", typeof(PluginLoader).Assembly.Location.Replace(@"\RomCheater.PluginFramework.dll", ""));
414 if (!silent)
415 logger.Debug.WriteLine("Plugins Path: {0}", PluginPath);
416 List<string> dlls = new List<string>(Directory.GetFiles(PluginPath, "*.dll"));
417 // also load any default plugins from the framework
418 dlls.Add(typeof(PluginLoader).Assembly.Location);
419
420 if (!silent)
421 logger.Debug.WriteLine(" Found: {0} plugin dlls", dlls.Count);
422 foreach (string dll in dlls)
423 {
424 FileInfo fi = new FileInfo(dll);
425 if (!silent)
426 logger.Debug.WriteLine(" plugin[{0}]: {1}", dlls.IndexOf(dll), fi.Name);
427 GetConfigPluginsFromDll(fi);
428 GetInputPluginsFromDll(fi);
429 GetWindowPluginsFromDll(fi);
430 GetUserControlPluginsFromDll(fi);
431 }
432
433
434
435 if (!silent)
436 logger.Info.WriteLine(" Loaded {0} config plugins", LoadedConfigPlugins.Count);
437 if (!silent)
438 logger.Info.WriteLine(" Loaded {0} input plugins", LoadedInputPlugins.Count);
439 if (!silent)
440 logger.Info.WriteLine(" Loaded {0} window plugins", LoadedWindowPlugins.Count);
441 if (!silent)
442 logger.Info.WriteLine(" Loaded {0} usercontrol plugins", LoadedUserControlPlugins.Count);
443 if (!silent)
444 logger.Info.WriteLine("Plugins Loaded.");
445 }
446 catch (ReflectionTypeLoadException ex)
447 {
448 StringBuilder builder = new StringBuilder();
449 if (ex.LoaderExceptions.Count() > 0)
450 {
451 foreach (Exception c in ex.LoaderExceptions)
452 {
453 builder.AppendLine(c.ToString());
454 }
455 }
456 if (!silent)
457 logger.Error.WriteLine("Failed to load one or more plugins{0}Possible Reason:{0}{1}", System.Environment.NewLine, builder.ToString());
458 }
459 catch (Exception ex)
460 {
461 if (!silent)
462 logger.Error.WriteLine("Failed to load one or more plugins{0}Possible Reason:{0}{1}", System.Environment.NewLine, ex.ToString());
463 }
464 }
465 public List<IConfigPlugin> LoadedConfigPlugins { get; private set; }
466 public List<IInputPlugin> LoadedInputPlugins { get; private set; }
467 public List<IWindowPlugin> LoadedWindowPlugins { get; private set; }
468 public List<IUserControlPlugin> LoadedUserControlPlugins { get; private set; }
469
470 public IConfigPlugin GetConfigPlugin(string t)
471 {
472 foreach (IConfigPlugin c in LoadedConfigPlugins) { if (c.ToString().ToLower() == t.ToLower()) { return c; } }
473 return GetGenericConfigPlugin();
474 }
475 public IConfigPlugin GetGenericConfigPlugin()
476 {
477 foreach (IConfigPlugin c in LoadedConfigPlugins) { if (c.IsGenericPlugin || c.IsNullPlugin) { return c; } }
478 return null;
479 }
480 public IInputPlugin GetInputPlugin(string t)
481 {
482 foreach (IInputPlugin c in LoadedInputPlugins) { if (c.ToString().ToLower() == t.ToLower()) { return c; } }
483 return GetGenericInputPlugin();
484 }
485 public IInputPlugin GetGenericInputPlugin()
486 {
487 foreach (IInputPlugin c in LoadedInputPlugins) { if (c.IsGenericPlugin || c.IsNullPlugin) { return c; } }
488 return null;
489 }
490 public IWindowPlugin GetWindowPlugin(string t)
491 {
492 foreach (IWindowPlugin c in LoadedWindowPlugins) { if (c.ToString().ToLower() == t.ToLower()) { return c; } }
493 return GetGenericWindowPlugin();
494 }
495 public IWindowPlugin GetGenericWindowPlugin()
496 {
497 foreach (IWindowPlugin c in LoadedWindowPlugins) { if (c.IsGenericPlugin || c.IsNullPlugin) { return c; } }
498 return null;
499 }
500 public IUserControlPlugin GetUserControlPlugin()
501 {
502 foreach (IUserControlPlugin c in LoadedUserControlPlugins) { if (c.IsGenericPlugin || c.IsNullPlugin) { return c; } }
503 return null;
504 }
505 #endregion
506
507 private void GetConfigPluginsFromDll(FileInfo dll)
508 {
509 logger.Debug.WriteLine(" Getting Config plugins contained in {0}", dll.Name);
510 Assembly asm = Assembly.LoadFile(dll.FullName);
511 List<Type> types = new List<Type>(asm.GetTypes());
512 foreach (Type type in types)
513 {
514 if (type.BaseType == typeof(ConfigPlugin))
515 {
516 ConstructorInfo ci = null;
517 ci = type.GetConstructor(new Type[] { });
518 if (ci == null)
519 {
520 throw new NullReferenceException(string.Format("Unable to bind to constructor for type: {0}", type.Name));
521 }
522 else
523 {
524 object o = ci.Invoke(new object[] { });
525 IConfigPlugin c = (IConfigPlugin)o;
526 if (c == null)
527 {
528 throw new NullReferenceException(string.Format("Failed to cast type {0} to IConfigPlugin", type.Name));
529 }
530 else
531 {
532 logger.Debug.WriteLine(" Loaded Config Plugin [name={0}] from {1}", c.Name, dll.Name);
533 LoadedConfigPlugins.Add(c);
534 }
535 }
536 }
537 }
538 }
539 private void GetInputPluginsFromDll(FileInfo dll)
540 {
541 logger.Debug.WriteLine(" Getting Input plugins contained in {0}", dll.Name);
542 Assembly asm = Assembly.LoadFile(dll.FullName);
543 List<Type> types = new List<Type>(asm.GetTypes());
544 foreach (Type type in types)
545 {
546 if (type.BaseType == typeof(InputPlugin))
547 {
548 ConstructorInfo ci = null;
549 ci = type.GetConstructor(new Type[] { });
550 if (ci == null)
551 {
552 throw new NullReferenceException(string.Format("Unable to bind to constructor for type: {0}", type.Name));
553 }
554 else
555 {
556 object o = ci.Invoke(new object[] { });
557 IInputPlugin c = (IInputPlugin)o;
558 if (c == null)
559 {
560 throw new NullReferenceException(string.Format("Failed to cast type {0} to IConfigPlugin", type.Name));
561 }
562 else
563 {
564 logger.Debug.WriteLine(" Loaded Input Plugin [name={0}] from {1}", c.Name, dll.Name);
565 LoadedInputPlugins.Add(c);
566 }
567 }
568 }
569 }
570 }
571 private void GetWindowPluginsFromDll(FileInfo dll)
572 {
573 logger.Debug.WriteLine(" Getting Window plugins contained in {0}", dll.Name);
574 Assembly asm = Assembly.LoadFile(dll.FullName);
575 List<Type> types = new List<Type>(asm.GetTypes());
576 foreach (Type type in types)
577 {
578 if (type.BaseType == typeof(WindowPlugin))
579 {
580 ConstructorInfo ci = null;
581 ci = type.GetConstructor(new Type[] { });
582 if (ci == null)
583 {
584 throw new NullReferenceException(string.Format("Unable to bind to constructor for type: {0}", type.Name));
585 }
586 else
587 {
588 object o = ci.Invoke(new object[] { });
589 IWindowPlugin c = (IWindowPlugin)o;
590 if (c == null)
591 {
592 throw new NullReferenceException(string.Format("Failed to cast type {0} to IConfigPlugin", type.Name));
593 }
594 else
595 {
596 logger.Debug.WriteLine(" Loaded Window Plugin [name={0}] from {1}", c.Name, dll.Name);
597 LoadedWindowPlugins.Add(c);
598 }
599 }
600 }
601 }
602 }
603 private void GetUserControlPluginsFromDll(FileInfo dll)
604 {
605 logger.Debug.WriteLine(" Getting UserControl plugins contained in {0}", dll.Name);
606 Assembly asm = Assembly.LoadFile(dll.FullName);
607 List<Type> types = new List<Type>(asm.GetTypes());
608 foreach (Type type in types)
609 {
610 if (type.BaseType == typeof(UserControlPlugin))
611 {
612 ConstructorInfo ci = null;
613 ci = type.GetConstructor(new Type[] { });
614 if (ci == null)
615 {
616 throw new NullReferenceException(string.Format("Unable to bind to constructor for type: {0}", type.Name));
617 }
618 else
619 {
620 object o = ci.Invoke(new object[] { });
621 IUserControlPlugin c = (IUserControlPlugin)o;
622 if (c == null)
623 {
624 throw new NullReferenceException(string.Format("Failed to cast type {0} to IConfigPlugin", type.Name));
625 }
626 else
627 {
628 logger.Debug.WriteLine(" Loaded UserControl Plugin [name={0}] from {1}", c.Name, dll.Name);
629 LoadedUserControlPlugins.Add(c);
630 }
631 }
632 }
633 }
634 }
635 }
636 }

  ViewVC Help
Powered by ViewVC 1.1.22