コード例 #1
0
            public override void SetValueInConfig(string value)
            {
                var pluginConfig = BepInExUtils.GetDependentPlugins(true).First(x => x.Key == ModGUID).Value.Config;
                var entry        = pluginConfig[Section, Key];

                entry.BoxedValue = value;
            }
コード例 #2
0
            internal override string GetValueFromConfig()
            {
                var pluginConfig = BepInExUtils.GetDependentPlugins(true).First(x => x.Key == ModGUID).Value.Config;
                var entry        = pluginConfig[Section, Key];

                return((string)entry.BoxedValue);
            }
コード例 #3
0
        /// <summary>
        ///     Unlock configuration entries.
        /// </summary>
        private void UnlockConfigurationEntries()
        {
            var loadedPlugins = BepInExUtils.GetDependentPlugins(true);

            foreach (var plugin in loadedPlugins)
            {
                foreach (var configDefinition in plugin.Value.Config.Keys)
                {
                    var configEntry     = plugin.Value.Config[configDefinition.Section, configDefinition.Key];
                    var configAttribute = (ConfigurationManagerAttributes)configEntry.Description.Tags
                                          .FirstOrDefault(x => x is ConfigurationManagerAttributes {
                        IsAdminOnly: true
                    });
コード例 #4
0
        internal void SynchronizeToServer()
        {
            // Lets compare and send to server, if applicable
            var loadedPlugins = BepInExUtils.GetDependentPlugins();

            var valuesToSend = new List <Tuple <string, string, string, string> >();

            foreach (var plugin in loadedPlugins)
            {
                foreach (var cd in plugin.Value.Config.Keys)
                {
                    var cx = plugin.Value.Config[cd.Section, cd.Key];
                    if (cx.Description.Tags.Any(x =>
                                                x is ConfigurationManagerAttributes && ((ConfigurationManagerAttributes)x).IsAdminOnly &&
                                                ((ConfigurationManagerAttributes)x).UnlockSetting))
                    {
                        var value = new Tuple <string, string, string, string>(plugin.Value.Info.Metadata.GUID, cd.Section, cd.Key, cx.GetSerializedValue());
                        valuesToSend.Add(value);
                    }

                    if (cx.SettingType == typeof(KeyCode))
                    {
                        ZInput.instance.Setbutton(cd.Key + "!" + plugin.Value.Info.Metadata.GUID, (KeyCode)cx.BoxedValue);
                    }
                }
            }

            // We need only changed values
            valuesToSend = valuesToSend.Where(x => !cachedConfigValues.Contains(x)).ToList();

            // Send to server
            if (valuesToSend.Count > 0)
            {
                var zPackage = GenerateConfigZPackage(valuesToSend);

                // Send values to server if it isn't a local instance
                if (!ZNet.instance.IsLocalInstance())
                {
                    ZRoutedRpc.instance.InvokeRoutedRPC(ZNet.instance.GetServerPeer().m_uid, nameof(RPC_Jotunn_ApplyConfig), zPackage);
                }
                else
                {
                    // If it is a local instance, send it to all connected peers
                    foreach (var peer in ZNet.instance.m_peers)
                    {
                        ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, nameof(RPC_Jotunn_ApplyConfig), zPackage);
                    }
                }
            }
        }
コード例 #5
0
            public override KeyCode GetValue()
            {
                // TODO: Get and parse value from input field
                var pluginConfig = BepInExUtils.GetDependentPlugins(true).First(x => x.Key == ModGUID).Value.Config;
                var entry        = pluginConfig[Section, Key];
                var temp         = KeyCode.None;

                if (Enum.TryParse(gameObject.transform.Find("Button/Text").GetComponent <Text>().text, out temp))
                {
                    return(temp);
                }

                Logger.LogError($"Error parsing Keycode {gameObject.transform.Find("Button/Text").GetComponent<Text>().text}");
                return(temp);
            }
コード例 #6
0
        private void AutomaticLocalizationLoading()
        {
            var jsonFormat  = new HashSet <FileInfo>();
            var unityFormat = new HashSet <FileInfo>();

            // Json format community files
            foreach (var fileInfo in GetTranslationFiles(Paths.LanguageTranslationsFolder, CommunityTranslationFileName))
            {
                jsonFormat.Add(fileInfo);
            }

            foreach (var fileInfo in GetTranslationFiles(Paths.LanguageTranslationsFolder, "*.json"))
            {
                jsonFormat.Add(fileInfo);
            }

            foreach (var fileInfo in GetTranslationFiles(Paths.LanguageTranslationsFolder, "*.language"))
            {
                unityFormat.Add(fileInfo);
            }

            foreach (var fileInfo in jsonFormat)
            {
                try
                {
                    var mod = BepInExUtils.GetPluginInfoFromPath(fileInfo)?.Metadata;
                    GetLocalization(mod ?? Main.Instance.Info.Metadata).AddFileByPath(fileInfo.FullName, true);
                }
                catch (Exception ex)
                {
                    Logger.LogWarning($"Exception caught while loading localization file {fileInfo}: {ex}");
                }
            }

            foreach (var fileInfo in unityFormat)
            {
                try
                {
                    var mod = BepInExUtils.GetPluginInfoFromPath(fileInfo)?.Metadata;
                    GetLocalization(mod ?? Main.Instance.Info.Metadata).AddFileByPath(fileInfo.FullName);
                }
                catch (Exception ex)
                {
                    Logger.LogWarning($"Exception caught while loading localization file {fileInfo}: {ex}");
                }
            }
        }
コード例 #7
0
 /// <summary>
 ///     Get the CustomLocalization for your mod.
 ///     Creates a new <see cref="CustomLocalization"/> if no localization was added before.
 /// </summary>
 /// <returns>Existing or newly created <see cref="CustomLocalization"/>.</returns>
 public CustomLocalization GetLocalization()
 {
     return(GetLocalization(BepInExUtils.GetSourceModMetadata()));
 }
コード例 #8
0
 /// <summary>
 ///     Get a <see cref="CustomRPC"/> for your mod
 /// </summary>
 /// <param name="name">Unique name for your RPC</param>
 /// <param name="serverReceive">Delegate which gets called on client instances when packages are received</param>
 /// <param name="clientReceive">Delegate which gets called on server instances when packages are received</param>
 /// <returns>Existing or newly created <see cref="CustomRPC"/></returns>
 public CustomRPC AddRPC(string name, CoroutineHandler serverReceive, CoroutineHandler clientReceive)
 {
     return(AddRPC(BepInExUtils.GetSourceModMetadata(), name, serverReceive, clientReceive));
 }
コード例 #9
0
        /// <summary>
        ///     Create custom configuration tab
        /// </summary>
        private static void CreateModConfigTab()
        {
            bool anyConfig = BepInExUtils.GetDependentPlugins(true).Any(x => GetConfigurationEntries(x.Value).GroupBy(x => x.Key.Section).Any());

            if (!anyConfig)
            {
                return;
            }

            // Hook SaveSettings to be notified when OK was pressed
            On.Settings.SaveSettings += Settings_SaveSettings;

            // Copy the Misc tab button
            var tabButtonCopy = Object.Instantiate(settingsRoot.transform.Find("panel/TabButtons/Misc").gameObject,
                                                   settingsRoot.transform.Find("panel/TabButtons"));

            var tabHandler = settingsRoot.transform.Find("panel/TabButtons").GetComponent <TabHandler>();

            // and set it's new property values
            tabButtonCopy.name = "ModConfig";
            tabButtonCopy.transform.Find("Text").GetComponent <Text>().text = "ModConfig";
            tabButtonCopy.transform.Find("Selected/Text (1)").GetComponent <Text>().text = "ModConfig";

            // Rearrange/center settings tab buttons (Valheim had an offset to the right.....)
            var numChildren = settingsRoot.transform.Find("panel/TabButtons").childCount;
            var width       = settingsRoot.transform.Find("panel/TabButtons").GetComponent <RectTransform>().rect.width;

            for (var i = 0; i < numChildren; i++)
            {
                settingsRoot.transform.Find("panel/TabButtons").GetChild(i).GetComponent <RectTransform>().anchoredPosition = new Vector2(
                    (width - numChildren * 100f) / 2f + i * 100f + 50f,
                    settingsRoot.transform.Find("panel/TabButtons").GetChild(i).GetComponent <RectTransform>().anchoredPosition.y);
            }


            // Add the tab

            var tab = settingsRoot.transform.Find("panel/Tabs").gameObject;

            // Create the content scroll view
            configTab = GUIManager.Instance.CreateScrollView(tab.transform, false, true, 8f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock,
                                                             new Color(0, 0, 0, 1), tab.GetComponent <RectTransform>().rect.width - 50f, tab.GetComponent <RectTransform>().rect.height - 50f)
                        .SetMiddleCenter();

            configTab.name = "ModConfig";

            // configure the ui group handler
            var groupHandler = configTab.AddComponent <UIGroupHandler>();

            groupHandler.m_groupPriority = 10;
            groupHandler.m_canvasGroup   = configTab.GetComponent <CanvasGroup>();
            groupHandler.m_canvasGroup.ignoreParentGroups = true;
            groupHandler.m_canvasGroup.blocksRaycasts     = true;
            groupHandler.Update();

            // create ok and back button (just copy them from Controls tab)
            var ok = Object.Instantiate(settingsRoot.transform.Find("panel/Tabs/Controls/Ok").gameObject, configTab.transform);

            ok.GetComponent <RectTransform>().anchoredPosition = ok.GetComponent <RectTransform>().anchoredPosition - new Vector2(0, 25f);
            ok.GetComponent <Button>().onClick.AddListener(() =>
            {
                Settings.instance.OnOk();

                // After applying ingame values, lets synchronize any changed (and unlocked) values
                SynchronizationManager.Instance.SynchronizeToServer();

                // remove reference to gameobject
                settingsRoot = null;
                configTab    = null;
            });

            var back = Object.Instantiate(settingsRoot.transform.Find("panel/Tabs/Controls/Back").gameObject, configTab.transform);

            back.GetComponent <RectTransform>().anchoredPosition = back.GetComponent <RectTransform>().anchoredPosition - new Vector2(0, 25f);
            back.GetComponent <Button>().onClick.AddListener(() =>
            {
                Settings.instance.OnBack();

                // remove reference to gameobject
                settingsRoot = null;
                configTab    = null;
            });

            // initially hide the configTab
            configTab.SetActive(false);

            // Add a new Tab to the TabHandler
            var newTab = new TabHandler.Tab();

            newTab.m_default = false;
            newTab.m_button  = tabButtonCopy.GetComponent <Button>();
            newTab.m_page    = configTab.GetComponent <RectTransform>();
            newTab.m_onClick = new UnityEvent();
            newTab.m_onClick.AddListener(() =>
            {
                configTab.GetComponent <UIGroupHandler>().SetActive(true);
                configTab.SetActive(true);
                configTab.transform.Find("Scroll View").GetComponent <ScrollRect>().normalizedPosition = new Vector2(0, 1);
            });

            // Add the onClick of the tabhandler to the tab button
            tabButtonCopy.GetComponent <Button>().onClick.AddListener(() => tabHandler.OnClick(newTab.m_button));

            // and add the new Tab to the tabs list
            tabHandler.m_tabs.Add(newTab);

            var innerWidth = configTab.GetComponent <RectTransform>().rect.width - 25f;

            // Iterate over all dependent plugins (including Jotunn itself)
            foreach (var mod in BepInExUtils.GetDependentPlugins(true))
            {
                // Create a header if there are any relevant configuration entries
                // TODO: dont count hidden ones
                if (GetConfigurationEntries(mod.Value).GroupBy(x => x.Key.Section).Any())
                {
                    // Create module header Text element
                    var text = GUIManager.Instance.CreateText(mod.Key, configTab.transform.Find("Scroll View/Viewport/Content"), new Vector2(0.5f, 0.5f),
                                                              new Vector2(0.5f, 0.5f), new Vector2(0, 0), GUIManager.Instance.AveriaSerifBold, 20, Color.white, true, Color.black,
                                                              configTab.GetComponent <RectTransform>().rect.width, 50, false);
                    text.GetComponent <RectTransform>().pivot           = new Vector2(0.5f, 0.5f);
                    text.GetComponent <Text>().alignment                = TextAnchor.MiddleCenter;
                    text.AddComponent <LayoutElement>().preferredHeight = 40f;
                }

                // Iterate over all configuration entries (grouped by their sections)
                // TODO: again, don't show hidden ones, helper function!
                foreach (var kv in GetConfigurationEntries(mod.Value).GroupBy(x => x.Key.Section))
                {
                    // Create section header Text element
                    var sectiontext = GUIManager.Instance.CreateText("Section " + kv.Key, configTab.transform.Find("Scroll View/Viewport/Content"),
                                                                     new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0, 0), GUIManager.Instance.AveriaSerifBold, 16,
                                                                     GUIManager.Instance.ValheimOrange, true, Color.black, configTab.GetComponent <RectTransform>().rect.width, 30, false);
                    sectiontext.SetMiddleCenter();
                    sectiontext.GetComponent <RectTransform>().anchoredPosition = new Vector2(0, 0);
                    sectiontext.GetComponent <Text>().alignment = TextAnchor.MiddleCenter;
                    sectiontext.AddComponent <LayoutElement>().preferredHeight = 30f;

                    // Iterate over all entries of this section
                    foreach (var entry in
                             kv.OrderByDescending(x =>
                    {
                        if (x.Value.Description.Tags.FirstOrDefault(y => y is ConfigurationManagerAttributes) is ConfigurationManagerAttributes cma)
                        {
                            return(cma.Order ?? 0);
                        }

                        return(0);
                    }).ThenBy(x => x.Key.Key))
                    {
                        // Create config entry
                        // switch by type

                        if (entry.Value.SettingType == typeof(bool))
                        {
                            // Create toggle element
                            var go = CreateToggleElement(configTab.transform.Find("Scroll View/Viewport/Content"), entry.Key.Key + ":",
                                                         entry.Value.Description.Description, mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key, innerWidth);
                            SetProperties(go.GetComponent <ConfigBoundBoolean>(), entry);
                        }
                        else if (entry.Value.SettingType == typeof(int))
                        {
                            var description = entry.Value.Description.Description;
                            if (entry.Value.Description.AcceptableValues != null)
                            {
                                description += Environment.NewLine + "(" +
                                               entry.Value.Description.AcceptableValues.ToDescriptionString().TrimStart('#').Trim() + ")";
                            }

                            // Create input field int
                            var go = CreateTextInputField(configTab.transform.Find("Scroll View/Viewport/Content"), entry.Key.Key + ":", description,
                                                          mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key, innerWidth);
                            go.AddComponent <ConfigBoundInt>().SetData(mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key);
                            go.transform.Find("Input").GetComponent <InputField>().characterValidation = InputField.CharacterValidation.Integer;
                            SetProperties(go.GetComponent <ConfigBoundInt>(), entry);
                            go.transform.Find("Input").GetComponent <InputField>().onValueChanged.AddListener(x =>
                            {
                                go.transform.Find("Input").GetComponent <InputField>().textComponent.color =
                                    go.GetComponent <ConfigBoundInt>().IsValid() ? Color.white : Color.red;
                            });
                        }
                        else if (entry.Value.SettingType == typeof(float))
                        {
                            var description = entry.Value.Description.Description;
                            if (entry.Value.Description.AcceptableValues != null)
                            {
                                description += Environment.NewLine + "(" +
                                               entry.Value.Description.AcceptableValues.ToDescriptionString().TrimStart('#').Trim() + ")";
                            }

                            // Create input field float
                            var go = CreateTextInputField(configTab.transform.Find("Scroll View/Viewport/Content"), entry.Key.Key + ":", description,
                                                          mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key, innerWidth);
                            go.AddComponent <ConfigBoundFloat>().SetData(mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key);
                            go.transform.Find("Input").GetComponent <InputField>().characterValidation = InputField.CharacterValidation.Decimal;
                            SetProperties(go.GetComponent <ConfigBoundFloat>(), entry);
                            go.transform.Find("Input").GetComponent <InputField>().onValueChanged.AddListener(x =>
                            {
                                go.transform.Find("Input").GetComponent <InputField>().textComponent.color =
                                    go.GetComponent <ConfigBoundFloat>().IsValid() ? Color.white : Color.red;
                            });
                        }
                        else if (entry.Value.SettingType == typeof(KeyCode))
                        {
                            // Create key binder
                            var go = CreateKeybindElement(configTab.transform.Find("Scroll View/Viewport/Content"), entry.Key.Key + ":",
                                                          entry.Value.Description.Description, mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key, innerWidth);
                            go.GetComponent <ConfigBoundKeyCode>().SetData(mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key);
                            SetProperties(go.GetComponent <ConfigBoundKeyCode>(), entry);
                        }
                        else if (entry.Value.SettingType == typeof(string))
                        {
                            // Create input field string
                            var go = CreateTextInputField(configTab.transform.Find("Scroll View/Viewport/Content"), entry.Key.Key + ":",
                                                          entry.Value.Description.Description, mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key, innerWidth);
                            go.AddComponent <ConfigBoundString>().SetData(mod.Value.Info.Metadata.GUID, entry.Key.Section, entry.Key.Key);
                            go.transform.Find("Input").GetComponent <InputField>().characterValidation = InputField.CharacterValidation.None;
                            SetProperties(go.GetComponent <ConfigBoundString>(), entry);
                        }
                    }
                }
            }
        }
コード例 #10
0
 /// <summary>
 ///     ctor automatically getting the SourceMod
 /// </summary>
 internal CustomEntity()
 {
     SourceMod = BepInExUtils.GetSourceModMetadata();
 }