ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/RomCheater/trunk/RomCheater.PluginFramework/Core/PluginLoader.cs
Revision: 889
Committed: Wed Sep 17 04:55:52 2014 UTC (8 years, 8 months ago) by william
File size: 26433 byte(s)
Log Message:

File Contents

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