Add encryption to account data - thx ThatGamerBlue

This commit is contained in:
Kyleeld
2019-04-24 02:02:13 +01:00
committed by GitHub
parent b5f4265012
commit 65f4b33f62
4 changed files with 864 additions and 443 deletions

View File

@@ -1,15 +1,37 @@
/*
* Decompiled with CFR 0.139.
* Copyright (c) 2019, Spedwards <https://github.com/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);
}
}

View File

@@ -1,5 +1,26 @@
/*
* Decompiled with CFR 0.139.
* Copyright (c) 2019, Spedwards <https://github.com/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;
}
}

View File

@@ -1,248 +1,555 @@
/*
* Decompiled with CFR 0.139.
* Copyright (c) 2019, Spedwards <https://github.com/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));
}
}

View File

@@ -1,10 +1,30 @@
/*
* Decompiled with CFR 0.139.
* Copyright (c) 2019, Spedwards <https://github.com/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();
}
}
}
}