Skip to content

Commit

Permalink
feat: require argument for config export to include urls (#160)
Browse files Browse the repository at this point in the history
Co-authored-by: Rasmus Karlsson <[email protected]>
  • Loading branch information
iProdigy and pajlada authored Feb 4, 2023
1 parent d87b390 commit c870998
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 11 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## Unreleased

- Major: Add Barbarian Assault high level gambling notifications. (#150)
- Minor: Add plugin config export and import chat commands. (#155)
- Minor: Add plugin config export and import chat commands. (#155, #160)
- Minor: Make time units of advanced settings more obvious in the user interface. (#158)
- Minor: Clean up setting tooltips that stretched too wide, making them difficult to read. (#151)
- Minor: Add warning when in-game kill count chat spam filter is enabled. (#154)
Expand Down
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,26 @@ Some notifiers require in-game settings to be configured to send chat messages u

Dink allows you to export your current plugin configuration to the clipboard via the `::dinkexport` chat command.

This export includes *every* setting from individual notifiers to the webhook URLs.
You can share this produced JSON to friends who want to send similarly configured messages.

This export includes settings across all of the notifiers, but omits webhook URLs. If you also want to include webhook URLs in the export, you can use the `all` parameter to the command: `::dinkexport all`.

If you *only* want to export the webhook URLs, run the `::dinkexport webhooks` chat command.

You can export just the settings for select notifiers.
Simply run: `::dinkexport <notifier section header name without spaces>`.
For example: `::dinkexport pet` or `::dinkexport collectionlog`.

#### Examples
- Export notifier settings, primary webhook URLs & webhook override URLs
`::dinkexport all`
- Export Slayer & BA Gambles Notifier settings
`::dinkexport slayer bagambles`
- Export webhook overrides only
`::dinkexport webhookoverrides`
- Export all webhooks & the Levels notifier settings:
`::dinkexport webhooks levels`

You can share this produced JSON to friends who want to send similarly configured messages to the same webhook URLs.

### Import Configuration via `::dinkimport`

Expand All @@ -63,7 +80,7 @@ If you would like all settings overwritten rather than merged during import, sim

After an import, if the dink plugin settings panel was open, simply close and open it for the updated configuration to be reflected in the user interface.

Note: There is no undo button for this command, so consider making a backup of your current Dink configuration by using the `::dinkexport` command explained above and saving that to a file on your computer.
Note: There is no undo button for this command, so consider making a backup of your current Dink configuration by using the `::dinkexport all` command explained above and saving that to a file on your computer.

Warning: If you import override URLs for a notifier (that previously did not have any overrides), this will result in the plugin no longer sending messages from that notifier to your old primary URLs.
As such, you can manually add your primary URLs to the newly populated override URL boxes so that notifications are still sent to the old primary URLs.
Expand Down
62 changes: 55 additions & 7 deletions src/main/java/dinkplugin/SettingsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import net.runelite.client.events.ConfigChanged;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.VisibleForTesting;

import javax.inject.Inject;
Expand All @@ -33,6 +34,7 @@
import java.util.Objects;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static dinkplugin.util.ConfigUtil.*;
Expand All @@ -44,9 +46,18 @@ public class SettingsManager {
private static final String CONFIG_GROUP = "dinkplugin";

/**
* Maps our setting keys to their type for safe serialization & deserialization
* Maps our setting keys to their type for safe serialization and deserialization.
*/
private final Map<String, Type> configValueTypes = new HashMap<>();

/**
* Maps section names to the corresponding config item keys to allow for selective export.
*/
private final Map<String, Collection<String>> keysBySection = new HashMap<>();

/**
* User-specified RSNs that should not trigger webhook notifications.
*/
private final Collection<String> ignoredNames = new HashSet<>();

private final Gson gson;
Expand All @@ -70,16 +81,52 @@ public boolean isNamePermitted(String name) {
@VisibleForTesting
public void init() {
setIgnoredNames(config.ignoredNames());
configManager.getConfigDescriptor(config).getItems()
.forEach(item -> configValueTypes.put(item.key(), item.getType()));
configManager.getConfigDescriptor(config).getItems().forEach(item -> {
String key = item.key();
configValueTypes.put(key, item.getType());

String section = item.getItem().section();
if (StringUtils.isNotEmpty(section)) {
keysBySection.computeIfAbsent(
section.toLowerCase().replace(" ", ""),
s -> new HashSet<>()
).add(key);
}
});
}

void onCommand(CommandExecuted event) {
String cmd = event.getCommand();
if ("dinkimport".equalsIgnoreCase(cmd)) {
if ("DinkImport".equalsIgnoreCase(cmd)) {
importConfig();
} else if ("dinkexport".equalsIgnoreCase(cmd)) {
exportConfig();
} else if ("DinkExport".equalsIgnoreCase(cmd)) {
String[] args = event.getArguments();

Predicate<String> includeKey;
if (args == null || args.length == 0) {
includeKey = k -> !WEBHOOK_CONFIG_KEYS.contains(k);
} else {
includeKey = k -> false;

for (String arg : args) {
if ("all".equalsIgnoreCase(arg)) {
includeKey = k -> true;
break;
} else if ("webhooks".equalsIgnoreCase(arg)) {
includeKey = includeKey.or(WEBHOOK_CONFIG_KEYS::contains);
} else {
Collection<String> sectionKeys = keysBySection.get(arg.toLowerCase());
if (sectionKeys != null) {
includeKey = includeKey.or(sectionKeys::contains);
} else {
plugin.addChatWarning(String.format("Failed to identify config section to export: \"%s\"", arg));
return;
}
}
}
}

exportConfig(includeKey);
}
}

Expand Down Expand Up @@ -180,11 +227,12 @@ private void setIgnoredNames(String configValue) {
* which is copied to the user's clipboard in string form
*/
@Synchronized
private void exportConfig() {
private void exportConfig(@NotNull Predicate<String> exportKey) {
String prefix = CONFIG_GROUP + '.';
Map<String, Object> configMap = configManager.getConfigurationKeys(prefix)
.stream()
.map(prop -> prop.substring(prefix.length()))
.filter(exportKey)
.map(key -> Pair.of(key, configValueTypes.get(key)))
.filter(pair -> pair.getValue() != null)
.map(pair -> Pair.of(pair.getKey(), configManager.getConfiguration(CONFIG_GROUP, pair.getKey(), pair.getValue())))
Expand Down

0 comments on commit c870998

Please sign in to comment.