Esempio n. 1
0
        /// <summary>
        ///     Unknown type, read only
        /// </summary>
        public void DrawUnknownField(PropSettingEntry setting)
        {
            // Try to use user-supplied converters
            if (setting.ObjToStr != null && setting.StrToObj != null)
            {
                var text   = setting.ObjToStr(setting.Get());
                var result = GUILayout.TextField(text);
                if (result != text)
                {
                    setting.Set(setting.StrToObj(result));
                }
                return;
            }

            // Fall back to slow/less reliable method
            var value = setting.Get()?.ToString() ?? "NULL";

            if (CanCovert(value, setting.SettingType))
            {
                var result = GUILayout.TextField(value);
                if (result != value)
                {
                    setting.Set(Convert.ChangeType(result, setting.SettingType));
                }
            }
            else
            {
                GUILayout.TextArea(value);
            }
        }
Esempio n. 2
0
        public void DrawRangeField(PropSettingEntry setting, AcceptableValueRangeAttribute range)
        {
            var value      = setting.Get();
            var converted  = (float)Convert.ToDouble(value);
            var leftValue  = (float)Convert.ToDouble(range.MinValue);
            var rightValue = (float)Convert.ToDouble(range.MaxValue);

            var result = GUILayout.HorizontalSlider(converted, leftValue, rightValue, GUILayout.ExpandWidth(true));

            if (Math.Abs(result - converted) > Mathf.Abs(rightValue - leftValue) / 1000)
            {
                var newValue = Convert.ChangeType(result, value.GetType());
                setting.Set(newValue);
            }

            if (range.ShowAsPercentage)
            {
                DrawCenteredLabel(
                    Mathf.Round(100 * Mathf.Abs(result - leftValue) / Mathf.Abs(rightValue - leftValue)) + "%",
                    GUILayout.Width(50));
            }
            else
            {
                DrawCenteredLabel(value.ToString(), GUILayout.Width(50));
            }
        }
Esempio n. 3
0
        public void DrawBoolField(PropSettingEntry setting)
        {
            var boolVal = (bool)setting.Get();
            var result  = GUILayout.Toggle(boolVal, boolVal ? "Enabled" : "Disabled", GUILayout.ExpandWidth(true));

            if (result != boolVal)
            {
                setting.Set(result);
            }
        }
        public void DrawKeyboardShortcut(PropSettingEntry setting)
        {
            var shortcut = (KeyboardShortcut)setting.Get();

            GUILayout.BeginHorizontal();
            {
                if (CurrentKeyboardShortcutToSet == setting)
                {
                    GUILayout.Label("Press any key combination", GUILayout.ExpandWidth(true));
                    GUIUtility.keyboardControl = -1;

                    foreach (var key in KeysToCheck)
                    {
                        if (Input.GetKeyUp(key))
                        {
                            shortcut.MainKey   = key;
                            shortcut.Modifiers = KeysToCheck.Where(Input.GetKey).OrderBy(x => x.ToString()).ToArray();

                            CurrentKeyboardShortcutToSet = null;
                            break;
                        }
                    }

                    if (GUILayout.Button("Cancel", GUILayout.ExpandWidth(false)))
                    {
                        CurrentKeyboardShortcutToSet = null;
                    }
                }
                else
                {
                    if (GUILayout.Button(shortcut.ToString(), GUILayout.ExpandWidth(true)))
                    {
                        CurrentKeyboardShortcutToSet = setting;
                    }

                    if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
                    {
                        setting.Set(KeyboardShortcut.Empty);
                        CurrentKeyboardShortcutToSet = null;
                    }
                }
            }
            GUILayout.EndHorizontal();
        }
Esempio n. 5
0
        public void DrawComboboxField(PropSettingEntry setting, IList list)
        {
            var buttonText = new GUIContent(setting.Get().ToString());
            var dispRect   = GUILayoutUtility.GetRect(buttonText, GUI.skin.button, GUILayout.ExpandWidth(true));

            if (!_comboBoxCache.TryGetValue(setting, out var box))
            {
                box = new ComboBox(dispRect, buttonText,
                                   list.Cast <object>().Select(x => new GUIContent(x.ToString())).ToArray(), GUI.skin.button);
                _comboBoxCache[setting] = box;
            }
            else
            {
                box.Rect          = dispRect;
                box.ButtonContent = buttonText;
            }

            var id = box.Show();

            if (id >= 0 && id < list.Count)
            {
                setting.Set(list[id]);
            }
        }
Esempio n. 6
0
 /// <summary>
 ///     Unknown type, read only
 /// </summary>
 public void DrawUnknownField(PropSettingEntry setting)
 {
     GUILayout.TextArea(setting.Get()?.ToString() ?? "NULL");
 }
Esempio n. 7
0
        public static void CollectSettings(out IEnumerable <PropSettingEntry> results, out List <string> modsWithoutSettings, bool showDebug)
        {
            var baseSettingType = typeof(ConfigWrapper <>);

            results             = Enumerable.Empty <PropSettingEntry>();
            modsWithoutSettings = new List <string>();
            foreach (var plugin in Utils.FindPlugins())
            {
                var type = plugin.GetType();

                var pluginInfo = MetadataHelper.GetMetadata(type);
                if (pluginInfo == null)
                {
                    ConfigurationManager.Logger.Log(LogLevel.Error, $"Plugin {type.FullName} is missing the BepInPlugin attribute!");
                    modsWithoutSettings.Add(type.FullName);
                    continue;
                }

                if (type.GetCustomAttributes(typeof(BrowsableAttribute), false).Cast <BrowsableAttribute>()
                    .Any(x => !x.Browsable))
                {
                    modsWithoutSettings.Add(pluginInfo.Name);
                    continue;
                }

                var detected = new List <PropSettingEntry>();

                // Config wrappers ------

                var settingProps = type
                                   .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                   .FilterBrowsable(true, true);

                var settingFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public)
                                    .Where(f => !f.IsSpecialName)
                                    .FilterBrowsable(true, true)
                                    .Select(f => new FieldToPropertyInfoWrapper(f));

                var settingEntries = settingProps.Concat(settingFields.Cast <PropertyInfo>())
                                     .Where(x => x.PropertyType.IsSubclassOfRawGeneric(baseSettingType));

                detected.AddRange(settingEntries.Select(x => PropSettingEntry.FromConfigWrapper(plugin, x, pluginInfo, plugin)).Where(x => x != null));

                // Config wrappers static ------

                var settingStaticProps = type
                                         .GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
                                         .FilterBrowsable(true, true);

                var settingStaticFields = type.GetFields(BindingFlags.Static | BindingFlags.Public)
                                          .Where(f => !f.IsSpecialName)
                                          .FilterBrowsable(true, true)
                                          .Select(f => new FieldToPropertyInfoWrapper(f));

                var settingStaticEntries = settingStaticProps.Concat(settingStaticFields.Cast <PropertyInfo>())
                                           .Where(x => x.PropertyType.IsSubclassOfRawGeneric(baseSettingType));

                detected.AddRange(settingStaticEntries.Select(x => PropSettingEntry.FromConfigWrapper(null, x, pluginInfo, plugin)).Where(x => x != null));

                // Normal properties ------

                bool IsPropSafeToShow(PropertyInfo p) => p.GetSetMethod()?.IsPublic == true && (p.PropertyType.IsValueType || p.PropertyType == typeof(string));

                var normalPropsSafeToShow = type
                                            .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
                                            .Where(IsPropSafeToShow)
                                            .FilterBrowsable(true, true)
                                            .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(baseSettingType));

                var normalPropsWithBrowsable = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
                                               .FilterBrowsable(true, false)
                                               .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(baseSettingType));

                var normalProps = normalPropsSafeToShow.Concat(normalPropsWithBrowsable).Distinct();

                detected.AddRange(normalProps.Select(x => PropSettingEntry.FromNormalProperty(plugin, x, pluginInfo, plugin)).Where(x => x != null));

                // Normal static properties ------

                var normalStaticPropsSafeToShow = type
                                                  .GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly)
                                                  .Where(IsPropSafeToShow)
                                                  .FilterBrowsable(true, true)
                                                  .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(baseSettingType));

                var normalStaticPropsWithBrowsable = type.GetProperties(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
                                                     .FilterBrowsable(true, false)
                                                     .Where(x => !x.PropertyType.IsSubclassOfRawGeneric(baseSettingType));

                var normalStaticProps = normalStaticPropsSafeToShow.Concat(normalStaticPropsWithBrowsable).Distinct();

                detected.AddRange(normalStaticProps.Select(x => PropSettingEntry.FromNormalProperty(null, x, pluginInfo, plugin)).Where(x => x != null));

                detected.RemoveAll(x => x.Browsable == false);

                if (!detected.Any())
                {
                    modsWithoutSettings.Add(pluginInfo.Name);
                }

                // Allow to enable/disable plugin if it uses any update methods ------
                if (showDebug && type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(x => _updateMethodNames.Contains(x.Name)))
                {
                    var enabledSetting =
                        PropSettingEntry.FromNormalProperty(plugin, type.GetProperty("enabled"), pluginInfo, plugin);
                    enabledSetting.DispName    = "!Allow plugin to run on every frame";
                    enabledSetting.Description =
                        "Disabling this will disable some or all of the plugin's functionality.\nHooks and event-based functionality will not be disabled.\nThis setting will be lost after game restart.";
                    enabledSetting.IsAdvanced = true;
                    detected.Add(enabledSetting);
                }

                if (detected.Any())
                {
                    var isAdvancedPlugin = type.GetCustomAttributes(typeof(AdvancedAttribute), false).Cast <AdvancedAttribute>()
                                           .Any(x => x.IsAdvanced);
                    if (isAdvancedPlugin)
                    {
                        detected.ForEach(entry => entry.IsAdvanced = true);
                    }

                    results = results.Concat(detected);
                }
            }
        }