summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--StardewModdingAPI/Config.cs228
-rw-r--r--StardewModdingAPI/Manifest.cs4
-rw-r--r--StardewModdingAPI/Program.cs4
3 files changed, 194 insertions, 42 deletions
diff --git a/StardewModdingAPI/Config.cs b/StardewModdingAPI/Config.cs
index b95888d2..ae126e33 100644
--- a/StardewModdingAPI/Config.cs
+++ b/StardewModdingAPI/Config.cs
@@ -11,19 +11,194 @@ using Newtonsoft.Json.Linq;
namespace StardewModdingAPI
{
- public class Config
+ public partial class Config
{
[JsonIgnore]
- public virtual JObject JObject { get; protected set; }
+ public virtual string ConfigLocation { get; protected internal set; }
[JsonIgnore]
- public virtual string ConfigLocation { get; protected set; }
+ public virtual string ConfigDir => Path.GetDirectoryName(ConfigLocation);
+
+ public virtual Config Instance<T>() where T : Config => Activator.CreateInstance<T>();
+
+ /// <summary>
+ /// Should never be used for anything.
+ /// </summary>
+ public Config()
+ {
+
+ }
+
+ /// <summary>
+ /// Loads the config from the json blob on disk, updating and re-writing to the disk if needed.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ internal virtual T LoadConfig<T>() where T : Config
+ {
+ if (string.IsNullOrEmpty(ConfigLocation))
+ {
+ Log.Error("A config tried to load without specifying a location on the disk.");
+ return null;
+ }
+
+ T ret = null;
+
+ if (!File.Exists(ConfigLocation))
+ {
+ //no config exists, generate default values
+ var c = this.GenerateBaseConfig<T>();
+ c.ConfigLocation = ConfigLocation;
+ ret = c;
+ }
+ else
+ {
+ try
+ {
+ //try to load the config from a json blob on disk
+ T c = JsonConvert.DeserializeObject<T>(File.ReadAllText(ConfigLocation));
+
+ c.ConfigLocation = ConfigLocation;
+
+ //update the config with default values if needed
+ ret = c.UpdateConfig<T>();
+
+ c = null;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("Invalid JSON Config: {0} \n{1}", ConfigLocation, ex);
+ return GenerateBaseConfig<T>();
+ }
+ }
+
+ ret.WriteConfig();
+ return ret;
+ }
+
+ /// <summary>
+ /// MUST be implemented in inheriting class!
+ /// </summary>
+ internal virtual T GenerateBaseConfig<T>() where T : Config
+ {
+ return null;
+ }
+
+ /// <summary>
+ /// Merges a default-value config with the user-config on disk.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ internal virtual T UpdateConfig<T>() where T : Config
+ {
+ try
+ {
+ //default config
+ var b = JObject.FromObject(Instance<T>().GenerateBaseConfig<T>());
+
+ //user config
+ var u = JObject.FromObject(this);
+
+ //overwrite default values with user values
+ b.Merge(u, new JsonMergeSettings {MergeArrayHandling = MergeArrayHandling.Replace});
+
+ //cast json object to config
+ T c = b.ToObject<T>();
+
+ //re-write the location on disk to the object
+ c.ConfigLocation = ConfigLocation;
+
+ return c;
+ }
+ catch (Exception ex)
+ {
+ Log.Error("An error occured when updating a config: " + ex);
+ return this as T;
+ }
+ }
+ }
+
+ public static class ConfigExtensions
+ {
+ /// <summary>
+ /// Initializes an instance of any class that inherits from Config.
+ /// This method performs the loading, saving, and merging of the config on the disk and in memory at a default state.
+ /// This method should not be used to re-load or to re-save a config.
+ /// </summary>
+ public static T InitializeConfig<T>(this T baseConfig, string configLocation) where T : Config
+ {
+ if (baseConfig == null)
+ {
+ baseConfig = Activator.CreateInstance<T>();
+ /*
+ Log.Error("A config tried to initialize whilst being null.");
+ return null;
+ */
+ }
+
+ if (string.IsNullOrEmpty(configLocation))
+ {
+ Log.Error("A config tried to initialize without specifying a location on the disk.");
+ return null;
+ }
+
+ baseConfig.ConfigLocation = configLocation;
+ T c = baseConfig.LoadConfig<T>();
+
+ return c;
+ }
+
+ /// <summary>
+ /// Writes a config to a json blob on the disk specified in the config's properties.
+ /// </summary>
+ public static void WriteConfig<T>(this T baseConfig) where T : Config
+ {
+ if (string.IsNullOrEmpty(baseConfig?.ConfigLocation) || string.IsNullOrEmpty(baseConfig.ConfigDir))
+ {
+ Log.Error("A config attempted to save when it itself or it's location were null.");
+ return;
+ }
+
+ string s = JsonConvert.SerializeObject(baseConfig, typeof (T), Formatting.Indented, new JsonSerializerSettings());
+
+ if (!Directory.Exists(baseConfig.ConfigDir))
+ Directory.CreateDirectory(baseConfig.ConfigDir);
+
+ if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllText(baseConfig.ConfigLocation).SequenceEqual(s))
+ File.WriteAllText(baseConfig.ConfigLocation, s);
+ }
+
+ /// <summary>
+ /// Re-reads the json blob on the disk and merges its values with a default config
+ /// </summary>
+ public static T ReloadConfig<T>(this T baseConfig) where T : Config
+ {
+ return baseConfig.UpdateConfig<T>();
+ }
- public static Config Instance
+ [Obsolete]
+ public static void WriteConfig(this Config baseConfig)
{
- get { return new Config(); }
+ Log.Error("A config has been written through an obsolete way.\n\tThis method of writing configs will not be supported in future versions.");
+ WriteConfig<Config>(baseConfig);
}
+ [Obsolete]
+ public static Config ReloadConfig(this Config baseConfig)
+ {
+ Log.Error("A config has been reloaded through an obsolete way.\n\tThis method of loading configs will not be supported in future versions.");
+ return baseConfig.ReloadConfig<Config>();
+ }
+ }
+
+ [Obsolete]
+ public partial class Config
+ {
+ [JsonIgnore]
+ [Obsolete]
+ public virtual JObject JObject { get; protected set; }
+
+ [Obsolete]
public static Config InitializeConfig(string configLocation, Config baseConfig)
{
if (string.IsNullOrEmpty(configLocation))
@@ -42,17 +217,19 @@ namespace StardewModdingAPI
return baseConfig.LoadConfig(baseConfig);
}
+ [Obsolete]
public virtual Config GenerateBaseConfig(Config baseConfig)
{
//Must be implemented in sub-class
return null;
}
+ [Obsolete]
public virtual Config LoadConfig(Config baseConfig)
{
if (!File.Exists(baseConfig.ConfigLocation))
{
- var v = (Config)baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig });
+ var v = (Config) baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] {baseConfig});
v.WriteConfig();
}
else
@@ -62,7 +239,7 @@ namespace StardewModdingAPI
try
{
var j = JObject.Parse(File.ReadAllText(baseConfig.ConfigLocation));
- baseConfig = (Config)j.ToObject(baseConfig.GetType());
+ baseConfig = (Config) j.ToObject(baseConfig.GetType());
baseConfig.ConfigLocation = p;
baseConfig.JObject = j;
@@ -74,29 +251,26 @@ namespace StardewModdingAPI
}
catch
{
- Log.Verbose("Invalid JSON Renamed: " + p);
- if (File.Exists(p))
- File.Move(p, Path.Combine(Path.GetDirectoryName(p), Path.GetFileNameWithoutExtension(p) + "." + Guid.NewGuid() + ".json")); //Get it out of the way for a new one
- var v = (Config)baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig });
- v.WriteConfig();
+ Log.Verbose("Invalid JSON: " + p);
}
}
return baseConfig;
}
+ [Obsolete]
public virtual Config UpdateConfig(Config baseConfig)
{
try
{
//default config with all standard values
- var b = JObject.FromObject(baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig }));
+ var b = JObject.FromObject(baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] {baseConfig}));
//user config with their values
var u = baseConfig.JObject;
- b.Merge(u, new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Replace });
+ b.Merge(u, new JsonMergeSettings {MergeArrayHandling = MergeArrayHandling.Replace});
- return (Config)b.ToObject(baseConfig.GetType());
+ return (Config) b.ToObject(baseConfig.GetType());
}
catch (Exception ex)
{
@@ -116,28 +290,4 @@ namespace StardewModdingAPI
return theMod.BaseConfigPath;
}
}
-
- public static class ConfigExtensions
- {
- public static void WriteConfig(this Config baseConfig)
- {
- if (baseConfig == null || string.IsNullOrEmpty(baseConfig.ConfigLocation) || string.IsNullOrEmpty(Path.GetDirectoryName(baseConfig.ConfigLocation)))
- {
- Log.Error("A config attempted to save when it itself or it's location were null.");
- return;
- }
-
- var toWrite = JsonConvert.SerializeObject(baseConfig, baseConfig.GetType(), Formatting.Indented, new JsonSerializerSettings());
- if (!Directory.Exists(Path.GetDirectoryName(baseConfig.ConfigLocation)))
- Directory.CreateDirectory(Path.GetDirectoryName(baseConfig.ConfigLocation));
- if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllText(baseConfig.ConfigLocation).SequenceEqual(toWrite))
- File.WriteAllText(baseConfig.ConfigLocation, toWrite);
- toWrite = null;
- }
-
- public static Config ReloadConfig(this Config baseConfig)
- {
- return baseConfig.UpdateConfig(baseConfig);
- }
- }
} \ No newline at end of file
diff --git a/StardewModdingAPI/Manifest.cs b/StardewModdingAPI/Manifest.cs
index 9b358c90..5a8b65a9 100644
--- a/StardewModdingAPI/Manifest.cs
+++ b/StardewModdingAPI/Manifest.cs
@@ -39,7 +39,7 @@ namespace StardewModdingAPI
/// </summary>
public virtual string EntryDll { get; set; }
- public override Config GenerateBaseConfig(Config baseConfig)
+ internal override T GenerateBaseConfig<T>()
{
Name = "";
Authour = "";
@@ -48,7 +48,7 @@ namespace StardewModdingAPI
UniqueID = Guid.NewGuid().ToString();
PerSaveConfigs = false;
EntryDll = "";
- return this;
+ return this as T;
}
}
}
diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs
index cfd7b05e..e7055ebf 100644
--- a/StardewModdingAPI/Program.cs
+++ b/StardewModdingAPI/Program.cs
@@ -290,7 +290,9 @@ namespace StardewModdingAPI
continue;
}
- manifest = (Manifest)Config.InitializeConfig(s, manifest);
+ //manifest = (Manifest)Config.InitializeConfig(s, manifest);
+ manifest = manifest.InitializeConfig(s);
+
if (string.IsNullOrEmpty(manifest.EntryDll))
{
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. EntryDll is empty!", s);