using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Globalization;
namespace ProxyCore
{
public class ConfigFile
{
protected ConfigFile()
{
}
private string Filepath;
///
/// Did we successfully load the config file? If not then it was probably missing.
///
public bool DidLoad
{
get;
private set;
}
///
/// Load a configuration file.
///
/// Configuration name - for example "server". This should be your plugin name.
///
internal void Load(string fileName)
{
fileName = "config." + fileName + ".txt";
_cfgData.Clear();
Filepath = fileName;
OnCreated();
if(_cfgData.Count == 0)
return;
StreamReader f = null;
try
{
f = new StreamReader(fileName);
}
catch(FileNotFoundException)
{
SaveNew();
return;
}
catch
{
return;
}
string l;
while((l = f.ReadLine()) != null)
{
l = l.Trim();
if(string.IsNullOrEmpty(l) || l.StartsWith("#") || l.StartsWith(";") || l.StartsWith("//"))
continue;
Match m = _loadRegex.Match(l);
if(!m.Success)
continue;
string Key = m.Groups[1].Value.ToLower();
if(!_cfgData.ContainsKey(Key))
continue;
string Value = m.Groups[3].Value;
if(Value.Contains('"') && _cfgData[Key].DefaultValue is string)
Value = Value.Substring(1, Value.Length - 2);
if(_cfgData[Key].DefaultValue is int)
{
int i;
if(!int.TryParse(Value, out i))
continue;
_cfgData[Key].Value = i;
}
else if(_cfgData[Key].DefaultValue is uint)
{
uint i;
if(!uint.TryParse(Value, out i))
continue;
_cfgData[Key].Value = i;
}
else if(_cfgData[Key].DefaultValue is long)
{
long i;
if(!long.TryParse(Value, out i))
continue;
_cfgData[Key].Value = i;
}
else if(_cfgData[Key].DefaultValue is ulong)
{
ulong i;
if(!ulong.TryParse(Value, out i))
continue;
_cfgData[Key].Value = i;
}
else if(_cfgData[Key].DefaultValue is string)
{
_cfgData[Key].Value = Value;
}
else if(_cfgData[Key].DefaultValue is float)
{
try
{
float i = Convert.ToSingle(Value, CultureInfo.InvariantCulture.NumberFormat);
_cfgData[Key].Value = i;
}
catch
{
continue;
}
}
else if(_cfgData[Key].DefaultValue is double)
{
try
{
double i = Convert.ToDouble(Value, CultureInfo.InvariantCulture.NumberFormat);
_cfgData[Key].Value = i;
}
catch
{
continue;
}
}
}
f.Close();
}
///
/// Regex pattern used to load a line from config file.
/// Groups[1]: Name of setting
/// Groups[3]: Value of setting (including "" if string)
///
private static readonly Regex _loadRegex = new Regex("([\\w\\.]+)\\s*(=|:|-)\\s*((\".*\")|(-?\\d+\\.\\d+)|(-?\\d+))", RegexOptions.Compiled);
///
/// Save a new configuration file with default values. If there is an existing config file, it will be replaced.
///
public void SaveNew()
{
if(string.IsNullOrEmpty(Filepath) || _cfgData.Count == 0)
return;
StreamWriter f = null;
try
{
f = new StreamWriter(Filepath, false);
}
catch
{
return;
}
foreach(KeyValuePair x in _cfgData)
{
f.WriteLine("###############################################################################");
f.WriteLine("#");
f.WriteLine("# " + x.Value.Key);
if(!string.IsNullOrEmpty(x.Value.Desc))
{
string[] oDesc = Utility.WrapColored(x.Value.Desc, 70, 0);
for(int i = 0; i < oDesc.Length; i++)
f.WriteLine("# " + oDesc[i]);
}
f.WriteLine("#");
f.WriteLine("###############################################################################");
f.WriteLine("");
f.WriteLine(x.Value.Key + " = " + ((x.Value.DefaultValue is string) ? ("\"" + x.Value.DefaultValue + "\"") : x.Value.DefaultValue.ToString().Replace(",", ".")));
f.WriteLine("");
}
f.Close();
}
///
/// This will be called to populate config data with default values and descriptions.
///
protected virtual void OnCreated()
{
}
///
/// Create a new setting for the file. If setting with this name already exists then skip.
///
/// Setting name.
/// Default value for setting. Make sure to use type casting if not integer.
/// Description to write in the file for this setting.
protected void CreateSetting(string Key, object Value, string Desc)
{
if(_cfgData.ContainsKey(Key.ToLower().Trim()))
return;
CfgEntry e = new CfgEntry()
{
Key = Key,
Value = Value,
DefaultValue = Value,
Desc = Desc
};
_cfgData[Key.ToLower().Trim()] = e;
}
///
/// Read a 32 bit integer value from configuration file.
///
/// Name of the option.
/// Default value if config is missing this option or is invalid.
///
public int GetInt32(string Key, int Default)
{
Key = Key.ToLower().Trim();
if(string.IsNullOrEmpty(Key) || !_cfgData.ContainsKey(Key) || !(_cfgData[Key].Value is int))
return Default;
return (int)_cfgData[Key].Value;
}
///
/// Read a 32 bit unsigned integer value from configuration file.
///
/// Name of the option.
/// Default value if config is missing this option or is invalid.
///
public uint GetUInt32(string Key, uint Default)
{
Key = Key.ToLower().Trim();
if(string.IsNullOrEmpty(Key) || !_cfgData.ContainsKey(Key) || !(_cfgData[Key].Value is uint))
return Default;
return (uint)_cfgData[Key].Value;
}
///
/// Read a 64 bit integer value from configuration file.
///
/// Name of the option.
/// Default value if config is missing this option or is invalid.
///
public long GetInt64(string Key, long Default)
{
Key = Key.ToLower().Trim();
if(string.IsNullOrEmpty(Key) || !_cfgData.ContainsKey(Key) || !(_cfgData[Key].Value is long))
return Default;
return (long)_cfgData[Key].Value;
}
///
/// Read a 64 bit unsigned integer value from configuration file.
///
/// Name of the option.
/// Default value if config is missing this option or is invalid.
///
public ulong GetUInt64(string Key, ulong Default)
{
Key = Key.ToLower().Trim();
if(string.IsNullOrEmpty(Key) || !_cfgData.ContainsKey(Key) || !(_cfgData[Key].Value is ulong))
return Default;
return (ulong)_cfgData[Key].Value;
}
///
/// Read a float value from configuration file.
///
/// Name of the option.
/// Default value if config is missing this option or is invalid.
///
public float GetFloat(string Key, float Default)
{
Key = Key.ToLower().Trim();
if(string.IsNullOrEmpty(Key) || !_cfgData.ContainsKey(Key) || !(_cfgData[Key].Value is float))
return Default;
return (float)_cfgData[Key].Value;
}
///
/// Read a double value from configuration file.
///
/// Name of the option.
/// Default value if config is missing this option or is invalid.
///
public double GetDouble(string Key, double Default)
{
Key = Key.ToLower().Trim();
if(string.IsNullOrEmpty(Key) || !_cfgData.ContainsKey(Key) || !(_cfgData[Key].Value is double))
return Default;
return (double)_cfgData[Key].Value;
}
///
/// Read a string value from configuration file.
///
/// Name of the option.
/// Default value if config is missing this option or is invalid.
///
public string GetString(string Key, string Default)
{
Key = Key.ToLower().Trim();
if(string.IsNullOrEmpty(Key) || !_cfgData.ContainsKey(Key) || !(_cfgData[Key].Value is string))
return Default;
return (string)_cfgData[Key].Value;
}
private Dictionary _cfgData = new Dictionary();
private class CfgEntry
{
public string Key;
public object Value;
public object DefaultValue;
public string Desc;
}
}
}