1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Linq ;
5+ using System . Reflection ;
6+ using I2 . Loc ;
7+ using Newtonsoft . Json ;
8+ using NSMedieval . Enums ;
9+
10+
11+ namespace GoingMedievalModLauncher
12+ {
13+
14+ /// <summary>
15+ /// A class that contains a plugin.
16+ /// TODO: the static tags (Name description) should be separated from code?
17+ /// </summary>
18+ public class PluginContainer
19+ {
20+
21+ /// <summary>
22+ /// the mod's folder
23+ /// </summary>
24+ private readonly DirectoryInfo _path ;
25+ /// <summary>
26+ /// The contained plugin
27+ /// </summary>
28+ public readonly IPlugin plugin ;
29+
30+ public string Name => plugin . Name ;
31+
32+ /// <summary>
33+ /// A alphanumeric string which describes the functionality of the contained plugin / mod.
34+ /// </summary>
35+ public string Description => plugin . Description ;
36+
37+ /// <summary>
38+ /// A alphanumeric string which describes the version of the contained plugin / mod.
39+ /// </summary>
40+ public string Version => plugin . Version ;
41+
42+ /// <summary>
43+ /// a boolean variable which indicates that the contained mod is active or not
44+ /// </summary>
45+ public bool activeState {
46+ get => plugin . activeState ;
47+ set => plugin . activeState = value ;
48+
49+ }
50+
51+ protected PluginContainer ( DirectoryInfo path , IPlugin plugin )
52+ {
53+ _path = path ;
54+ this . plugin = plugin ;
55+ }
56+
57+ public bool loadLanguageFile ( )
58+ {
59+ Logger . Instance . info ( "Loading language file for: " + Name ) ;
60+ FileInfo langFile = null ;
61+ foreach ( var file in _path . EnumerateFiles ( "*.json" ) )
62+ {
63+ if ( file . Name == "lang.json" && file . Length != 0 )
64+ {
65+ langFile = file ;
66+ }
67+ }
68+
69+ if ( langFile == null )
70+ {
71+ //No language file was found.
72+ Logger . Instance . info ( "No langugae file was found for: " + Name ) ;
73+ return true ;
74+ }
75+
76+ var data = ( Dictionary < string , Dictionary < string , string > > ) JsonConvert . DeserializeObject (
77+ langFile . OpenText ( ) . ReadToEnd ( ) ,
78+ typeof ( Dictionary < string , Dictionary < string , string > > ) ) ;
79+
80+ var source = LocalizationManager . Sources [ 0 ] ;
81+
82+ foreach ( var node in data )
83+ {
84+ foreach ( var translation in node . Value )
85+ {
86+ var id = source . GetLanguageIndex ( translation . Key ) ;
87+ var term = source . AddTerm ( node . Key ) ;
88+ term . SetTranslation ( id , translation . Value ) ;
89+ }
90+ }
91+
92+ source . UpdateDictionary ( ) ;
93+
94+ return true ;
95+
96+ }
97+
98+ public static PluginContainer Create ( DirectoryInfo dir )
99+ {
100+ Logger . Instance . info ( "Creating plugin container for: " + dir . Name ) ;
101+
102+ // load all the assemblies from the directory
103+ ICollection < Assembly > assemblies = new List < Assembly > ( ) ;
104+ foreach ( FileInfo dllFile in dir . GetFiles ( "*.dll" ) )
105+ {
106+ Logger . Instance . info ( "Found dll: " + dllFile + " ..." ) ;
107+ AssemblyName an = AssemblyName . GetAssemblyName ( dllFile . FullName ) ;
108+ Assembly assembly = Assembly . Load ( an ) ;
109+ assemblies . Add ( assembly ) ;
110+ }
111+
112+ // Check if the assembly is valid (we don't want to load any dll within the mods-directory
113+ Type pluginType = typeof ( IPlugin ) ;
114+ List < Type > validPlugins = new List < Type > ( ) ;
115+ foreach ( Assembly assembly in assemblies )
116+ {
117+ if ( assembly != null )
118+ {
119+ Type [ ] types = assembly . GetTypes ( ) ;
120+ foreach ( Type type in types )
121+ {
122+ if ( type . IsInterface || type . IsAbstract )
123+ {
124+ continue ;
125+ }
126+
127+ if
128+ (
129+ type . GetInterface ( pluginType . FullName ) != null &&
130+ type . GetInterfaces ( ) . Contains ( typeof ( IPlugin ) )
131+ )
132+ {
133+ validPlugins . Add ( type ) ;
134+ }
135+ }
136+ }
137+ }
138+
139+ if ( validPlugins . Count == 0 )
140+ {
141+ Logger . Instance . info ( "No valid plugin were found for this directory." ) ;
142+
143+ return InvalidPluginContainer . Instance ;
144+ }
145+
146+ if ( validPlugins . Count > 2 )
147+ {
148+ Logger . Instance . info ( "More than two plugins were found in this directory!" ) ;
149+
150+ return InvalidPluginContainer . Instance ;
151+ }
152+
153+ //TODO: more erros?
154+
155+ var plugin = ( IPlugin ) Activator . CreateInstance ( validPlugins [ 0 ] ) ;
156+
157+ try
158+ {
159+ plugin . initialize ( ) ;
160+ // TODO: plugin.start(doorstepGameObject);
161+ }
162+ catch ( Exception e )
163+ {
164+ Logger . Instance . info ( "An error happened initalizting a plugin!\n " + e ) ;
165+
166+ return InvalidPluginContainer . Instance ;
167+ }
168+
169+ var container = new PluginContainer ( dir , plugin ) ;
170+
171+ container . loadLanguageFile ( ) ;
172+
173+ return container ;
174+
175+ }
176+ }
177+
178+
179+ /// <summary>
180+ /// An invalid plugins container;
181+ /// </summary>
182+ public class InvalidPluginContainer : PluginContainer
183+ {
184+
185+ public static readonly InvalidPluginContainer Instance = new InvalidPluginContainer ( ) ;
186+
187+ private InvalidPluginContainer ( ) : base ( null , null ) { }
188+
189+ }
190+
191+ }
0 commit comments