/// <summary> /// Initializes and stores the options table for quicker lookups later. /// </summary> internal static void Init() { lock (PSharedData.GetLock(PRegistry.KEY_OPTIONS_LOCK)) { modOptions = PSharedData.GetData <OptionsTable>(PRegistry.KEY_OPTIONS_TABLE); PSharedData.PutData(PRegistry.KEY_OPTIONS_LATEST, typeof(POptions)); } }
/// <summary> /// Registers a building to properly display its name, description, and tech tree /// entry. PLib must be initialized using InitLibrary before using this method. Each /// building should only be registered once, either in OnLoad or a post-load patch. /// </summary> /// <param name="building">The building to register.</param> public static void Register(PBuilding building) { if (building == null) { throw new ArgumentNullException("building"); } // In case this call is used before the library was initialized if (!PUtil.PLibInit) { PUtil.InitLibrary(false); PUtil.LogWarning("PUtil.InitLibrary was not called before using " + "PBuilding.Register!"); } // Must use object as the building table type lock (PSharedData.GetLock(PRegistry.KEY_BUILDING_LOCK)) { var table = PSharedData.GetData <ICollection <object> >(PRegistry. KEY_BUILDING_TABLE); if (table == null) { PSharedData.PutData(PRegistry.KEY_BUILDING_TABLE, table = new List <object>(64)); } #if DEBUG PUtil.LogDebug("Registered building: {0}".F(building.ID)); #endif table.Add(building); } }
/// <summary> /// Registers the specified assembly for automatic PLib localization. If null is /// passed, the calling assembly is registered. /// </summary> /// <param name="assembly">The assembly to register for PLib localization.</param> public static void Register(Assembly assembly = null) { if (assembly == null) { assembly = Assembly.GetCallingAssembly(); } lock (PSharedData.GetLock(PRegistry.KEY_LOCALE_LOCK)) { // Get list holding locale information var list = PSharedData.GetData <IList <Assembly> >(PRegistry.KEY_LOCALE_TABLE); if (list == null) { PSharedData.PutData(PRegistry.KEY_LOCALE_TABLE, list = new List <Assembly>(8)); } list.Add(assembly); } var types = assembly.GetTypes(); if (types == null || types.Length == 0) { PUtil.LogWarning("Registered assembly " + assembly.GetName()?.Name + " that had no types for localization!"); } else { // This call searches all types in the assembly implicitly Localization.RegisterForTranslation(types[0]); } }
/// <summary> /// Initializes the Imagination Loader. PLib will be initialized if not already done. /// </summary> /// <param name="rootType">The Type that will be used as the base for this Imagination /// mod's assembly. The namespace for that Type will be registered as the name for /// other Imagination mods to see.</param> public static void Init(Type rootType) { if (rootType == null) { throw new ArgumentNullException("rootType"); } var asm = Assembly.GetExecutingAssembly(); PUtil.InitLibrary(); // Create imagination mod table var imag = PSharedData.GetData <IDictionary <string, Assembly> >(IMAGINATION_TABLE); if (imag == null) { PSharedData.PutData(IMAGINATION_TABLE, imag = new Dictionary <string, Assembly>(8)); } var rootNS = rootType.Namespace; if (imag.ContainsKey(rootNS)) { PUtil.LogWarning("Reimagination mod {0} is loaded more than once. This may " + "cause severe problems!".F(rootType.FullName)); } else { imag.Add(rootNS, asm); PUtil.LogDebug("Imagination Loader registered mod ID: " + rootNS); } }
/// <summary> /// Registers a class as a mod options class. /// </summary> /// <param name="optionsType">The class which will represent the options for this mod.</param> public static void RegisterOptions(Type optionsType) { if (optionsType == null) { throw new ArgumentNullException("optionsType"); } var assembly = optionsType.Assembly; var id = Path.GetFileName(GetModDir(assembly)); // Prevent concurrent modification (should be impossible anyways) lock (PSharedData.GetLock(PRegistry.KEY_OPTIONS_LOCK)) { // Get options table var options = PSharedData.GetData <OptionsTable>(PRegistry.KEY_OPTIONS_TABLE); if (options == null) { PSharedData.PutData(PRegistry.KEY_OPTIONS_TABLE, options = new Dictionary <string, Type>(8)); } if (options.ContainsKey(id)) { PUtil.LogWarning("Duplicate mod ID: " + id); } else { // Add as options for this mod options.Add(id, optionsType); PUtil.LogDebug("Registered mod options class {0} for {1}".F( optionsType.Name, assembly.GetName()?.Name)); } } }
/// <summary> /// Registers a class as a mod options class. The type is registered for its defining /// assembly, not for the calling assembly, for compatibility reasons. /// </summary> /// <param name="optionsType">The class which will represent the options for this mod.</param> public static void RegisterOptions(Type optionsType) { if (optionsType == null) { throw new ArgumentNullException("optionsType"); } #if OPTIONS_ONLY var assembly = optionsType.Assembly; var id = Path.GetFileName(GetModDir(assembly)); // Local options type if (modOptions == null) { modOptions = new Dictionary <string, Type>(4); } if (modOptions.ContainsKey(id)) { PUtil.LogWarning("Duplicate mod ID: " + id); } else { // Add as options for this mod modOptions.Add(id, optionsType); PUtil.LogDebug("Registered mod options class {0} for {1}".F(optionsType.Name, assembly.GetName()?.Name)); } #else // In case this call is used before the library was initialized if (!PUtil.PLibInit) { PUtil.InitLibrary(false); PUtil.LogWarning("PUtil.InitLibrary was not called before using " + "RegisterOptions!"); } var assembly = optionsType.Assembly; var id = Path.GetFileName(GetModDir(assembly)); // Prevent concurrent modification (should be impossible anyways) lock (PSharedData.GetLock(PRegistry.KEY_OPTIONS_LOCK)) { // Get options table var options = PSharedData.GetData <OptionsTable>(PRegistry.KEY_OPTIONS_TABLE); if (options == null) { PSharedData.PutData(PRegistry.KEY_OPTIONS_TABLE, options = new Dictionary <string, Type>(8)); } if (options.ContainsKey(id)) { PUtil.LogWarning("Duplicate mod ID: " + id); } else { // Add as options for this mod options.Add(id, optionsType); PUtil.LogDebug("Registered mod options class {0} for {1}".F(optionsType. Name, assembly.GetName()?.Name)); } } #endif }
/// <summary> /// Gets the lock object for the achievement list. /// </summary> /// <returns>An object used to synchronize mods accessing the achievement list.</returns> private static object GetAchievementLock() { var obj = PSharedData.GetData <object>(ACHIEVEMENTS_API_LOCK); if (obj == null) { PSharedData.PutData(ACHIEVEMENTS_API_LOCK, obj = new object()); } return(obj); }
/// <summary> /// Registers a light shape handler. /// </summary> /// <param name="identifier">A unique identifier for this shape. If another mod has /// already registered that identifier, the previous mod will take precedence.</param> /// <param name="handler">The handler for that shape.</param> /// <returns>The light shape which can be used.</returns> public static PLightShape Register(string identifier, CastLight handler) { PLightShape lightShape; // In case this call is used before the library was initialized if (!PUtil.PLibInit) { PUtil.InitLibrary(false); PUtil.LogWarning("PUtil.InitLibrary was not called before using " + "PLightShape.Register!"); } lock (PSharedData.GetLock(PRegistry.KEY_LIGHTING_LOCK)) { // Get list holding lighting information var list = PSharedData.GetData <IList <object> >(PRegistry.KEY_LIGHTING_TABLE); if (list == null) { PSharedData.PutData(PRegistry.KEY_LIGHTING_TABLE, list = new List <object>(8)); } // Try to find a match for this identifier object ls = null; int n = list.Count, index = 0; for (int i = 0; i < n; i++) { var light = list[i]; // Might be from another assembly so the types may or may not be compatible if (light != null && light.ToString() == identifier && light.GetType(). Name == typeof(PLightShape).Name) { index = i; break; } } if (ls == null) { // Not currently existing lightShape = new PLightShape(n + 1, identifier, handler); PUtil.LogDebug("Registered new light shape: " + identifier); list.Add(lightShape); } else { // Exists already PUtil.LogDebug("Found existing light shape: " + identifier); lightShape = new PLightShape(n + 1, identifier, null); } } return(lightShape); }
/// <summary> /// Gets the information for the specified achievement. The achievement lock must be /// held for this method to work properly. /// </summary> /// <param name="id">The achievement ID to look up.</param> /// <returns>The achievement information.</returns> private static Traverse GetAchievement(string id) { var data = PSharedData.GetData <AchievementDict>(ACHIEVEMENTS_API_INFO); if (data == null) { PSharedData.PutData(ACHIEVEMENTS_API_INFO, data = new Dictionary <string, object>(32)); } if (!data.TryGetValue(id, out object info)) { data.Add(id, info = new AchievementInfo(id)); } return(Traverse.Create(info)); }
private static void RegisterEntry(Assembly modAssembly, string lockKey, string tableKey, string entryPath, string debugLine) { // Store the path to the creatures folder on disk for use in loading codex entries string dir = Options.POptions.GetModDir(modAssembly); lock (PSharedData.GetLock(lockKey)) { var table = PSharedData.GetData <IList <string> >(tableKey); if (table == null) { PSharedData.PutData(tableKey, table = new List <string>(8)); } #if DEBUG PUtil.LogDebug(debugLine.F(dir)); #endif table.Add(Path.Combine(dir, entryPath)); } }
/// <summary> /// Registers the specified assembly for automatic PLib localization. If null is /// passed, the calling assembly is registered. /// </summary> /// <param name="assembly">The assembly to register for PLib localization.</param> public static void Register(Assembly assembly = null) { if (!PUtil.PLibInit) { PUtil.InitLibrary(false); PUtil.LogWarning("PUtil.InitLibrary was not called before using " + "PLocalization.Register!"); } if (assembly == null) { assembly = Assembly.GetCallingAssembly(); } lock (PSharedData.GetLock(PRegistry.KEY_LOCALE_LOCK)) { // Get list holding locale information var list = PSharedData.GetData <IList <Assembly> >(PRegistry.KEY_LOCALE_TABLE); if (list == null) { PSharedData.PutData(PRegistry.KEY_LOCALE_TABLE, list = new List <Assembly>(8)); } list.Add(assembly); } var types = assembly.GetTypes(); if (types == null || types.Length == 0) { PUtil.LogWarning("Registered assembly " + assembly.GetNameSafe() + " that had no types for localization!"); } else { // This call searches all types in the assembly implicitly Localization.RegisterForTranslation(types[0]); #if DEBUG PUtil.LogDebug("Localizing assembly {0} using base namespace {1}".F(assembly. GetNameSafe(), types[0].Namespace)); #endif } }