using System; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEngine; namespace AllocsFixes { public static class Mods { public class ModData { public Assembly assembly; public string name; public string version; public ModAPI apiInstance; } private static readonly string MOD_PATH = Application.dataPath + "/../Mods"; private static Dictionary loadedMods = new Dictionary (); public static void LoadMods () { if (Directory.Exists (MOD_PATH)) { Log.Out ("Loading mods"); foreach (string modDir in Directory.GetDirectories (MOD_PATH)) { foreach (string modDll in Directory.GetFiles (modDir, "*.dll")) { try { Assembly assemblyInstance = Assembly.LoadFrom (modDll); ModData md = new ModData (); md.assembly = assemblyInstance; md.apiInstance = CreateApiInstance (md); if (md.apiInstance == null) { Log.Warning ("DLL does not declare a class of type ModAPI, ignoring"); continue; } if (string.IsNullOrEmpty (md.apiInstance.ModName ())) { Log.Warning ("DLL's ModAPI does not override ModName(), ignoring"); continue; } if (loadedMods.ContainsKey (md.apiInstance.ModName ())) { Log.Warning ("DLL's ModAPI.ModName() returns name that's already loaded, ignoring"); continue; } md.name = md.apiInstance.ModName (); md.version = md.apiInstance.ModVersion (); loadedMods.Add (md.name, md); Log.Out ("Loaded mod: " + md.name + " (" + md.version + ")"); } catch (Exception e) { Log.Error ("Failed loading DLL"); Log.Exception (e); } } } Log.Out ("Loading mods done"); } else { Log.Out ("No mods folder found"); } } public static bool ModLoaded (string _modName) { return loadedMods.ContainsKey (_modName); } public static Assembly GetModAssembly (string _modName) { if (ModLoaded (_modName)) { return loadedMods [_modName].assembly; } return null; } public static List LoadedMods () { List res = new List (); foreach (ModData md in loadedMods.Values) { res.Add (md); } return res; } private static ModAPI CreateApiInstance (ModData _md) { Type modApiType = typeof (ModAPI); foreach (Type t in _md.assembly.GetTypes ()) { if (modApiType.IsAssignableFrom (t)) { Log.Out ("Found ModAPI"); return Activator.CreateInstance(t) as ModAPI; } } return null; } public static void CallGameAwake () { foreach (ModData md in loadedMods.Values) { if (md.apiInstance != null) { md.apiInstance.GameAwake (); } } } public static void CallGameShutdown () { foreach (ModData md in loadedMods.Values) { if (md.apiInstance != null) { md.apiInstance.GameShutdown (); } } } public static void CallSavePlayerData (int _clientId, PlayerDataFile _playerDataFile) { foreach (ModData md in loadedMods.Values) { if (md.apiInstance != null) { md.apiInstance.SavePlayerData (_clientId, _playerDataFile); } } } public static void CallRequestToSpawnPlayer (int _clientId, string _name, int _chunkViewDim, PlayerProfile _playerProfile) { foreach (ModData md in loadedMods.Values) { if (md.apiInstance != null) { md.apiInstance.RequestToSpawnPlayer (_clientId, _name, _chunkViewDim, _playerProfile); } } } public static void CallPlayerDisconnected (ClientInfo _cInfo, bool _bShutdown) { foreach (ModData md in loadedMods.Values) { if (md.apiInstance != null) { md.apiInstance.PlayerDisconnected (_cInfo, _bShutdown); } } } public static void CallCalcMapColors (Chunk _chunk) { foreach (ModData md in loadedMods.Values) { if (md.apiInstance != null) { md.apiInstance.CalcMapColors (_chunk); } } } } }