using System; using System.Collections.Generic; using System.Drawing; using NTERA.EmuEra.Game.EraEmu.Sub; namespace NTERA.EmuEra.Game.EraEmu.Config { internal abstract class AConfigItem { public AConfigItem(ConfigCode code, string text) { Code = code; Name = code.ToString(); Text = text; } public static ConfigItem Copy(ConfigItem other) { if(other == null) return null; ConfigItem ret = new ConfigItem(other.Code, other.Text, other.Value); ret.Fixed = other.Fixed; return ret; } public abstract void CopyTo(AConfigItem other); public abstract bool TryParse(string tokens); public abstract void SetValue(U p); public abstract U GetValue(); public abstract string ValueToString(); public readonly ConfigCode Code; public readonly string Name; public readonly string Text; public bool Fixed; } internal sealed class ConfigItem : AConfigItem { public ConfigItem(ConfigCode code,string text, T t):base(code, text) { val = t; } private T val; public T Value { get => val; set { if(Fixed) return; val = value; } } public override void CopyTo(AConfigItem other) { ConfigItem item = ((ConfigItem)other); item.Fixed = false; item.Value = Value; item.Fixed = Fixed; } public override void SetValue(U p) { //if (this is ConfigItem) ((ConfigItem)(AConfigItem)this).Value = p; //else // throw new ExeEE("型が一致しない"); } public override U GetValue() { ////if (this is ConfigItem) return ((ConfigItem)(AConfigItem)this).Value; //throw new ExeEE("型が一致しない"); } public override string ValueToString() { if(this is ConfigItem) { //ConfigItemをConfigItemに直接キャストすることはできない bool b = ((ConfigItem)(AConfigItem)this).Value; if (b) return "YES"; return "NO"; } if (this is ConfigItem) { Color c = ((ConfigItem)(AConfigItem)this).Value; return string.Format("{0},{1},{2}", c.R, c.G, c.B); } return val.ToString(); } public override string ToString() { return Text + ":" + ValueToString(); } /// ジェネリック化大失敗。なんかうまい方法ないかな~ public override bool TryParse(string param) { bool ret = false; if ((param == null) || (param.Length == 0)) return false; if(Fixed) return false; string str = param.Trim(); if (this is ConfigItem) { bool b = false; ret = tryStringToBool(str, ref b); if (ret)//ConfigItemをConfigItemに直接キャストすることはできない ((ConfigItem)(AConfigItem)this).Value = b; } else if (this is ConfigItem) { Color c; ret = tryStringsToColor(str, out c); if (ret) ((ConfigItem)(AConfigItem)this).Value = c; else throw new CodeEE("Value can not be recognized as Color specifier"); } else if (this is ConfigItem) { char c; ret = char.TryParse(str, out c); if (ret) ((ConfigItem)(AConfigItem)this).Value = c; } else if (this is ConfigItem) { Int32 i; ret = Int32.TryParse(str, out i); if (ret) ((ConfigItem)(AConfigItem)this).Value = i; else throw new CodeEE("Numeric config item contains non-numeric characters"); } else if (this is ConfigItem) { Int64 i; ret = Int64.TryParse(str, out i); if (ret) ((ConfigItem)(AConfigItem)this).Value = i; else throw new CodeEE("Numeric config item contains non-numeric characters"); } else if (this is ConfigItem>) { ((ConfigItem>)(AConfigItem)this).Value.Clear(); Int64 i; string[] strs = str.Split('/'); foreach (string st in strs) { ret = Int64.TryParse(st.Trim(), out i); if (ret) ((ConfigItem>)(AConfigItem)this).Value.Add(i); else { throw new CodeEE("Numeric config item contains non-numeric characters"); } } } else if (this is ConfigItem) { ret = true; ((ConfigItem)(AConfigItem)this).Value = str; } else if (this is ConfigItem>) { ret = true; ((ConfigItem>)(AConfigItem)this).Value.Add(str); } else if (this is ConfigItem) { str = str.ToUpper(); ret = Enum.IsDefined(typeof(TextDrawingMode), str); if (ret) { ((ConfigItem)(AConfigItem)this).Value = (TextDrawingMode)Enum.Parse(typeof(TextDrawingMode), str); } else throw new CodeEE("Invalid specification"); } else if (this is ConfigItem) { str = str.ToUpper(); ret = Enum.IsDefined(typeof(ReduceArgumentOnLoadFlag), str); if (ret) { ((ConfigItem)(AConfigItem)this).Value = (ReduceArgumentOnLoadFlag)Enum.Parse(typeof(ReduceArgumentOnLoadFlag), str); } else throw new CodeEE("Invalid specification"); } else if (this is ConfigItem) { str = str.ToUpper(); ret = Enum.IsDefined(typeof(DisplayWarningFlag), str); if (ret) { ((ConfigItem)(AConfigItem)this).Value = (DisplayWarningFlag)Enum.Parse(typeof(DisplayWarningFlag), str); } else throw new CodeEE("Invalid specification"); } else if (this is ConfigItem) { str = str.ToUpper(); ret = Enum.IsDefined(typeof(UseLanguage), str); if (ret) { ((ConfigItem)(AConfigItem)this).Value = (UseLanguage)Enum.Parse(typeof(UseLanguage), str); } else throw new CodeEE("Invalid specification"); } else if (this is ConfigItem) { str = str.ToUpper(); ret = Enum.IsDefined(typeof(TextEditorType), str); if (ret) { ((ConfigItem)(AConfigItem)this).Value = (TextEditorType)Enum.Parse(typeof(TextEditorType), str); } else throw new CodeEE("Invalid specification"); } //else // throw new ExeEE("型不明なコンフィグ"); return ret; } private bool tryStringToBool(string arg, ref bool p) { if (arg == null) return false; string str = arg.Trim(); int i = 0; if (Int32.TryParse(str, out i)) { p = (i != 0); return true; } if (str.Equals("NO", StringComparison.CurrentCultureIgnoreCase) || str.Equals("FALSE", StringComparison.CurrentCultureIgnoreCase) || str.Equals("後", StringComparison.CurrentCultureIgnoreCase))//"単位の位置"用 { p = false; return true; } if (str.Equals("YES", StringComparison.CurrentCultureIgnoreCase) || str.Equals("TRUE", StringComparison.CurrentCultureIgnoreCase) || str.Equals("前", StringComparison.CurrentCultureIgnoreCase)) { p = true; return true; } throw new CodeEE("Invalid specification"); } private bool tryStringsToColor(string str, out Color c) { string[] tokens = str.Split(','); c = Color.Black; int r, g, b; if (tokens.Length < 3) return false; if (!Int32.TryParse(tokens[0].Trim(), out r) || (r < 0) || (r > 255)) return false; if (!Int32.TryParse(tokens[1].Trim(), out g) || (g < 0) || (g > 255)) return false; if (!Int32.TryParse(tokens[2].Trim(), out b) || (b < 0) || (b > 255)) return false; c = Color.FromArgb(r, g, b); return true; } } }