| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 | using System;using System.Collections.Generic;using System.ComponentModel;using System.IO;using System.Linq;using Newtonsoft.Json;namespace InABox.Core{    public class UserProperty    {        [DoNotSerialize]        public Type Type { get; set; }        public object? Value { get; set; }    }    [Serializable]    public class UserProperties    {        public delegate void PropertyChangedEventHandler(object sender, string name, object? before, object? after);        public UserProperties()        {            Dictionary = new Dictionary<string, UserProperty>();            //_dictionary = new Dictionary<string, UserProperty>();        }        public Dictionary<string, UserProperty> Dictionary { get; set; }        //public Type ParentType { get; set; }        public object? this[string key]        {            get => Get(key);            set => Set(key, value);        }        [JsonIgnore]        public Dictionary<string, object?> AsDictionary        {            get            {                var result = new Dictionary<string, object?>();                foreach (var key in Dictionary.Keys)                    result[key] = this[key];                return result;            }            set            {                Clear();                foreach (var key in value.Keys)                    this[key] = value[key];            }        }        [JsonIgnore]        public int Count => Dictionary.Count;        public override bool Equals(object obj)        {            if (!(obj is UserProperties other))                return false;            if (Dictionary.Count != other.Count) // Require equal count.                return false;            foreach (var pair in Dictionary)                try                {                    var value = other[pair.Key];                    if (value == null)                    {                        if (pair.Value != null)                            return false;                    }                    else if (!value.Equals(pair.Value))                    {                        return false;                    }                }                catch                {                    return false;                }            return true;        }        public event PropertyChangedEventHandler? OnPropertyChanged;        private object? Get(string key)        {            var prop = new UserProperty { Type = typeof(string), Value = "" };            if (Dictionary.ContainsKey(key))                prop = Dictionary[key];            if (prop.Type == null)                return prop.Value;            if (prop.Value == null)                return prop.Type == typeof(object) ? null : Activator.CreateInstance(prop.Type);            if (prop.Value.GetType() == prop.Type)                return prop.Value;            var tc = TypeDescriptor.GetConverter(prop.Type);            return tc.ConvertFrom(prop.Value);        }        private void Set(string key, object? obj)        {            var before = Dictionary.GetValueOrDefault(key);            Dictionary[key] = new UserProperty { Type = obj?.GetType() ?? typeof(object), Value = obj };            OnPropertyChanged?.Invoke(this, key, before, obj);        }        public bool ContainsKey(string key)        {            return Dictionary.ContainsKey(key);        }        public void Clear()        {            Dictionary.Clear();        }        public string[] GetKeys()        {            return Dictionary.Keys.ToArray();        }        internal void LoadFromDictionary(Dictionary<string, object?> defaultProperties)        {            foreach (var pair in defaultProperties)                Dictionary[pair.Key] = new UserProperty { Type = pair.Value != null ? pair.Value.GetType() : typeof(object), Value = pair.Value };        }    }    public class UserPropertiesJsonConverter : JsonConverter    {        public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)        {            if (!(value is UserProperties props)) return;            writer.WriteStartObject();            foreach (var key in props.GetKeys())                if (props[key] != null)                {                    writer.WritePropertyName(key);                    writer.WriteValue(props[key] is string ? props[key] as string : props[key]);                }            writer.WriteEndObject();        }        public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)        {            var result = new UserProperties();            while (reader.TokenType != JsonToken.EndObject && reader.Read())                if (reader.Value != null)                {                    var key = reader.Value.ToString();                    reader.Read();                    result[key] = reader.Value;                }            return result;        }        public override bool CanConvert(Type objectType)        {            return objectType == typeof(UserProperties);        }    }}
 |