コード例 #1
0
        public override bool ParseCommand(ref string input, bool isFromRemote)
        {
            var inputCopy       = input;
            var parts           = input.Replace("  ", " ").Split(' ').ToList();
            var command         = parts.Count >= 1 ? parts[0] : null;
            var sectionPropPart = parts.Count >= 2 ? parts[1] : null;
            var valuePart       = parts.Count == 3 ? parts[2] : null;

            var    configParts = new List <string>();
            string sectionName = null;
            string valueName   = null;

            if (!string.IsNullOrEmpty(sectionPropPart))
            {
                configParts.AddRange(sectionPropPart.Split('.'));
                sectionName = configParts.Count >= 1 ? configParts[0] : null;
                valueName   = configParts.Count == 2 ? configParts[1] : null;
            }

            // Set input to nothing, so it won't be added again after our messages
            input = "";
            if (string.IsNullOrEmpty(valueName) && string.Equals(sectionName, "help", StringComparison.CurrentCultureIgnoreCase))
            {
                if (!isFromRemote)
                {
                    Console.instance.AddString("Usage:");
                    Console.instance.AddString("SetValue (get the list of sections)");
                    Console.instance.AddString("SetValue <SectionName> (get the list of values from that section)");
                    Console.instance.AddString("SetValue <SectionName>.<ValueName> (get information about that value)");
                    Console.instance.AddString("SetValue <SectionName>.<ValueName> <value> (set that value to <value>)");
                }

                return(false);
            }

            if (string.IsNullOrEmpty(sectionName))
            {
                Console.instance.AddString("List of configuration sections:");
                foreach (var property in Configuration.propertyCache)
                {
                    var syncable = typeof(ISyncableSection).IsAssignableFrom(property.PropertyType);
                    Console.instance.AddString($"{property.Name} \t\t{(syncable ? "Admin only" : "")}");
                }
            }


            if (!string.IsNullOrEmpty(sectionName) && string.IsNullOrEmpty(valuePart))
            {
                if (string.IsNullOrEmpty(valueName))
                {
                    // write info about section

                    var sectProperty =
                        Configuration.propertyCache.FirstOrDefault(x => string.Equals(x.Name, sectionName, StringComparison.CurrentCultureIgnoreCase));
                    if (sectProperty == null)
                    {
                        Console.instance.AddString($"No section {sectionName} available.");
                        return(false);
                    }

                    Console.instance.AddString($"Section {sectProperty.Name}");
                    Console.instance.AddString("Properties:");

                    var sectValue = sectProperty.GetValue(Configuration.Current, null);

                    foreach (var prop in BaseConfig.GetProps(sectProperty.PropertyType))
                    {
                        var val        = prop.GetValue(sectValue, null);
                        var valDefault = ((BaseConfig)sectValue).GetDefault(sectProperty.PropertyType, prop.Name);
                        Console.instance.AddString($"{prop.Name} {prop.PropertyType.Name} ({val}, default:{valDefault})");
                    }
                }
                else
                {
                    var sectProperty =
                        Configuration.propertyCache.FirstOrDefault(x => string.Equals(x.Name, sectionName, StringComparison.CurrentCultureIgnoreCase));
                    var valueProp = BaseConfig.GetProps(sectProperty.PropertyType)
                                    .FirstOrDefault(x => string.Equals(x.Name, valueName, StringComparison.CurrentCultureIgnoreCase));
                    var ca           = (ConfigurationAttribute)valueProp.GetCustomAttributes(false).FirstOrDefault(x => x is ConfigurationAttribute);
                    var valueComment = "";
                    if (ca != null)
                    {
                        valueComment = ca.Comment;
                    }

                    Console.instance.AddString($"Section {sectProperty.Name} value {valueProp.Name}, type {valueProp.PropertyType.Name}");

                    if (!string.IsNullOrEmpty(valueComment))
                    {
                        Console.instance.AddString(valueComment);
                    }
                }

                return(false);
            }

            if (parts.Count != 3)
            {
                if (!isFromRemote)
                {
                    Console.instance.AddString("Usage: SetValue <SectionName>.<ValueName> <value>");
                }

                return(false);
            }


            var sectionProperty =
                Configuration.propertyCache.FirstOrDefault(x => string.Equals(x.Name, sectionName, StringComparison.CurrentCultureIgnoreCase));

            if (sectionProperty == null)
            {
                if (!isFromRemote)
                {
                    Console.instance.AddString($"Section '{sectionName}' does not exist.");
                }

                return(false);
            }

            var section = sectionProperty.GetValue(Configuration.Current, null);

            var needsSync = typeof(ISyncableSection).IsAssignableFrom(sectionProperty.PropertyType);

            var valueProperty = BaseConfig.GetProps(sectionProperty.PropertyType)
                                .FirstOrDefault(x => string.Equals(x.Name, valueName, StringComparison.CurrentCultureIgnoreCase));

            if (valueProperty == null)
            {
                if (!isFromRemote)
                {
                    Console.instance.AddString($"Value '{valueName}' does not exist in section '{sectionName}'");
                }

                return(false);
            }

            // Switch for value type
            if (valueProperty.PropertyType == typeof(float))
            {
                var newValue = GetFloat(valuePart);
                var oldValue = (float)valueProperty.GetValue(section, null);


                if (!isFromRemote)
                {
                    Console.instance.Print($"Setting {sectionName}.{valueName} to {newValue} (old: {oldValue})");
                }

                if (needsSync && !isFromRemote)
                {
                    SyncToClients(inputCopy);
                }
                else if (needsSync == isFromRemote)
                {
                    valueProperty.SetValue(section, newValue, null);
                }

                return(true);
            }

            if (valueProperty.PropertyType == typeof(int))
            {
                var newValue = GetInt(valuePart);
                var oldValue = (int)valueProperty.GetValue(section, null);

                if (!isFromRemote)
                {
                    Console.instance.AddString($"Setting {sectionName}.{valueName} to {newValue} (old: {oldValue})");
                }

                if (needsSync && !isFromRemote)
                {
                    SyncToClients(inputCopy);
                }
                else if (needsSync == isFromRemote)
                {
                    valueProperty.GetSetMethod().Invoke(section, new object[] { newValue });
                    valueProperty.SetValue(section, newValue, null);
                }

                return(true);
            }

            if (valueProperty.PropertyType == typeof(KeyCode))
            {
                var newValue = GetKeyCode(valuePart);
                var oldValue = (KeyCode)valueProperty.GetValue(section, null);

                if (!isFromRemote)
                {
                    Console.instance.AddString($"Setting {sectionName}.{valueName} to {newValue} (old: {oldValue})");
                }

                if (needsSync && !isFromRemote)
                {
                    SyncToClients(inputCopy);
                }
                else if (needsSync == isFromRemote)
                {
                    valueProperty.SetValue(section, newValue, null);
                }

                return(true);
            }

            if (valueProperty.PropertyType == typeof(bool))
            {
                var newValue = GetBool(valuePart);
                var oldValue = (bool)valueProperty.GetValue(section, null);
                if (!isFromRemote)
                {
                    Console.instance.AddString($"Setting {sectionName}.{valueName} to {newValue} (old: {oldValue})");
                }

                if (needsSync && !isFromRemote)
                {
                    SyncToClients(inputCopy);
                }
                else if (needsSync == isFromRemote)
                {
                    valueProperty.SetValue(section, newValue, null);
                }

                return(true);
            }

            // If it got here, we done something weird in the configuration files
            // All types should be int,float, bool or KeyCode

            return(false);
        }