Add encryption to account data - thx ThatGamerBlue
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user