Skip to content

Commit dea279b

Browse files
committed
Fixed issue where ModBase could possibly determine the wrong mod assembly file during initialization
1 parent 6d0f8af commit dea279b

File tree

2 files changed

+46
-10
lines changed

2 files changed

+46
-10
lines changed

ModBase.cs

+35-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public abstract class ModBase
1717
{
1818
public List<Texture2D> ModTextures { get; protected set; }
1919
public List<GameObject> ModObjects { get; protected set; }
20+
public Assembly ModAssembly { get; protected set; } // This is set by the mod loader and should generally not be set elsewhere except possibly by second stage mod loaders
2021

2122
public virtual Version ModVersion => new Version(0, 0, 0, 0);
2223

@@ -25,22 +26,28 @@ public abstract class ModBase
2526
private static FastZip ZipInstance { get; } = new FastZip();
2627

2728
protected ModBase()
29+
{
30+
ExtractAssemblyResources();
31+
LoadResourcesSafe();
32+
UpdateCredits();
33+
}
34+
35+
protected virtual void ExtractAssemblyResources()
2836
{
2937
//Extract embedded assets
3038
ZipConstants.DefaultCodePage = 0; //This is a workaround to get files to extract properly
3139

32-
var currentAssembly = Assembly.GetCallingAssembly();
33-
var manifest = currentAssembly.GetManifestResourceNames();
34-
35-
PreProcessEmbeddedResources(manifest);
40+
var manifestResources = ModAssembly.GetManifestResourceNames();
41+
PreProcessEmbeddedResources(manifestResources);
3642

37-
foreach (var file in manifest)
43+
foreach (var file in manifestResources)
3844
{
39-
if (!PreProcessEmbeddedResource(file)) continue;
45+
if (!PreProcessEmbeddedResource(file))
46+
continue;
4047

4148
Debug.Log($"Processing embedded file \"{file}\"");
4249

43-
using (var resourceStream = currentAssembly.GetManifestResourceStream(file))
50+
using (var resourceStream = ModAssembly.GetManifestResourceStream(file))
4451
{
4552
switch (Path.GetExtension(file))
4653
{
@@ -73,7 +80,17 @@ protected ModBase()
7380
}
7481
}
7582
}
83+
}
84+
85+
protected virtual void LoadResourcesSafe()
86+
{
87+
LoadStringsSafe();
88+
LoadPngsSafe();
89+
LoadObjsSafe();
90+
}
7691

92+
protected virtual void LoadStringsSafe()
93+
{
7794
try
7895
{
7996
LoadAllStrings("strings");
@@ -83,7 +100,10 @@ protected ModBase()
83100
Debug.Log("Failed to load strings files due to exception:");
84101
Utils.LogException(e);
85102
}
103+
}
86104

105+
protected virtual void LoadPngsSafe()
106+
{
87107
try
88108
{
89109
ModTextures = LoadAllPngs("png");
@@ -98,12 +118,15 @@ protected ModBase()
98118
Debug.Log("Failed to load PNG files due to exception:");
99119
Utils.LogException(e);
100120
}
121+
}
101122

123+
protected virtual void LoadObjsSafe()
124+
{
102125
try
103126
{
104127
ModObjects = LoadAllObjs("obj");
105128

106-
if(ModObjects.Count > 0)
129+
if (ModObjects.Count > 0)
107130
{
108131
Debug.Log($"Successfully loaded {ModObjects.Count} object(s)");
109132
}
@@ -113,8 +136,11 @@ protected ModBase()
113136
Debug.Log("Failed to load OBJ files due to exception:");
114137
Utils.LogException(e);
115138
}
139+
}
116140

117-
var credits = GetCredits().Trim();
141+
protected virtual void UpdateCredits()
142+
{
143+
var credits = GetCredits()?.Trim();
118144
if (!string.IsNullOrEmpty(credits))
119145
ConstructorPatch.Credits[this] = credits;
120146
}

Modloader.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using System.Reflection;
6+
using System.Runtime.Serialization;
67
using Mono.Cecil;
78
using Planetbase;
89
using PlanetbaseFramework.Cecil;
@@ -120,12 +121,21 @@ public static T LoadMod<T>(Assembly modAssembly, string modTypeName) where T : M
120121
try
121122
{
122123
var modType = modAssembly.GetType(modTypeName);
123-
mod = Activator.CreateInstance(modType) as T;
124+
var constructor = modType.GetConstructor(Type.EmptyTypes) ??
125+
throw new Exception(
126+
$"The type \"{modType.FullName}\" does not have a parameterless constructor");
127+
128+
mod = FormatterServices.GetUninitializedObject(modType) as T;
124129

125130
if (mod == null)
126131
throw new Exception(
127132
$"The type \"{modType.FullName}\" is not convertible to \"{typeof(T).FullName}\".");
128133

134+
// Populate the mod's fields and call constructor
135+
// This is safe to assume as non-null as the property name is checked at compile time (if mod.ModAssembly does not exist, then compilation fails)
136+
modType.GetProperty(nameof(mod.ModAssembly)).SetValue(mod, modAssembly, null);
137+
constructor.Invoke(mod, null);
138+
129139
Debug.Log($"Instantiated mod \"{mod.ModName}\" from type \"{modTypeName}\"");
130140
}
131141
catch (Exception e)

0 commit comments

Comments
 (0)