diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index fcb82a02..4147fdb9 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -248,7 +248,16 @@ namespace NewHorizons.Handlers } } } - Main.Instance.OnPlanetLoaded?.Invoke(body.Config.name); + + try + { + Main.Instance.OnPlanetLoaded?.Invoke(body.Config.name); + } + catch (Exception e) + { + Logger.LogError($"Error in event handler for OnPlanetLoaded on body {body.Config.name}: {e.Message} : {e.StackTrace}"); + } + return true; } diff --git a/NewHorizons/INewHorizons.cs b/NewHorizons/INewHorizons.cs index aa014ea6..8f132ee7 100644 --- a/NewHorizons/INewHorizons.cs +++ b/NewHorizons/INewHorizons.cs @@ -50,14 +50,14 @@ namespace NewHorizons UnityEvent GetBodyLoadedEvent(); /// - /// Gets an object in the `extras` object of a body config, returns null if the key doesn't exist + /// Uses JSONPath to query a body /// - object GetExtraModuleForBody(Type moduleType, string extrasModuleName, string planetName); + object QueryBody(Type outType, string bodyName, string path); /// - /// Gets an object in the `extras` object of a system config, returns null if the key doesn't exist + /// Uses JSONPath to query a system /// - object GetExtraModuleForSystem(Type moduleType, string extrasModuleName, string systemName); + object QuerySystem(Type outType, string path); /// /// Allows you to overwrite the default system. This is where the player is respawned after dying. diff --git a/NewHorizons/NewHorizonsApi.cs b/NewHorizons/NewHorizonsApi.cs index e8e36a24..0ac47b68 100644 --- a/NewHorizons/NewHorizonsApi.cs +++ b/NewHorizons/NewHorizonsApi.cs @@ -8,6 +8,8 @@ using System.Collections.Generic; using System.Data.SqlTypes; using System.IO; using System.Linq; +using System.Reflection; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.Events; @@ -101,42 +103,40 @@ namespace NewHorizons } } - private object GetExtraModule(Type moduleType, string key, string path) + private static object QueryJson(Type outType, string filePath, string jsonPath) { - if (path == "") return null; + if (filePath == "") return null; try { - var jsonText = File.ReadAllText(path); + var jsonText = File.ReadAllText(filePath); var jsonData = JObject.Parse(jsonText); - var possibleExtras = jsonData.Property("extras")?.Value; - if (possibleExtras is JObject extras) - { - return extras.Property(key)?.Value.ToObject(moduleType); - } - return null; + return jsonData.SelectToken(jsonPath)?.ToObject(outType); } catch (FileNotFoundException) { return null; } + catch (JsonException e) + { + Logger.LogError($"{e.Message} : {e.StackTrace}"); + return null; + } } - public object GetExtraModuleForBody(Type moduleType, string extraModuleKey, string planetName) + public object QueryBody(Type outType, string bodyName, string jsonPath) { - var planet = Main.BodyDict[Main.Instance.CurrentStarSystem].Find((b) => b.Config.name == planetName); + var planet = Main.BodyDict[Main.Instance.CurrentStarSystem].Find((b) => b.Config.name == bodyName); return planet == null ? null - : GetExtraModule(moduleType, extraModuleKey, - planet.Mod.ModHelper.Manifest.ModFolderPath + planet.RelativePath); + : QueryJson(outType, planet.Mod.ModHelper.Manifest.ModFolderPath + planet.RelativePath, jsonPath); } - public object GetExtraModuleForSystem(Type moduleType, string extraModuleKey, string systemName) + public object QuerySystem(Type outType, string jsonPath) { var system = Main.SystemDict[Main.Instance.CurrentStarSystem]; return system == null ? null - : GetExtraModule(moduleType, extraModuleKey, - system.Mod.ModHelper.Manifest.ModFolderPath + system.RelativePath); + : QueryJson(outType, system.Mod.ModHelper.Manifest.ModFolderPath + system.RelativePath, jsonPath); } public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, diff --git a/docs/content/pages/tutorials/api.md b/docs/content/pages/tutorials/api.md index 0400351f..5c7a8996 100644 --- a/docs/content/pages/tutorials/api.md +++ b/docs/content/pages/tutorials/api.md @@ -52,14 +52,14 @@ public interface INewHorizons UnityEvent GetBodyLoadedEvent(); /// - /// Gets an object in the `extras` object of a body config, returns null if the key doesn't exist + /// Uses JSONPath to query a body /// - object GetExtraModuleForBody(Type moduleType, string extrasModuleName, string planetName); + object QueryBody(Type outType, string bodyName, string path); /// - /// Gets an object in the `extras` object of a system config, returns null if the key doesn't exist + /// Uses JSONPath to query a system /// - object GetExtraModuleForSystem(Type moduleType, string extrasModuleName, string systemName); + object QuerySystem(Type outType, string path); /// /// Allows you to overwrite the default system. This is where the player is respawned after dying. diff --git a/docs/content/pages/tutorials/extending.md b/docs/content/pages/tutorials/extending.md index 406b5e0a..7c3b4ec4 100644 --- a/docs/content/pages/tutorials/extending.md +++ b/docs/content/pages/tutorials/extending.md @@ -23,7 +23,7 @@ Addon developers will add a key to the `extras` object in the root of the config } ``` -Your mod will then use the API's `GetExtraModuleForBody` method to obtain the `myCoolExtensionData` object. +Your mod will then use the API's `QueryBody` method to obtain the `myCoolExtensionData` object. **It's up to the addon dev to list your mod as a dependency!** @@ -31,7 +31,7 @@ Your mod will then use the API's `GetExtraModuleForBody` method to obtain the `m You can extend all planets by hooking into the `OnBodyLoaded` event of the API: -```cs +```csharp var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); api.GetBodyLoadedEvent().AddListener((name) => { ModHelper.Console.WriteLine($"Body: {name} Loaded!"); @@ -40,19 +40,19 @@ api.GetBodyLoadedEvent().AddListener((name) => { In order to get your extra module, first define the module as a class: -```cs +```csharp public class MyCoolExtensionData { int myCoolExtensionProperty; } ``` -Then, use the `GetExtraModuleForBody` method: +Then, use the `QueryBody` method: -```cs +```csharp var api = ModHelper.Interactions.TryGetModApi("xen.NewHorizons"); api.GetBodyLoadedEvent().AddListener((name) => { ModHelper.Console.WriteLine($"Body: {name} Loaded!"); - var potentialData = api.GetExtraModuleForBody(typeof(MyCoolExtensionData), "myCoolExtensionData", name); + var potentialData = api.QueryBody(typeof(MyCoolExtensionData), "$.extras.myCoolExtensionData", name); // Makes sure the module is valid and not null if (potentialData is MyCoolExtensionData data) { ModHelper.Console.WriteLine($"myCoolExtensionProperty for {name} is {data.myCoolExtensionProperty}!"); @@ -62,4 +62,13 @@ api.GetBodyLoadedEvent().AddListener((name) => { ## Extending Systems -Extending systems is the exact same as extending planets, except you use the `GetExtraModuleForSystem` method instead. +Extending systems is the exact same as extending planets, except you use the `QuerySystem` method instead. + +## Accessing Other Values + +You can also use the `QueryBody` method to get values of the config outside of your extension object + +```csharp +var primaryBody = NHAPI.QueryBody(typeof(string), "Wetrock", "$.Orbit.primaryBody"); + ModHelper.Console.WriteLine($"Primary of {bodyName} is {primaryBody ?? "NULL"}!"); +```