From 65f4b33f6273b64230c78e55b7ea4bcdbccbb655 Mon Sep 17 00:00:00 2001 From: Kyleeld <48519776+Kyleeld@users.noreply.github.com> Date: Wed, 24 Apr 2019 02:02:13 +0100 Subject: [PATCH] Add encryption to account data - thx ThatGamerBlue --- .../client/plugins/profiles/ProfilePanel.java | 239 +++--- .../plugins/profiles/ProfilesConfig.java | 111 ++- .../plugins/profiles/ProfilesPanel.java | 759 ++++++++++++------ .../plugins/profiles/ProfilesPlugin.java | 198 +++-- 4 files changed, 864 insertions(+), 443 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java index cf27d2b78d..f8e92fbf36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilePanel.java @@ -1,15 +1,37 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019, Spedwards + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.runelite.client.plugins.profiles; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JLabel; @@ -17,107 +39,140 @@ import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.client.ui.ColorScheme; import net.runelite.client.util.ImageUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -class ProfilePanel -extends JPanel { - private static final Logger log = LoggerFactory.getLogger(ProfilePanel.class); - private static final ImageIcon DELETE_ICON; - private static final ImageIcon DELETE_HOVER_ICON; - private final String loginText; - private String password = null; +@Slf4j +class ProfilePanel extends JPanel +{ + private static final ImageIcon DELETE_ICON; + private static final ImageIcon DELETE_HOVER_ICON; - ProfilePanel(final Client client, final String data, final ProfilesConfig config) { - String[] parts = data.split(":"); - this.loginText = parts[1]; - if (parts.length == 3) { - this.password = parts[2]; - } - final ProfilePanel panel = this; - this.setLayout(new BorderLayout()); - this.setBackground(ColorScheme.DARKER_GRAY_COLOR); - JPanel labelWrapper = new JPanel(new BorderLayout()); - labelWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR); - labelWrapper.setBorder(new CompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR), BorderFactory.createLineBorder(ColorScheme.DARKER_GRAY_COLOR))); - JPanel panelActions = new JPanel(new BorderLayout(3, 0)); - panelActions.setBorder(new EmptyBorder(0, 0, 0, 8)); - panelActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); - final JLabel delete = new JLabel(); - delete.setIcon(DELETE_ICON); - delete.setToolTipText("Delete account profile"); - delete.addMouseListener(new MouseAdapter(){ + static + { + final BufferedImage deleteImg = ImageUtil.getResourceStreamFromClass(ProfilesPlugin.class, "delete_icon.png"); + DELETE_ICON = new ImageIcon(deleteImg); + DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, -100)); + } - @Override - public void mousePressed(MouseEvent e) { - panel.getParent().remove(panel); - ProfilesPanel.removeProfile(data); - } + private final String loginText; + private final ProfilesPanel parent; + private String password = null; - @Override - public void mouseEntered(MouseEvent e) { - delete.setIcon(DELETE_HOVER_ICON); - } + ProfilePanel(final Client client, String data, ProfilesConfig config, ProfilesPanel parent) + { + this.parent = parent; + String[] parts = data.split(":"); + this.loginText = parts[1]; + if (parts.length == 3) + { + this.password = parts[2]; + } - @Override - public void mouseExited(MouseEvent e) { - delete.setIcon(DELETE_ICON); - } - }); - panelActions.add((Component)delete, "East"); - JLabel label = new JLabel(); - label.setText(parts[0]); - label.setBorder(null); - label.setBackground(ColorScheme.DARKER_GRAY_COLOR); - label.setPreferredSize(new Dimension(0, 24)); - label.setForeground(Color.WHITE); - label.setBorder(new EmptyBorder(0, 8, 0, 0)); - labelWrapper.add((Component)label, "Center"); - labelWrapper.add((Component)panelActions, "East"); - label.addMouseListener(new MouseAdapter(){ + final ProfilePanel panel = this; - @Override - public void mousePressed(MouseEvent e) { - if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) { - client.setUsername(ProfilePanel.this.loginText); - if (config.rememberPassword() && ProfilePanel.this.password != null) { - client.setPassword(ProfilePanel.this.password); - } - } - } - }); - JPanel bottomContainer = new JPanel(new BorderLayout()); - bottomContainer.setBorder(new EmptyBorder(8, 0, 8, 0)); - bottomContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); - bottomContainer.addMouseListener(new MouseAdapter(){ + setLayout(new BorderLayout()); + setBackground(ColorScheme.DARKER_GRAY_COLOR); - @Override - public void mousePressed(MouseEvent e) { - if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) { - client.setUsername(ProfilePanel.this.loginText); - } - } - }); - JLabel login = new JLabel(); - login.setText(config.isStreamerMode() ? "Hidden email" : this.loginText); - login.setBorder(null); - login.setPreferredSize(new Dimension(0, 24)); - login.setForeground(Color.WHITE); - login.setBorder(new EmptyBorder(0, 8, 0, 0)); - bottomContainer.add((Component)login, "Center"); - this.add((Component)labelWrapper, "North"); - this.add((Component)bottomContainer, "Center"); - } + JPanel labelWrapper = new JPanel(new BorderLayout()); + labelWrapper.setBackground(ColorScheme.DARKER_GRAY_COLOR); + labelWrapper.setBorder(new CompoundBorder( + BorderFactory.createMatteBorder(0, 0, 1, 0, ColorScheme.DARK_GRAY_COLOR), + BorderFactory.createLineBorder(ColorScheme.DARKER_GRAY_COLOR) + )); - static { - BufferedImage deleteImg = ImageUtil.getResourceStreamFromClass(ProfilesPlugin.class, "net/runelite/client/plugins/profiles/delete_icon.png"); - DELETE_ICON = new ImageIcon(deleteImg); - DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, -100)); - } + JPanel panelActions = new JPanel(new BorderLayout(3, 0)); + panelActions.setBorder(new EmptyBorder(0, 0, 0, 8)); + panelActions.setBackground(ColorScheme.DARKER_GRAY_COLOR); + JLabel delete = new JLabel(); + delete.setIcon(DELETE_ICON); + delete.setToolTipText("Delete account profile"); + delete.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + panel.getParent().remove(panel); + try + { + parent.removeProfile(data); + } + catch (InvalidKeySpecException | NoSuchAlgorithmException ex) + { + ex.printStackTrace(); + } + } + + @Override + public void mouseEntered(MouseEvent e) + { + delete.setIcon(DELETE_HOVER_ICON); + } + + @Override + public void mouseExited(MouseEvent e) + { + delete.setIcon(DELETE_ICON); + } + }); + + panelActions.add(delete, BorderLayout.EAST); + + JLabel label = new JLabel(); + label.setText(parts[0]); + label.setBorder(null); + label.setBackground(ColorScheme.DARKER_GRAY_COLOR); + label.setPreferredSize(new Dimension(0, 24)); + label.setForeground(Color.WHITE); + label.setBorder(new EmptyBorder(0, 8, 0, 0)); + + labelWrapper.add(label, BorderLayout.CENTER); + labelWrapper.add(panelActions, BorderLayout.EAST); + label.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) + { + client.setUsername(loginText); + if (config.rememberPassword() && password != null) + { + client.setPassword(password); + } + } + } + }); + + JPanel bottomContainer = new JPanel(new BorderLayout()); + bottomContainer.setBorder(new EmptyBorder(8, 0, 8, 0)); + bottomContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR); + bottomContainer.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + if (SwingUtilities.isLeftMouseButton(e) && client.getGameState() == GameState.LOGIN_SCREEN) + { + client.setUsername(loginText); + } + } + }); + + JLabel login = new JLabel(); + login.setText(config.isStreamerMode() ? "Hidden email" : loginText); + login.setBorder(null); + login.setPreferredSize(new Dimension(0, 24)); + login.setForeground(Color.WHITE); + login.setBorder(new EmptyBorder(0, 8, 0, 0)); + + bottomContainer.add(login, BorderLayout.CENTER); + + add(labelWrapper, BorderLayout.NORTH); + add(bottomContainer, BorderLayout.CENTER); + } } - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java index 2d6b171919..0ad47fc7ce 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesConfig.java @@ -1,5 +1,26 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019, Spedwards + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.runelite.client.plugins.profiles; @@ -7,30 +28,74 @@ import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -@ConfigGroup(value="profiles") -public interface ProfilesConfig -extends Config { - @ConfigItem(keyName="profilesData", name="", description="", hidden=true) - default public String profilesData() { - return ""; - } +@ConfigGroup("profiles") +public interface ProfilesConfig extends Config +{ - @ConfigItem(keyName="profilesData", name="", description="") - public void profilesData(String var1); - @ConfigItem(keyName="rememberPassword", name="Remember Password", description="Remembers passwords for accounts") - default public boolean rememberPassword() { - return true; - } + @ConfigItem( + keyName = "profilesData", + name = "", + description = "", + hidden = true + ) + default String profilesData() + { + return ""; + } - @ConfigItem(keyName="streamerMode", name="Hide email addresses", description="Hides your account emails") - default public boolean isStreamerMode() { - return false; - } + @ConfigItem( + keyName = "profilesData", + name = "", + description = "" + ) + void profilesData(String str); + + @ConfigItem( + keyName = "salt", + name = "", + description = "", + hidden = true + ) + default String salt() + { + return ""; + } + + @ConfigItem( + keyName = "salt", + name = "", + description = "" + ) + void salt(String key); - @ConfigItem(keyName="switchPanel", name="Auto-open Panel", description="Automatically switch to the account switcher panel on the login screen") - default public boolean switchPanel() { - return true; - } + @ConfigItem( + keyName = "rememberPassword", + name = "Remember Password", + description = "Remembers passwords for accounts" + ) + default boolean rememberPassword() + { + return true; + } + + @ConfigItem( + keyName = "streamerMode", + name = "Hide email addresses", + description = "Hides your account emails" + ) + default boolean isStreamerMode() + { + return false; + } + + @ConfigItem( + keyName = "switchPanel", + name = "Auto-open Panel", + description = "Automatically switch to the account switcher panel on the login screen" + ) + default boolean switchPanel() + { + return false; + } } - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java index f3f6da6b67..0366c4bda7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPanel.java @@ -1,248 +1,555 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019, Spedwards + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.runelite.client.plugins.profiles; -import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.awt.LayoutManager; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; import java.util.Arrays; -import java.util.function.Consumer; +import java.util.Base64; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; import javax.inject.Inject; -import javax.swing.JButton; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; -import javax.swing.border.Border; +import javax.swing.*; import javax.swing.border.EmptyBorder; + +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.client.plugins.profiles.ProfilePanel; -import net.runelite.client.plugins.profiles.ProfilesConfig; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class ProfilesPanel -extends PluginPanel { - private static final Logger log = LoggerFactory.getLogger(ProfilesPanel.class); - private static final String ACCOUNT_USERNAME = "Account Username"; - private static final String ACCOUNT_LABEL = "Account Label"; - private static final String PASSWORD_LABEL = "Account Password"; - private static final Dimension PREFERRED_SIZE = new Dimension(205, 30); - private static final Dimension MINIMUM_SIZE = new Dimension(0, 30); - private final Client client; - private static ProfilesConfig profilesConfig; - private final JTextField txtAccountLabel = new JTextField("Account Label"); - private final JPasswordField txtAccountLogin = new JPasswordField("Account Username"); - private final JPasswordField txtPasswordLogin = new JPasswordField("Account Password"); - private final JPanel profilesPanel = new JPanel(); - private GridBagConstraints c; - - @Inject - public ProfilesPanel(Client client, final ProfilesConfig config) { - this.client = client; - profilesConfig = config; - this.setBorder(new EmptyBorder(18, 10, 0, 10)); - this.setBackground(ColorScheme.DARK_GRAY_COLOR); - this.setLayout(new GridBagLayout()); - this.c = new GridBagConstraints(); - this.c.fill = 2; - this.c.gridx = 0; - this.c.gridy = 0; - this.c.weightx = 1.0; - this.c.weighty = 0.0; - this.c.insets = new Insets(0, 0, 4, 0); - this.txtAccountLabel.setPreferredSize(PREFERRED_SIZE); - this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtAccountLabel.setBackground(ColorScheme.DARKER_GRAY_COLOR); - this.txtAccountLabel.setMinimumSize(MINIMUM_SIZE); - this.txtAccountLabel.addFocusListener(new FocusListener(){ - - @Override - public void focusGained(FocusEvent e) { - if (ProfilesPanel.this.txtAccountLabel.getText().equals(ProfilesPanel.ACCOUNT_LABEL)) { - ProfilesPanel.this.txtAccountLabel.setText(""); - ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (ProfilesPanel.this.txtAccountLabel.getText().isEmpty()) { - ProfilesPanel.this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - ProfilesPanel.this.txtAccountLabel.setText(ProfilesPanel.ACCOUNT_LABEL); - } - } - }); - this.add((Component)this.txtAccountLabel, this.c); - ++this.c.gridy; - this.txtAccountLogin.setEchoChar('\u0000'); - this.txtAccountLogin.setPreferredSize(PREFERRED_SIZE); - this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtAccountLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); - this.txtAccountLogin.setMinimumSize(MINIMUM_SIZE); - this.txtAccountLogin.addFocusListener(new FocusListener(){ - - @Override - public void focusGained(FocusEvent e) { - if (ProfilesPanel.ACCOUNT_USERNAME.equals(String.valueOf(ProfilesPanel.this.txtAccountLogin.getPassword()))) { - ProfilesPanel.this.txtAccountLogin.setText(""); - if (config.isStreamerMode()) { - ProfilesPanel.this.txtAccountLogin.setEchoChar('*'); - } - ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (ProfilesPanel.this.txtAccountLogin.getPassword().length == 0) { - ProfilesPanel.this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - ProfilesPanel.this.txtAccountLogin.setText(ProfilesPanel.ACCOUNT_USERNAME); - ProfilesPanel.this.txtAccountLogin.setEchoChar('\u0000'); - } - } - }); - this.add((Component)this.txtAccountLogin, this.c); - ++this.c.gridy; - this.txtPasswordLogin.setEchoChar('\u0000'); - this.txtPasswordLogin.setPreferredSize(PREFERRED_SIZE); - this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtPasswordLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); - this.txtPasswordLogin.setToolTipText("Account password"); - this.txtPasswordLogin.setMinimumSize(MINIMUM_SIZE); - this.txtPasswordLogin.addFocusListener(new FocusListener(){ - - @Override - public void focusGained(FocusEvent e) { - if (ProfilesPanel.PASSWORD_LABEL.equals(String.valueOf(ProfilesPanel.this.txtPasswordLogin.getPassword()))) { - ProfilesPanel.this.txtPasswordLogin.setText(""); - ProfilesPanel.this.txtPasswordLogin.setEchoChar('*'); - ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (ProfilesPanel.this.txtPasswordLogin.getPassword().length == 0) { - ProfilesPanel.this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - ProfilesPanel.this.txtPasswordLogin.setText(ProfilesPanel.PASSWORD_LABEL); - ProfilesPanel.this.txtPasswordLogin.setEchoChar('\u0000'); - } - } - }); - if (config.rememberPassword()) { - this.add((Component)this.txtPasswordLogin, this.c); - ++this.c.gridy; - } - this.c.insets = new Insets(0, 0, 15, 0); - final JButton btnAddAccount = new JButton("Add Account"); - btnAddAccount.setPreferredSize(PREFERRED_SIZE); - btnAddAccount.setBackground(ColorScheme.DARKER_GRAY_COLOR); - btnAddAccount.setMinimumSize(MINIMUM_SIZE); - btnAddAccount.addActionListener(e -> { - String labelText = String.valueOf(this.txtAccountLabel.getText()); - String loginText = String.valueOf(this.txtAccountLogin.getPassword()); - String passwordText = String.valueOf(this.txtPasswordLogin.getPassword()); - if (labelText.equals(ACCOUNT_LABEL) || loginText.equals(ACCOUNT_USERNAME)) { - return; - } - String data = config.rememberPassword() && this.txtPasswordLogin.getPassword() != null ? labelText + ":" + loginText + ":" + passwordText : labelText + ":" + loginText; - log.info(data); - this.addAccount(data); - ProfilesPanel.addProfile(data); - this.txtAccountLabel.setText(ACCOUNT_LABEL); - this.txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtAccountLogin.setText(ACCOUNT_USERNAME); - this.txtAccountLogin.setEchoChar('\u0000'); - this.txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - this.txtPasswordLogin.setText(PASSWORD_LABEL); - this.txtPasswordLogin.setEchoChar('\u0000'); - this.txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); - }); - this.txtAccountLogin.addKeyListener(new KeyAdapter(){ - - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == 10) { - btnAddAccount.doClick(); - btnAddAccount.requestFocus(); - } - } - }); - this.txtAccountLogin.addMouseListener(new MouseListener(){ - - @Override - public void mouseClicked(MouseEvent e) { - } - - @Override - public void mousePressed(MouseEvent e) { - } - - @Override - public void mouseReleased(MouseEvent e) { - } - - @Override - public void mouseEntered(MouseEvent e) { - } - - @Override - public void mouseExited(MouseEvent e) { - } - }); - this.add((Component)btnAddAccount, this.c); - ++this.c.gridy; - this.profilesPanel.setLayout(new GridBagLayout()); - this.add((Component)this.profilesPanel, this.c); - this.c.gridy = 0; - this.c.insets = new Insets(0, 0, 5, 0); - this.addAccounts(config.profilesData()); - } - - void redrawProfiles() { - this.profilesPanel.removeAll(); - this.c.gridy = 0; - this.addAccounts(profilesConfig.profilesData()); - } - - private void addAccount(String data) { - ProfilePanel profile = new ProfilePanel(this.client, data, profilesConfig); - ++this.c.gridy; - this.profilesPanel.add((Component)profile, this.c); - this.revalidate(); - this.repaint(); - } - - void addAccounts(String data) { - if (!(data = data.trim()).contains(":")) { - return; - } - Arrays.stream(data.split("\\n")).forEach(this::addAccount); - } - - static void addProfile(String data) { - profilesConfig.profilesData(profilesConfig.profilesData() + data + "\n"); - } - - static void removeProfile(String data) { - profilesConfig.profilesData(profilesConfig.profilesData().replaceAll(data + "\\n", "")); - } +@Slf4j +class ProfilesPanel extends PluginPanel +{ + private static final int iterations = 100000; + private static final String UNLOCK_PASSWORD = "Encryption Password"; + private static final String LOAD_ACCOUNTS = "Load Accounts"; + private static final String ACCOUNT_USERNAME = "Account Username"; + private static final String ACCOUNT_LABEL = "Account Label"; + private static final String PASSWORD_LABEL = "Account Password"; + private static final Dimension PREFERRED_SIZE = new Dimension(PluginPanel.PANEL_WIDTH - 20, 30); + private static final Dimension MINIMUM_SIZE = new Dimension(0, 30); + + private final Client client; + private static ProfilesConfig profilesConfig; + + private final JPasswordField txtDecryptPassword = new JPasswordField(UNLOCK_PASSWORD); + private final JButton btnLoadAccounts = new JButton(LOAD_ACCOUNTS); + private final JTextField txtAccountLabel = new JTextField(ACCOUNT_LABEL); + private final JPasswordField txtAccountLogin = new JPasswordField(ACCOUNT_USERNAME); + private final JPasswordField txtPasswordLogin = new JPasswordField(PASSWORD_LABEL); + private final JPanel profilesPanel = new JPanel(); + private GridBagConstraints c; + + @Inject + public ProfilesPanel(Client client, ProfilesConfig config) + { + super(); + this.client = client; + profilesConfig = config; + + setBorder(new EmptyBorder(18, 10, 0, 10)); + setBackground(ColorScheme.DARK_GRAY_COLOR); + setLayout(new GridBagLayout()); + + c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.gridx = 0; + c.gridy = 0; + c.weightx = 1; + c.weighty = 0; + c.insets = new Insets(0, 0, 4, 0); + + txtDecryptPassword.setEchoChar((char) 0); + txtDecryptPassword.setPreferredSize(PREFERRED_SIZE); + txtDecryptPassword.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + txtDecryptPassword.setBackground(ColorScheme.DARKER_GRAY_COLOR); + txtDecryptPassword.setMinimumSize(MINIMUM_SIZE); + txtDecryptPassword.setToolTipText(UNLOCK_PASSWORD); + txtDecryptPassword.addFocusListener(new FocusListener() + { + @Override + public void focusGained(FocusEvent e) + { + txtDecryptPassword.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + if (String.valueOf(txtDecryptPassword.getPassword()).equals(UNLOCK_PASSWORD)) + { + txtDecryptPassword.setText(""); + txtDecryptPassword.setEchoChar('*'); + } + } + + @Override + public void focusLost(FocusEvent e) + { + txtDecryptPassword.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + if (txtDecryptPassword.getPassword().length == 0) + { + txtDecryptPassword.setText(UNLOCK_PASSWORD); + txtDecryptPassword.setEchoChar((char) 0); + } + } + }); + + add(txtDecryptPassword, c); + c.gridy++; + + btnLoadAccounts.setPreferredSize(PREFERRED_SIZE); + btnLoadAccounts.setBackground(ColorScheme.DARKER_GRAY_COLOR); + btnLoadAccounts.setMinimumSize(MINIMUM_SIZE); + btnLoadAccounts.setToolTipText(LOAD_ACCOUNTS); + btnLoadAccounts.addMouseListener(new MouseListener() + { + @Override + public void mouseClicked(MouseEvent e) + { + + } + + @Override + public void mousePressed(MouseEvent e) + { + + } + + @Override + public void mouseReleased(MouseEvent e) + { + try + { + redrawProfiles(); + } + catch (InvalidKeySpecException | NoSuchAlgorithmException ex) + { + showErrorMessage("Unable to load data", "Incorrect password!"); + } + } + + @Override + public void mouseEntered(MouseEvent e) + { + + } + + @Override + public void mouseExited(MouseEvent e) + { + + } + }); + + add(btnLoadAccounts, c); + c.gridy++; + + txtAccountLabel.setPreferredSize(PREFERRED_SIZE); + txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + txtAccountLabel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + txtAccountLabel.setMinimumSize(MINIMUM_SIZE); + txtAccountLabel.addFocusListener(new FocusListener() + { + @Override + public void focusGained(FocusEvent e) + { + if (txtAccountLabel.getText().equals(ACCOUNT_LABEL)) + { + txtAccountLabel.setText(""); + txtAccountLabel.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + } + } + + @Override + public void focusLost(FocusEvent e) + { + if (txtAccountLabel.getText().isEmpty()) + { + txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + txtAccountLabel.setText(ACCOUNT_LABEL); + } + } + }); + + add(txtAccountLabel, c); + c.gridy++; + + // Do not hide username characters until they focus or if in streamer mode + txtAccountLogin.setEchoChar((char) 0); + txtAccountLogin.setPreferredSize(PREFERRED_SIZE); + txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + txtAccountLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); + txtAccountLogin.setMinimumSize(MINIMUM_SIZE); + txtAccountLogin.addFocusListener(new FocusListener() + { + @Override + public void focusGained(FocusEvent e) + { + if (ACCOUNT_USERNAME.equals(String.valueOf(txtAccountLogin.getPassword()))) + { + txtAccountLogin.setText(""); + if (config.isStreamerMode()) + { + txtAccountLogin.setEchoChar('*'); + } + txtAccountLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + } + } + + @Override + public void focusLost(FocusEvent e) + { + if (txtAccountLogin.getPassword().length == 0) + { + txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + txtAccountLogin.setText(ACCOUNT_USERNAME); + txtAccountLogin.setEchoChar((char) 0); + } + } + }); + + add(txtAccountLogin, c); + c.gridy++; + + txtPasswordLogin.setEchoChar((char) 0); + txtPasswordLogin.setPreferredSize(PREFERRED_SIZE); + txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + txtPasswordLogin.setBackground(ColorScheme.DARKER_GRAY_COLOR); + txtPasswordLogin.setToolTipText(PASSWORD_LABEL); + txtPasswordLogin.setMinimumSize(MINIMUM_SIZE); + txtPasswordLogin.addFocusListener(new FocusListener() + { + @Override + public void focusGained(FocusEvent e) + { + if (PASSWORD_LABEL.equals(String.valueOf(txtPasswordLogin.getPassword()))) + { + txtPasswordLogin.setText(""); + txtPasswordLogin.setEchoChar('*'); + txtPasswordLogin.setForeground(ColorScheme.LIGHT_GRAY_COLOR); + } + } + + @Override + public void focusLost(FocusEvent e) + { + if (txtPasswordLogin.getPassword().length == 0) + { + txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + txtPasswordLogin.setText(PASSWORD_LABEL); + txtPasswordLogin.setEchoChar((char) 0); + } + } + }); + + + if (config.rememberPassword()) + { + add(txtPasswordLogin, c); + c.gridy++; + } + c.insets = new Insets(0, 0, 15, 0); + + JButton btnAddAccount = new JButton("Add Account"); + btnAddAccount.setPreferredSize(PREFERRED_SIZE); + btnAddAccount.setBackground(ColorScheme.DARKER_GRAY_COLOR); + btnAddAccount.setMinimumSize(MINIMUM_SIZE); + btnAddAccount.addActionListener(e -> + { + String labelText = String.valueOf(txtAccountLabel.getText()); + String loginText = String.valueOf(txtAccountLogin.getPassword()); + String passwordText = String.valueOf(txtPasswordLogin.getPassword()); + + if (labelText.equals(ACCOUNT_LABEL) || loginText.equals(ACCOUNT_USERNAME)) + { + return; + } + String data; + if (config.rememberPassword() && txtPasswordLogin.getPassword() != null) + { + data = labelText + ":" + loginText + ":" + passwordText; + } + else + { + data = labelText + ":" + loginText; + } + + try + { + if(!addProfile(data)) + { + return; + } + } + catch (InvalidKeySpecException | NoSuchAlgorithmException ex) + { + ex.printStackTrace(); + } + + this.addAccount(data); + + txtAccountLabel.setText(ACCOUNT_LABEL); + txtAccountLabel.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + + txtAccountLogin.setText(ACCOUNT_USERNAME); + txtAccountLogin.setEchoChar((char) 0); + txtAccountLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + + txtPasswordLogin.setText(PASSWORD_LABEL); + txtPasswordLogin.setEchoChar((char) 0); + txtPasswordLogin.setForeground(ColorScheme.MEDIUM_GRAY_COLOR); + }); + + txtAccountLogin.addKeyListener(new KeyAdapter() + { + @Override + public void keyPressed(KeyEvent e) + { + if (e.getKeyCode() == KeyEvent.VK_ENTER) + { + btnAddAccount.doClick(); + btnAddAccount.requestFocus(); + } + } + }); + txtAccountLogin.addMouseListener(new MouseListener() + { + @Override + public void mouseClicked(MouseEvent e) + { + + + } + + @Override + public void mousePressed(MouseEvent e) + { + + } + + @Override + public void mouseReleased(MouseEvent e) + { + + } + + @Override + public void mouseEntered(MouseEvent e) + { + } + + @Override + public void mouseExited(MouseEvent e) + { + + } + }); + + add(btnAddAccount, c); + c.gridy++; + + profilesPanel.setLayout(new GridBagLayout()); + add(profilesPanel, c); + c.gridy = 0; + c.insets = new Insets(0, 0, 5, 0); + + //addAccounts(config.profilesData()); + } + + void redrawProfiles() throws InvalidKeySpecException, NoSuchAlgorithmException + { + profilesPanel.removeAll(); + c.gridy = 0; + addAccounts(getProfileData()); + + revalidate(); + repaint(); + } + + private void addAccount(String data) + { + ProfilePanel profile = new ProfilePanel(client, data, profilesConfig, this); + c.gridy++; + profilesPanel.add(profile, c); + + revalidate(); + repaint(); + } + + void addAccounts(String data) + { + //log.info("Data: " + data); + data = data.trim(); + if (!data.contains(":")) + { + return; + } + Arrays.stream(data.split("\\n")).forEach(this::addAccount); + } + + boolean addProfile(String data) throws InvalidKeySpecException, NoSuchAlgorithmException + { + return setProfileData( + getProfileData() + data + "\n"); + } + + void removeProfile(String data) throws InvalidKeySpecException, NoSuchAlgorithmException + { + setProfileData( + getProfileData().replaceAll(data + "\\n", "")); + redrawProfiles(); + } + + void setSalt(byte[] bytes) + { + profilesConfig.salt(base64Encode(bytes)); + } + + byte[] getSalt() + { + if(profilesConfig.salt().length() == 0) + { + return new byte[0]; + } + return base64Decode(profilesConfig.salt()); + } + + SecretKey getAesKey() throws NoSuchAlgorithmException, InvalidKeySpecException + { + if(getSalt().length == 0) + { + byte[] b = new byte[16]; + SecureRandom.getInstanceStrong().nextBytes(b); + setSalt(b); + } + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + KeySpec spec = new PBEKeySpec(txtDecryptPassword.getPassword(), getSalt(), iterations, 128); + SecretKey key = factory.generateSecret(spec); + return key; + } + + String getProfileData() throws InvalidKeySpecException, NoSuchAlgorithmException + { + String tmp = profilesConfig.profilesData(); + if(tmp.startsWith("¬")) + { + if(txtDecryptPassword.getPassword().length == 0 || String.valueOf(txtDecryptPassword.getPassword()).equals(UNLOCK_PASSWORD)) + { + showErrorMessage("Unable to load data", "Please enter a password!"); + return tmp; + } + tmp = tmp.substring(1); + return decryptText(base64Decode(tmp), getAesKey()); + } + return tmp; + } + + boolean setProfileData(String data) throws InvalidKeySpecException, NoSuchAlgorithmException + { + if(txtDecryptPassword.getPassword().length == 0 || String.valueOf(txtDecryptPassword.getPassword()).equals(UNLOCK_PASSWORD)) + { + showErrorMessage("Unable to save data", "Please enter a password!"); + return false; + } + byte[] enc = encryptText(data, getAesKey()); + if(enc.length == 0) + return false; + String s = "¬"+base64Encode(enc); + profilesConfig.profilesData(s); + return true; + } + + public byte[] base64Decode(String data) + { + return Base64.getDecoder().decode(data); + } + + public String base64Encode(byte[] data) + { + return Base64.getEncoder().encodeToString(data); + } + + /** + * Encrypts login info + * + * @param text text to encrypt + * @return encrypted string + */ + public static byte[] encryptText(String text, SecretKey aesKey) + { + try + { + Cipher cipher = Cipher.getInstance("AES"); + SecretKeySpec newKey = new SecretKeySpec(aesKey.getEncoded(), "AES"); + cipher.init(Cipher.ENCRYPT_MODE, newKey); + return cipher.doFinal(text.getBytes()); + } + catch (NoSuchAlgorithmException | IllegalBlockSizeException | InvalidKeyException | BadPaddingException | NoSuchPaddingException e) + { + e.printStackTrace(); + } + return new byte[0]; + } + + public static String decryptText(byte[] enc, SecretKey aesKey) + { + try + { + Cipher cipher = Cipher.getInstance("AES"); + SecretKeySpec newKey = new SecretKeySpec(aesKey.getEncoded(), "AES"); + cipher.init(Cipher.DECRYPT_MODE, newKey); + return new String(cipher.doFinal(enc)); + } + catch (NoSuchAlgorithmException | IllegalBlockSizeException | InvalidKeyException | BadPaddingException | NoSuchPaddingException e) + { + e.printStackTrace(); + } + return ""; + } + + public static void showErrorMessage(String title, String text) + { + SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(null, + text, + title, + JOptionPane.ERROR_MESSAGE)); + } + } - diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java index af707dbc1c..79adbccacd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/profiles/ProfilesPlugin.java @@ -1,10 +1,30 @@ /* - * Decompiled with CFR 0.139. + * Copyright (c) 2019, Spedwards + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.runelite.client.plugins.profiles; import com.google.inject.Provides; -import java.awt.image.BufferedImage; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; @@ -14,9 +34,10 @@ import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; -import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.GameState; import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; @@ -25,112 +46,85 @@ import net.runelite.client.plugins.PluginType; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; +import javax.inject.Inject; +import java.awt.image.BufferedImage; @PluginDescriptor( - - name="Account Switcher", - description="Allow for a allows you to easily switch between multiple OSRS Accounts", - tags={"profile", "account", "login", "log in"}, - type = PluginType.UTILITY + name = "Account Switcher", + description = "Allow for a allows you to easily switch between multiple OSRS Accounts", + tags = {"profile", "account", "login", "log in", "pklite"}, + type = PluginType.UTILITY ) +public class ProfilesPlugin extends Plugin +{ + @Inject + private ClientToolbar clientToolbar; -public class ProfilesPlugin -extends Plugin { - @Inject - private ClientToolbar clientToolbar; - @Inject - private Client client; - @Inject - private ProfilesConfig config; - private ProfilesPanel panel; - private NavigationButton navButton; - String text = "Hello World"; - private static String key = "Bar12345Bar12345"; - private static Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); + @Inject + private Client client; - @Provides - ProfilesConfig getConfig(ConfigManager configManager) { - return configManager.getConfig(ProfilesConfig.class); - } + @Inject + private ProfilesConfig config; - @Override - protected void startUp() throws Exception { - this.panel = this.injector.getInstance(ProfilesPanel.class); - BufferedImage icon = ImageUtil.getResourceStreamFromClass(this.getClass(), "/net/runelite/client/plugins/profiles/profiles_icon.png"); - this.navButton = NavigationButton.builder().tooltip("Profiles").icon(icon).priority(8).panel(this.panel).build(); - this.clientToolbar.addNavigation(this.navButton); - } - @Override - protected void shutDown() { - this.clientToolbar.removeNavigation(this.navButton); - } - - @Subscribe - private void onConfigChanged(ConfigChanged event) throws Exception { - if (event.getGroup().equals("profiles") && event.getKey().equals("rememberPassword")) { - this.panel = this.injector.getInstance(ProfilesPanel.class); - this.shutDown(); - this.startUp(); - } - } + private ProfilesPanel panel; + private NavigationButton navButton; - public static String decryptText(String text) { - byte[] bb = new byte[text.length()]; - for (int i = 0; i < text.length(); ++i) { - bb[i] = (byte)text.charAt(i); - } - Cipher cipher = null; - try { - cipher = Cipher.getInstance("AES"); - } - catch (NoSuchAlgorithmException | NoSuchPaddingException e) { - e.printStackTrace(); - } - try { - cipher.init(2, aesKey); - } - catch (InvalidKeyException e) { - e.printStackTrace(); - } - try { - Logger.getLogger("EncryptionLogger").info("Decrypted " + text + " to " + new String(cipher.doFinal(bb))); - return new String(cipher.doFinal(bb)); - } - catch (BadPaddingException | IllegalBlockSizeException e) { - e.printStackTrace(); - return ""; - } - } - public static String encryptText(String text) { - try { - Cipher cipher = Cipher.getInstance("AES"); - cipher.init(1, aesKey); - byte[] encrypted = cipher.doFinal(text.getBytes()); - StringBuilder sb = new StringBuilder(); - for (byte b : encrypted) { - sb.append((char)b); - } - Logger.getLogger("EncryptionLogger").info("Encrypted " + text + " to " + sb.toString()); - return sb.toString(); - } - catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - catch (NoSuchPaddingException e) { - e.printStackTrace(); - } - catch (BadPaddingException e) { - e.printStackTrace(); - } - catch (IllegalBlockSizeException e) { - e.printStackTrace(); - } - catch (InvalidKeyException e) { - e.printStackTrace(); - } - return ""; - } + @Provides + ProfilesConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(ProfilesConfig.class); + } + + @Override + protected void startUp() throws Exception + { + panel = injector.getInstance(ProfilesPanel.class); + + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "profiles_icon.png"); + + navButton = NavigationButton.builder() + .tooltip("Profiles") + .icon(icon) + .priority(8) + .panel(panel) + .build(); + + clientToolbar.addNavigation(navButton); + + } + + @Override + protected void shutDown() + { + clientToolbar.removeNavigation(navButton); + } + + @Subscribe + void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState().equals(GameState.LOGIN_SCREEN) && config.switchPanel()) + { + if (!navButton.isSelected()) + { + navButton.getOnSelect().run(); + } + } + } + + @Subscribe + private void onConfigChanged(ConfigChanged event) throws Exception + { + if (event.getGroup().equals("profiles")) + { + if (event.getKey().equals("rememberPassword")) + { + panel = injector.getInstance(ProfilesPanel.class); + this.shutDown(); + this.startUp(); + } + } + } + } -