Configuration
#region Configuration
private Configuration _config;
private class Configuration
{
[JsonProperty("Example String")]
public string Example = "example";
[JsonProperty("Example List", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> ExampleList = new List<string>() { "example" };
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch
{
PrintError("Your configuration file contains an error. Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig() => Config.WriteObject(_config);
protected override void LoadDefaultConfig() => _config = new Configuration();
#endregion
Single Datafile
#region Work with Data
private PluginData _data;
private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, _data);
private void LoadData()
{
try
{
_data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_data == null) _data = new PluginData();
}
private class PluginData
{
public string ExampleString = string.Empty;
public List<string> ExampleList = new List<string>();
}
#endregion
Multiple Datafiles
You may implement datafiles per player, building etc. You would need to copy the CustomData
class to implement new files. Remember to change the path under CustomData.BaseFolder
and rename CustomData
to something more meaningful, such as PlayerPreferences
. You might consider running CustomData.LoadedData.Clear()
on Unload
.
#region Work with Data
private abstract class SplitDatafile<T> where T : SplitDatafile<T>, new()
{
public static Dictionary<string, T> LoadedData = new Dictionary<string, T>();
protected static string[] GetFiles(string baseFolder)
{
try
{
var json = ".json".Length;
var paths = Interface.Oxide.DataFileSystem.GetFiles(baseFolder);
for (var i = 0; i < paths.Length; i++)
{
var path = paths[i];
var separatorIndex = path.LastIndexOf(Path.DirectorySeparatorChar);
// We have to do this since GetFiles returns paths instead of filenames
// And other methods require filenames
paths[i] = path.Substring(separatorIndex + 1, path.Length - separatorIndex - 1 - json);
}
return paths;
}
catch
{
return Array.Empty<string>();
}
}
protected static T Save(string baseFolder, string filename)
{
T data;
if (!LoadedData.TryGetValue(filename, out data))
return null;
Interface.Oxide.DataFileSystem.WriteObject(baseFolder + filename, data);
return data;
}
protected static T Get(string baseFolder, string filename)
{
T data;
if (LoadedData.TryGetValue(filename, out data))
return data;
return null;
}
protected static T GetOrLoad(string baseFolder, string filename)
{
T data;
if (LoadedData.TryGetValue(filename, out data))
return data;
try
{
data = Interface.Oxide.DataFileSystem.ReadObject<T>(baseFolder + filename);
}
catch (Exception e)
{
Interface.Oxide.LogError(e.ToString());
}
return LoadedData[filename] = data;
}
protected static T GetOrCreate(string baseFolder, string path)
{
return GetOrLoad(baseFolder, path) ?? (LoadedData[path] = new T());
}
}
private class CustomData : SplitDatafile<CustomData>
{
public string ExampleString = string.Empty;
public List<string> ExampleList = new List<string>();
public static readonly string BaseFolder = "PluginName" + Path.DirectorySeparatorChar + "Subfolder" + Path.DirectorySeparatorChar;
public static string[] GetFiles() => GetFiles(BaseFolder);
public static CustomData Save(string filename) => Save(BaseFolder, filename);
public static CustomData Get(string filename) => Get(BaseFolder, filename);
public static CustomData GetOrLoad(string filename) => GetOrLoad(BaseFolder, filename);
public static CustomData GetOrCreate(string filename) => GetOrCreate(BaseFolder, filename);
}
#endregion