@@ -60,73 +60,86 @@ public void LoadMods(Node node)
6060 {
6161 if ( ! dir . CurrentIsDir ( ) )
6262 {
63- goto Next ;
63+ filename = dir . GetNext ( ) ;
64+ continue ;
6465 }
6566
66- string modRoot = $@ "{ modsPath } /{ filename } ";
67- string modJson = $@ "{ modRoot } /mod.json";
67+ TryLoadModDirectory ( node , modsPath , filename , options ) ;
68+ filename = dir . GetNext ( ) ;
69+ }
6870
69- if ( ! File . Exists ( modJson ) )
70- {
71- _logger . LogWarning ( $ "The mod folder '{ filename } ' does not have a mod.json so it will not be loaded") ;
72- goto Next ;
73- }
71+ dir . ListDirEnd ( ) ;
72+ dir . Dispose ( ) ;
73+ }
7474
75- string jsonFileContents = File . ReadAllText ( modJson ) ;
75+ private void TryLoadModDirectory ( Node hostNode , string modsPath , string folderName , JsonSerializerOptions options )
76+ {
77+ string modRoot = $@ "{ modsPath } /{ folderName } ";
78+ string modJson = $@ "{ modRoot } /mod.json";
7679
77- jsonFileContents = jsonFileContents . Replace ( "*" , "Any" ) ;
80+ if ( ! File . Exists ( modJson ) )
81+ {
82+ _logger . LogWarning ( $ "The mod folder '{ folderName } ' does not have a mod.json so it will not be loaded") ;
83+ return ;
84+ }
7885
79- if ( ! TryDeserializeModInfo ( modJson , jsonFileContents , options , out ModInfo ? modInfo ) )
80- {
81- goto Next ;
82- }
86+ string jsonFileContents ;
87+ try
88+ {
89+ jsonFileContents = File . ReadAllText ( modJson ) ;
90+ }
91+ catch ( IOException exception )
92+ {
93+ _logger . LogWarning ( $ "Failed to read '{ modJson } ': { exception . Message } ") ;
94+ return ;
95+ }
96+ catch ( UnauthorizedAccessException exception )
97+ {
98+ _logger . LogWarning ( $ "Access denied while reading '{ modJson } ': { exception . Message } ") ;
99+ return ;
100+ }
83101
84- modInfo ! . Normalize ( ) ;
102+ jsonFileContents = jsonFileContents . Replace ( "*" , "Any" ) ;
85103
86- if ( string . IsNullOrWhiteSpace ( modInfo . Id ) )
87- {
88- _logger . LogWarning ( $ "The mod folder '{ filename } ' has an invalid or empty id and will be skipped") ;
89- goto Next ;
90- }
104+ if ( ! TryDeserializeModInfo ( modJson , jsonFileContents , options , out ModInfo ? modInfo ) )
105+ return ;
91106
92- if ( _mods . ContainsKey ( modInfo . Id ) )
93- {
94- _logger . LogWarning ( $ "Duplicate mod id '{ modInfo . Id } ' was skipped") ;
95- goto Next ;
96- }
107+ modInfo ! . Normalize ( ) ;
108+
109+ if ( string . IsNullOrWhiteSpace ( modInfo . Id ) )
110+ {
111+ _logger . LogWarning ( $ "The mod folder '{ folderName } ' has an invalid or empty id and will be skipped") ;
112+ return ;
113+ }
97114
98- _mods . Add ( modInfo . Id , modInfo ) ;
115+ if ( _mods . ContainsKey ( modInfo . Id ) )
116+ {
117+ _logger . LogWarning ( $ "Duplicate mod id '{ modInfo . Id } ' was skipped") ;
118+ return ;
119+ }
99120
100- // Load pck
101- string pckPath = $@ "{ modRoot } /mod.pck";
121+ _mods . Add ( modInfo . Id , modInfo ) ;
102122
103- if ( File . Exists ( pckPath ) )
104- {
105- bool success = ProjectSettings . LoadResourcePack ( pckPath , replaceFiles : false ) ;
123+ string pckPath = $@ "{ modRoot } /mod.pck";
124+ if ( File . Exists ( pckPath ) )
125+ {
126+ bool success = ProjectSettings . LoadResourcePack ( pckPath , replaceFiles : false ) ;
106127
107- if ( ! success )
108- {
109- _logger . LogWarning ( $ "Failed to load pck file for mod '{ modInfo . Name } '") ;
110- }
111- else
112- {
113- TryInstantiateModScene ( node , modInfo ) ;
114- }
128+ if ( ! success )
129+ {
130+ _logger . LogWarning ( $ "Failed to load pck file for mod '{ modInfo . Name } '") ;
115131 }
116-
117- // Load dll
118- string dllPath = $@ "{ modRoot } /Mod.dll";
119- if ( File . Exists ( dllPath ) )
132+ else
120133 {
121- TryLoadManagedMod ( node , modInfo , dllPath ) ;
134+ TryInstantiateModScene ( hostNode , modInfo ) ;
122135 }
123-
124- Next :
125- filename = dir . GetNext ( ) ;
126136 }
127137
128- dir . ListDirEnd ( ) ;
129- dir . Dispose ( ) ;
138+ string dllPath = $@ "{ modRoot } /Mod.dll";
139+ if ( File . Exists ( dllPath ) )
140+ {
141+ TryLoadManagedMod ( hostNode , modInfo , dllPath ) ;
142+ }
130143 }
131144
132145 private bool TryDeserializeModInfo (
@@ -188,6 +201,18 @@ private void TryLoadManagedMod(Node hostNode, ModInfo modInfo, string dllPath)
188201 ManagedModRuntime runtime = new ( loadContext , assembly , entrypoints ) ;
189202 _managedMods . Add ( modInfo . Id , runtime ) ;
190203 }
204+ catch ( FileNotFoundException exception )
205+ {
206+ _logger . LogErr ( exception , $ "Managed mod '{ modInfo . Id } ' assembly was not found") ;
207+ }
208+ catch ( FileLoadException exception )
209+ {
210+ _logger . LogErr ( exception , $ "Managed mod '{ modInfo . Id } ' assembly could not be loaded") ;
211+ }
212+ catch ( BadImageFormatException exception )
213+ {
214+ _logger . LogErr ( exception , $ "Managed mod '{ modInfo . Id } ' assembly is not a valid .NET assembly") ;
215+ }
191216 catch ( Exception exception )
192217 {
193218 _logger . LogErr ( exception , $ "Failed to load managed mod '{ modInfo . Id } '") ;
@@ -213,6 +238,18 @@ private List<IModEntrypoint> ActivateEntrypoints(Node hostNode, ModInfo modInfo,
213238 entrypoints . Add ( entrypoint ) ;
214239 }
215240 }
241+ catch ( MissingMethodException exception )
242+ {
243+ _logger . LogErr ( exception , $ "Entrypoint '{ type . FullName } ' for mod '{ modInfo . Id } ' requires a public parameterless constructor") ;
244+ }
245+ catch ( MemberAccessException exception )
246+ {
247+ _logger . LogErr ( exception , $ "Entrypoint '{ type . FullName } ' for mod '{ modInfo . Id } ' is not accessible") ;
248+ }
249+ catch ( TargetInvocationException exception )
250+ {
251+ _logger . LogErr ( exception , $ "Entrypoint '{ type . FullName } ' for mod '{ modInfo . Id } ' threw during activation") ;
252+ }
216253 catch ( Exception exception )
217254 {
218255 _logger . LogErr ( exception , $ "Failed to initialize entrypoint '{ type . FullName } ' for mod '{ modInfo . Id } '") ;
0 commit comments