Data Files
Data files are used to store potentially large amounts of arbitrary data.
Using a data file
The GetDatafile
method will return a DynamicConfigFile
object. If the file requested already exists, its data will be loaded into the DynamicConfigFile
. If the file does not exist, it will be created.
Creating/saving the file
DynamicConfigFile dataFile = Interface.Oxide.DataFileSystem.GetDatafile("MyDataFile");
dataFile["EpicString"] = "EpicValue";
dataFile["EpicNumber"] = 42;
dataFile.Save();
Doing this will create a file at the location oxide/data/MyDataFile.json
which will have the following contents:
{
"EpicString" : "EpicValue",
"EpicNumber" : 42
}
Accessing data by key
// Check if the EpicString exists
if (dataFile["EpicString"] != null)
{
Puts(dataFile["EpicString"]); // Outputs: EpicValue
}
// Check if the EpicNumber exists
if (dataFile["EpicNumber"] != null)
{
Puts(dataFile["EpicNumber"]); // Outputs: 42
}
Removing a key
Remove a particular key, using the previous example.
dataFile.Remove("EpicString");
dataFile.Save();
The final JSON output:
{
"EpicNumber" : 42
}
Clearing the entire file
dataFile.Clear();
Nested keys
A developer may use the DynamicConfigFile
object to easily read and write nested key-value pairs.
Write nested key
dataFile["EpicCategory", "EpicString"] = "EpicValue";
{
"EpicCategory" : {
"EpicString" : "EpicValue"
}
}
Read nested key
if (dataFile["EpicCategory", "EpicString"] != null)
{
Puts(dataFile["EpicCategory", "EpicString"]); // Outputs: EpicValue
}
Checking if a file exists
if (Interface.Oxide.DataFileSystem.ExistsDatafile("MyDataFile"))
{
Puts("MyDataFile exists!");
}
else
{
Puts("MyDataFile does not exist");
}
Loading a data object
Much like advanced configurations, data files may be scaffolded using a class definition.
private class StoredData
{
public HashSet<PlayerInfo> Players = new HashSet<PlayerInfo>();
public StoredData()
{
}
}
private class PlayerInfo
{
public string Id;
public string Name;
public PlayerInfo()
{
}
public PlayerInfo(IPlayer player)
{
Id = player.Id;
Name = player.Name;
}
}
private StoredData storedData;
private void Init()
{
storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>("MyDataFile");
}
Saving a data object
Change data files by simply assigning the new values and writing the object to the file.
[Command("test")]
private void TestCommand(IPlayer player, string command, string[] args)
{
PlayerInfo info = new PlayerInfo(player);
if (storedData.Players.Contains(info))
{
player.Reply("Your data has already been added to the file");
}
else
{
storedData.Players.Add(info);
player.Reply("Saving your data to the file...");
Interface.Oxide.DataFileSystem.WriteObject("MyDataFile", storedData);
}
}
Advanced data
For large plugins that potentially store massive amounts of data, using a single data file may not be advisable. In this case, uMod provides the ability to store many smaller data files in a custom sub-directory. These smaller data files may be loaded on an as-needed basis, thus reducing the impact of a plugin on memory and the filesystem overall.
private DataFileSystem dataFile;
private void Init()
{
dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\player_info");
}
private PlayerInfo LoadPlayerInfo(string playerId)
{
return dataFile.ReadObject<PlayerInfo>($"playerInfo_{playerId}");
}
private void SavePlayerInfo(string playerId, PlayerInfo playerInfo)
{
dataFile.WriteObject<PlayerInfo>($"playerInfo_{playerId}", playerInfo);
}