From 654ee9051222ceefff271cec8c1cd88238bcd2fa Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 17 Jan 2019 20:51:38 +0100 Subject: [PATCH 1/4] Add button to sync local config with remote Add button to info panel that will show when you are logged in to sync local configuration with remote. Signed-off-by: Tomas Slusny --- .../runelite/client/config/ConfigManager.java | 58 +++++++++++++++++- .../client/plugins/info/InfoPanel.java | 41 +++++++++++-- .../client/plugins/info/import_icon.png | Bin 0 -> 8483 bytes 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/info/import_icon.png diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 2cde4900ad..bb04cbec5f 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -111,12 +111,17 @@ public class ConfigManager load(); // load profile specific config } + private File getLocalPropertiesFile() + { + return new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME); + } + private File getPropertiesFile() { // Sessions that aren't logged in have no username if (session == null || session.getUsername() == null) { - return new File(RuneLite.RUNELITE_DIR, SETTINGS_FILE_NAME); + return getLocalPropertiesFile(); } else { @@ -184,6 +189,57 @@ public class ConfigManager } } + private synchronized void syncPropertiesFromFile(File propertiesFile) + { + final Properties properties = new Properties(); + try (FileInputStream in = new FileInputStream(propertiesFile)) + { + properties.load(new InputStreamReader(in, Charset.forName("UTF-8"))); + } + catch (Exception e) + { + log.debug("Malformed properties, skipping update"); + return; + } + + final Map copy = (Map) ImmutableMap.copyOf(this.properties); + copy.forEach((groupAndKey, value) -> + { + if (!properties.containsKey(groupAndKey)) + { + final String[] split = groupAndKey.split("\\.", 2); + if (split.length != 2) + { + return; + } + + final String groupName = split[0]; + final String key = split[1]; + unsetConfiguration(groupName, key); + } + }); + + properties.forEach((objGroupAndKey, objValue) -> + { + final String groupAndKey = String.valueOf(objGroupAndKey); + final String[] split = groupAndKey.split("\\.", 2); + if (split.length != 2) + { + return; + } + + final String groupName = split[0]; + final String key = split[1]; + final String value = String.valueOf(objValue); + setConfiguration(groupName, key, value); + }); + } + + public void importLocal() + { + syncPropertiesFromFile(getLocalPropertiesFile()); + } + private synchronized void loadFromFile() { properties.clear(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index 2edb250135..203b688b4e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -40,6 +40,7 @@ import javax.inject.Singleton; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import javax.swing.event.HyperlinkEvent; @@ -48,6 +49,7 @@ import net.runelite.api.events.SessionClose; import net.runelite.api.events.SessionOpen; import net.runelite.client.RuneLiteProperties; import net.runelite.client.account.SessionManager; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.ColorScheme; @@ -66,9 +68,12 @@ public class InfoPanel extends PluginPanel private static final ImageIcon DISCORD_ICON; private static final ImageIcon PATREON_ICON; private static final ImageIcon WIKI_ICON; + private static final ImageIcon IMPORT_ICON; private final JLabel loggedLabel = new JLabel(); private final JRichTextPane emailLabel = new JRichTextPane(); + private JPanel syncPanel; + private JPanel actionsContainer; @Inject @Nullable @@ -86,6 +91,9 @@ public class InfoPanel extends PluginPanel @Inject private ScheduledExecutorService executor; + @Inject + private ConfigManager configManager; + static { ARROW_RIGHT_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "/util/arrow_right.png")); @@ -93,6 +101,7 @@ public class InfoPanel extends PluginPanel DISCORD_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "discord_icon.png")); PATREON_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "patreon_icon.png")); WIKI_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "wiki_icon.png")); + IMPORT_ICON = new ImageIcon(ImageUtil.getResourceStreamFromClass(InfoPanel.class, "import_icon.png")); } void init() @@ -150,11 +159,22 @@ public class InfoPanel extends PluginPanel versionPanel.add(loggedLabel); versionPanel.add(emailLabel); - updateLoggedIn(); - - JPanel actionsContainer = new JPanel(); + actionsContainer = new JPanel(); actionsContainer.setBorder(new EmptyBorder(10, 0, 0, 0)); - actionsContainer.setLayout(new GridLayout(4, 1, 0, 10)); + actionsContainer.setLayout(new GridLayout(0, 1, 0, 10)); + + syncPanel = buildLinkPanel(IMPORT_ICON, "Import local settings", "to remote RuneLite account", () -> + { + final int result = JOptionPane.showOptionDialog(syncPanel, + "This will replace your current RuneLite account settings with settings from your local profile.", + "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, new String[]{"Yes", "No"}, "No"); + + if (result == JOptionPane.YES_OPTION) + { + configManager.importLocal(); + } + }); actionsContainer.add(buildLinkPanel(GITHUB_ICON, "Report an issue or", "make a suggestion", runeLiteProperties.getGithubLink())); actionsContainer.add(buildLinkPanel(DISCORD_ICON, "Talk to us on our", "discord server", runeLiteProperties.getDiscordInvite())); @@ -164,6 +184,7 @@ public class InfoPanel extends PluginPanel add(versionPanel, BorderLayout.NORTH); add(actionsContainer, BorderLayout.CENTER); + updateLoggedIn(); eventBus.register(this); } @@ -171,6 +192,14 @@ public class InfoPanel extends PluginPanel * Builds a link panel with a given icon, text and url to redirect to. */ private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, String url) + { + return buildLinkPanel(icon, topText, bottomText, () -> LinkBrowser.browse(url)); + } + + /** + * Builds a link panel with a given icon, text and callable to call. + */ + private static JPanel buildLinkPanel(ImageIcon icon, String topText, String bottomText, Runnable callback) { JPanel container = new JPanel(); container.setBackground(ColorScheme.DARKER_GRAY_COLOR); @@ -193,7 +222,6 @@ public class InfoPanel extends PluginPanel @Override public void mousePressed(MouseEvent mouseEvent) { - LinkBrowser.browse(url); container.setBackground(pressedColor); textContainer.setBackground(pressedColor); } @@ -201,6 +229,7 @@ public class InfoPanel extends PluginPanel @Override public void mouseReleased(MouseEvent e) { + callback.run(); container.setBackground(hoverColor); textContainer.setBackground(hoverColor); } @@ -252,12 +281,14 @@ public class InfoPanel extends PluginPanel emailLabel.setContentType("text/plain"); emailLabel.setText(name); loggedLabel.setText("Logged in as"); + actionsContainer.add(syncPanel, 0); } else { emailLabel.setContentType("text/html"); emailLabel.setText("Login to sync settings to the cloud."); loggedLabel.setText("Not logged in"); + actionsContainer.remove(syncPanel); } } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/info/import_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/info/import_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..32263bf15962b926d8c5862f0becbb3780753967 GIT binary patch literal 8483 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 Date: Fri, 22 Feb 2019 00:25:59 +0100 Subject: [PATCH 2/4] Backup RuneLite account settings before overwriting them Signed-off-by: Tomas Slusny --- .../runelite/client/config/ConfigManager.java | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index bb04cbec5f..78b84776a1 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -43,8 +43,11 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.nio.channels.FileLock; import java.nio.charset.Charset; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.time.Instant; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -70,6 +73,7 @@ import net.runelite.http.api.config.Configuration; public class ConfigManager { private static final String SETTINGS_FILE_NAME = "settings.properties"; + private static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); @Inject EventBus eventBus; @@ -179,7 +183,7 @@ public class ConfigManager try { - saveToFile(); + saveToFile(propertiesFile); log.debug("Updated configuration on disk with the latest version"); } @@ -237,6 +241,24 @@ public class ConfigManager public void importLocal() { + if (session == null) + { + // No session, no import + return; + } + + final File file = new File(propertiesFile.getParent(), propertiesFile.getName() + "." + TIME_FORMAT.format(new Date())); + + try + { + saveToFile(file); + } + catch (IOException e) + { + log.warn("Backup failed, skipping import", e); + return; + } + syncPropertiesFromFile(getLocalPropertiesFile()); } @@ -287,7 +309,7 @@ public class ConfigManager } } - private synchronized void saveToFile() throws IOException + private synchronized void saveToFile(final File propertiesFile) throws IOException { propertiesFile.getParentFile().mkdirs(); @@ -368,7 +390,7 @@ public class ConfigManager { try { - saveToFile(); + saveToFile(propertiesFile); } catch (IOException ex) { @@ -411,7 +433,7 @@ public class ConfigManager { try { - saveToFile(); + saveToFile(propertiesFile); } catch (IOException ex) { From 4e1e132985b7d7bf6d76d4231732e34461f15256 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Fri, 22 Feb 2019 00:39:17 +0100 Subject: [PATCH 3/4] Log config property changes only if they really change This prevents spam from previous property loading addition Signed-off-by: Tomas Slusny --- .../java/net/runelite/client/config/ConfigManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 78b84776a1..9ef92ed01c 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -372,8 +372,6 @@ public class ConfigManager public void setConfiguration(String groupName, String key, String value) { - log.debug("Setting configuration value for {}.{} to {}", groupName, key, value); - String oldValue = (String) properties.setProperty(groupName + "." + key, value); if (Objects.equals(oldValue, value)) @@ -381,6 +379,8 @@ public class ConfigManager return; } + log.debug("Setting configuration value for {}.{} to {}", groupName, key, value); + synchronized (pendingChanges) { pendingChanges.put(groupName + "." + key, value); @@ -415,8 +415,6 @@ public class ConfigManager public void unsetConfiguration(String groupName, String key) { - log.debug("Unsetting configuration value for {}.{}", groupName, key); - String oldValue = (String) properties.remove(groupName + "." + key); if (oldValue == null) @@ -424,6 +422,8 @@ public class ConfigManager return; } + log.debug("Unsetting configuration value for {}.{}", groupName, key); + synchronized (pendingChanges) { pendingChanges.put(groupName + "." + key, null); From 114422e3919d2ef50e955e84d4d4cca04c65a8b7 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Fri, 22 Feb 2019 00:54:48 +0100 Subject: [PATCH 4/4] Properly split config properties loaded from config client Some keys contain multiple dots (account-based, farming) and so this was setting incorrect value before. Signed-off-by: Tomas Slusny --- .../java/net/runelite/client/config/ConfigManager.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 9ef92ed01c..b24c9ccb96 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -167,7 +167,13 @@ public class ConfigManager for (ConfigEntry entry : configuration.getConfig()) { log.debug("Loading configuration value from client {}: {}", entry.getKey(), entry.getValue()); - final String[] split = entry.getKey().split("\\."); + final String[] split = entry.getKey().split("\\.", 2); + + if (split.length != 2) + { + continue; + } + final String groupName = split[0]; final String key = split[1]; final String value = entry.getValue();