using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework.Input;
using Newtonsoft.Json;
using StardewModdingAPI.Advanced;
namespace StardewModdingAPI.Framework.Serialisation
{
/// Encapsulates SMAPI's JSON file parsing.
internal class JsonHelper
{
/*********
** Accessors
*********/
/// The JSON settings to use when serialising and deserialising files.
private readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
ObjectCreationHandling = ObjectCreationHandling.Replace, // avoid issue where default ICollection values are duplicated each time the config is loaded
Converters = new List
{
new SelectiveStringEnumConverter(typeof(Buttons), typeof(Keys))
}
};
/*********
** Public methods
*********/
/// Read a JSON file.
/// The model type.
/// The absolete file path.
/// The mod helper to inject for instances.
/// Returns the deserialised model, or null if the file doesn't exist or is empty.
public TModel ReadJsonFile(string fullPath, IModHelper modHelper)
where TModel : class
{
// read file
string json;
try
{
json = File.ReadAllText(fullPath);
}
catch (Exception ex) when (ex is DirectoryNotFoundException || ex is FileNotFoundException)
{
return null;
}
// deserialise model
TModel model = JsonConvert.DeserializeObject(json, this.JsonSettings);
if (model is IConfigFile)
{
var wrapper = (IConfigFile)model;
wrapper.ModHelper = modHelper;
wrapper.FilePath = fullPath;
}
return model;
}
/// Save to a JSON file.
/// The model type.
/// The absolete file path.
/// The model to save.
public void WriteJsonFile(string fullPath, TModel model)
where TModel : class
{
// create directory if needed
string dir = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
// write file
string json = JsonConvert.SerializeObject(model, this.JsonSettings);
File.WriteAllText(fullPath, json);
}
}
}