2016-03-21 03:43:31 +08:00
/ *
Copyright 2016 Zoey ( Zoryn )
* /
using System ;
using System.IO ;
using System.Linq ;
using System.Reflection ;
using Newtonsoft.Json ;
using Newtonsoft.Json.Linq ;
namespace StardewModdingAPI
{
public class Config
{
[JsonIgnore]
public virtual JObject JObject { get ; protected set ; }
[JsonIgnore]
public virtual string ConfigLocation { get ; protected set ; }
public static Config Instance
{
get { return new Config ( ) ; }
}
public static Config InitializeConfig ( string configLocation , Config baseConfig )
{
2016-03-23 08:36:04 +08:00
if ( string . IsNullOrEmpty ( configLocation ) )
{
Log . Verbose ( "The location to save the config to must not be empty." ) ;
return null ;
}
2016-03-21 03:43:31 +08:00
if ( baseConfig = = null )
{
2016-03-23 08:36:04 +08:00
Log . Verbose ( "A config must be instantiated before being passed to Initialize.\n\t" + configLocation ) ;
2016-03-21 03:43:31 +08:00
return null ;
}
baseConfig . ConfigLocation = configLocation ;
return baseConfig . LoadConfig ( baseConfig ) ;
}
public virtual Config GenerateBaseConfig ( Config baseConfig )
{
//Must be implemented in sub-class
return null ;
}
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 } ) ;
v . WriteConfig ( ) ;
}
else
{
var p = baseConfig . ConfigLocation ;
try
{
2016-03-23 08:36:04 +08:00
var j = JObject . Parse ( File . ReadAllText ( baseConfig . ConfigLocation ) ) ;
2016-03-21 03:43:31 +08:00
baseConfig = ( Config ) j . ToObject ( baseConfig . GetType ( ) ) ;
baseConfig . ConfigLocation = p ;
baseConfig . JObject = j ;
baseConfig = UpdateConfig ( baseConfig ) ;
baseConfig . ConfigLocation = p ;
baseConfig . JObject = j ;
baseConfig . WriteConfig ( ) ;
}
catch
{
2016-03-23 08:36:04 +08:00
Log . Verbose ( "Invalid JSON Renamed: " + p ) ;
2016-03-21 03:43:31 +08:00
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 ( ) ;
}
}
return baseConfig ;
}
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 } ) ) ;
//user config with their values
var u = baseConfig . JObject ;
2016-03-23 04:38:16 +08:00
b . Merge ( u , new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling . Replace } ) ;
2016-03-21 03:43:31 +08:00
return ( Config ) b . ToObject ( baseConfig . GetType ( ) ) ;
}
catch ( Exception ex )
{
2016-03-23 08:36:04 +08:00
Log . Error ( ex . ToString ( ) ) ;
2016-03-21 03:43:31 +08:00
}
return baseConfig ;
}
2016-03-23 08:36:04 +08:00
/// <summary>
/// NOTICE: THIS IS OBSOLETE AND WILL BE REMOVED IN THE FUTURE. 'BaseConfigPath' IS NOW A PROPERTY IN A MOD
/// </summary>
/// <param name="theMod"></param>
/// <returns></returns>
[Obsolete]
2016-03-21 03:43:31 +08:00
public static string GetBasePath ( Mod theMod )
{
2016-03-23 08:36:04 +08:00
return theMod . BaseConfigPath ;
2016-03-21 03:43:31 +08:00
}
}
public static class ConfigExtensions
{
public static void WriteConfig ( this Config baseConfig )
{
2016-03-23 08:36:04 +08:00
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 ) ;
2016-03-21 03:43:31 +08:00
toWrite = null ;
}
public static Config ReloadConfig ( this Config baseConfig )
{
return baseConfig . UpdateConfig ( baseConfig ) ;
}
}
}