Problem
Set Homes Two never rewrites a config.yml that already exists (SetHomesTwo.initConfig, which returns early when the file is present). That is the right default, since it protects an admin's customisations, but it means every setting added in a later release is invisible to an upgrading server. The value silently falls back to its default and the admin cannot change a setting they cannot see.
This is not theoretical, and it is not a one-release problem. On a real test server upgrading through several releases:
- shipped
default-config.yml: 65 top-level keys
- that server's
config.yml: 21 keys, so 44 missing
Missing keys included teleportSafety, checkForUpdates, updateReminderDays, every home management GUI setting, and every message added since the file was written.
The README currently tells owners to copy keys out of default-config.yml by hand, or to rename their file and copy their old values back. Both work, and both are exactly the kind of chore that does not get done.
Proposed
A /update-config command that adds missing settings to the existing config.yml without touching anything already in it.
Requirements:
- Only add, never replace. An existing key keeps the admin's value, whatever it is.
- Preserve comments, both the admin's own and the shipped ones. The comments in
default-config.yml are the documentation for each setting, so a merge that strips them makes the result worse than the problem.
- Back up first, to something like
config.yml.bak, before writing.
- Idempotent. Running it twice adds nothing the second time.
- Report what it did, naming the keys added, and reload the config so a restart is not required.
- Gate on a new op-default permission, and add it to the
sh2.admin bundle.
The catch worth knowing before implementing
A naive key-level merge, for example config.options().copyDefaults(true) plus saveConfig(), would not have solved the case that prompted this issue.
The permissions: block, the one an admin most often needs to discover, is shipped entirely commented out:
# -- PERMISSIONS --
# ... 21 comment lines, 0 real keys ...
# permissions:
# sh2.import-homes: op
# sh2.manage-homes: false
There is no permissions key in the file, so no key-copying approach will ever bring it across. The same applies to any future commented-out example block.
So the merge has to work at the level of blocks of text, not keys. Suggested shape:
- Parse
default-config.yml into blocks, where a block is a run of comment lines plus the top-level key line and any indented children beneath it. Comment-only blocks, like the permissions example, count as blocks in their own right.
- Read the admin's
config.yml with YamlConfiguration to determine which top-level keys are already present. Use the parsed YAML rather than regex, so an unusually formatted file is still read correctly.
- Append each block whose key is absent, grouped under the
# -- SECTION -- headers default-config.yml already uses, writing a section header only when at least one block below it is being added.
- A comment-only block is added when none of the keys it documents are present.
Appending rather than merging in place means an admin who has reordered or restructured their file is never disturbed.
Alternatives considered
- Write
config.yml.new beside the existing file and let the admin diff and swap. Zero risk of damaging their file, but it puts the work back on them, which is what the issue is trying to remove. Reasonable fallback if the in-place merge proves fragile.
- Overwrite on upgrade. Not acceptable. It would destroy customisations.
Worth shipping alongside, and much cheaper
Whatever happens to the command, the plugin could log a warning at startup naming the count and the missing keys:
SetHomesTwo: your config.yml is missing 44 settings added in later releases.
Run /update-config, or copy them from default-config.yml.
That turns a silent gap into a visible one and is a few lines. It is arguably worth doing even if the command itself is never built.
Acceptance criteria
Notes
Found while running the in-game verification pass for the v1 parity and permission config work. Deliberately kept off that branch, which is finished and reviewed. This is its own feature and needs its own changeset.
Problem
Set Homes Two never rewrites a
config.ymlthat already exists (SetHomesTwo.initConfig, which returns early when the file is present). That is the right default, since it protects an admin's customisations, but it means every setting added in a later release is invisible to an upgrading server. The value silently falls back to its default and the admin cannot change a setting they cannot see.This is not theoretical, and it is not a one-release problem. On a real test server upgrading through several releases:
default-config.yml: 65 top-level keysconfig.yml: 21 keys, so 44 missingMissing keys included
teleportSafety,checkForUpdates,updateReminderDays, every home management GUI setting, and every message added since the file was written.The README currently tells owners to copy keys out of
default-config.ymlby hand, or to rename their file and copy their old values back. Both work, and both are exactly the kind of chore that does not get done.Proposed
A
/update-configcommand that adds missing settings to the existingconfig.ymlwithout touching anything already in it.Requirements:
default-config.ymlare the documentation for each setting, so a merge that strips them makes the result worse than the problem.config.yml.bak, before writing.sh2.adminbundle.The catch worth knowing before implementing
A naive key-level merge, for example
config.options().copyDefaults(true)plussaveConfig(), would not have solved the case that prompted this issue.The
permissions:block, the one an admin most often needs to discover, is shipped entirely commented out:There is no
permissionskey in the file, so no key-copying approach will ever bring it across. The same applies to any future commented-out example block.So the merge has to work at the level of blocks of text, not keys. Suggested shape:
default-config.ymlinto blocks, where a block is a run of comment lines plus the top-level key line and any indented children beneath it. Comment-only blocks, like the permissions example, count as blocks in their own right.config.ymlwithYamlConfigurationto determine which top-level keys are already present. Use the parsed YAML rather than regex, so an unusually formatted file is still read correctly.# -- SECTION --headersdefault-config.ymlalready uses, writing a section header only when at least one block below it is being added.Appending rather than merging in place means an admin who has reordered or restructured their file is never disturbed.
Alternatives considered
config.yml.newbeside the existing file and let the admin diff and swap. Zero risk of damaging their file, but it puts the work back on them, which is what the issue is trying to remove. Reasonable fallback if the in-place merge proves fragile.Worth shipping alongside, and much cheaper
Whatever happens to the command, the plugin could log a warning at startup naming the count and the missing keys:
That turns a silent gap into a visible one and is a few lines. It is arguably worth doing even if the command itself is never built.
Acceptance criteria
permissions:example is added when the admin has nopermissionsblock.default-config.ymland a changeset entry updated.Notes
Found while running the in-game verification pass for the v1 parity and permission config work. Deliberately kept off that branch, which is finished and reviewed. This is its own feature and needs its own changeset.