highest = PokemonGoMainWindow.getPoGo().getItemTemplates().getEvolutions().getHighest(p.getPokemonId());
final PokemonIdOuterClass.PokemonId highestUpgradedFamily = highest.get(0);
final int cpAfterFullyEvolve;
if (highest.contains(p.getPokemonId())) {
@@ -280,7 +295,7 @@ public Object get(final Pokemon p) {
} else {
cpAfterFullyEvolve = p.getCpAfterFullEvolve(highestUpgradedFamily);
}
-
+
if (cpAfterFullyEvolve != p.getCp()) {
return String.valueOf(cpAfterFullyEvolve);
} else {
@@ -401,6 +416,12 @@ public Object get(final Pokemon p) {
: "";
}
},
+ HEALTH("Health", ColumnType.PERCENTAGE) {
+ @Override
+ public Object get(final Pokemon p) {
+ return p.getStamina() / (double) p.getMaxStamina();
+ }
+ },
PID("PID", ColumnType.LONG) {
@Override
public Object get(final Pokemon p) {
@@ -491,7 +512,7 @@ public Comparator> getComparator() {
public TableCellRenderer getCellRenderer() {
return customCellRenderer != null ? customCellRenderer : columnType.tableCellRenderer;
}
-
+
/**
* Returns the table cell editor for the given column, based on the column type.
*
diff --git a/src/me/corriekay/pokegoutil/data/managers/AccountManager.java b/src/me/corriekay/pokegoutil/data/managers/AccountManager.java
index 096132c0..85d0e7aa 100644
--- a/src/me/corriekay/pokegoutil/data/managers/AccountManager.java
+++ b/src/me/corriekay/pokegoutil/data/managers/AccountManager.java
@@ -3,6 +3,7 @@
import com.pokegoapi.api.PokemonGo;
import com.pokegoapi.api.player.PlayerProfile;
import com.pokegoapi.auth.CredentialProvider;
+import com.pokegoapi.auth.GoogleAutoCredentialProvider;
import com.pokegoapi.auth.GoogleUserCredentialProvider;
import com.pokegoapi.auth.PtcCredentialProvider;
import com.pokegoapi.exceptions.request.LoginFailedException;
@@ -28,6 +29,15 @@ public final class AccountManager {
private PokemonGo go;
private PlayerAccount playerAccount;
+ /**
+ * Private constructor to avoid instantiating this class.
+ */
+ private AccountManager() { }
+
+ /**
+ * Static method to obtain the only singleton instance of this class.
+ * @return AccountManager if is already created or create and return it.
+ */
public static AccountManager getInstance() {
if (instance == null) {
instance = new AccountManager();
@@ -36,10 +46,6 @@ public static AccountManager getInstance() {
return instance;
}
- private AccountManager() {
-
- }
-
/**
* Deletes the specified LoginType from the config.json.
*
@@ -85,15 +91,34 @@ private void deleteLoginData(final LoginType type, final boolean deleteSaveAuth)
}
}
+ /**
+ * Return pokemonGo instance of the API.
+ * @return pokemonGo instance of the API.
+ */
+ public PokemonGo getPokemonGo() {
+ return go;
+ }
+
+ /**
+ * Get login information from config.json file.
+ * @return LoginData with all the information inside
+ */
public LoginData getLoginData() {
final LoginData loginData = new LoginData(
config.getString(ConfigKey.LOGIN_PTC_USERNAME),
config.getString(ConfigKey.LOGIN_PTC_PASSWORD),
- config.getString(ConfigKey.LOGIN_GOOGLE_AUTH_TOKEN));
+ config.getString(ConfigKey.LOGIN_GOOGLE_AUTH_TOKEN),
+ config.getString(ConfigKey.LOGIN_GOOGLE_APP_USERNAME),
+ config.getString(ConfigKey.LOGIN_GOOGLE_APP_PASSWORD),
+ config.getString(ConfigKey.LOGIN_POKEHASHKEY));
- if (loginData.isValidGoogleLogin()) {
+ if (loginData.hasToken()) {
loginData.setSavedToken(true);
}
+ final String lastLoginType = ConfigNew.getConfig().getString(ConfigKey.LOGIN_LAST_TYPE);
+ if (lastLoginType != null) {
+ loginData.setLoginType(LoginType.valueOf(lastLoginType));
+ }
return loginData;
}
@@ -111,6 +136,9 @@ public PlayerProfile getPlayerProfile() {
return go != null ? go.getPlayerProfile() : null;
}
+ /**
+ * Initialize controllers.
+ */
private void initOtherControllers() {
InventoryManager.initialize(go);
PokemonBagManager.initialize(go);
@@ -130,6 +158,11 @@ public BpmResult login(final LoginData loginData) {
return logOnGoogleAuth(loginData);
}
break;
+ case GOOGLE_APP_PASSWORD:
+ if (loginData.isValidGoogleAppLogin()) {
+ return logOnGoogleApp(loginData);
+ }
+ break;
case PTC:
if (loginData.isValidPtcLogin()) {
return logOnPtc(loginData);
@@ -147,12 +180,13 @@ public BpmResult login(final LoginData loginData) {
* @return results of the login
*/
private BpmResult logOnGoogleAuth(final LoginData loginData) {
- OkHttpClient http;
- CredentialProvider cp;
+ final OkHttpClient http;
+ final CredentialProvider cp;
http = new OkHttpClient();
final String authCode = loginData.getToken();
final boolean saveAuth = config.getBool(ConfigKey.LOGIN_SAVE_AUTH);
+ config.setString(ConfigKey.LOGIN_POKEHASHKEY, loginData.getHashKey());
boolean shouldRefresh = false;
if (loginData.isSavedToken() && saveAuth) {
@@ -179,15 +213,16 @@ private BpmResult logOnGoogleAuth(final LoginData loginData) {
deleteLoginData(LoginType.GOOGLE_AUTH);
}
} catch (RequestFailedException e) {
- deleteLoginData(LoginType.GOOGLE_APP_PASSWORD);
+ //deleteLoginData(LoginType.GOOGLE_APP_PASSWORD);
return new BpmResult(e.getMessage());
}
try {
prepareLogin(cp, http);
+ config.setString(ConfigKey.LOGIN_LAST_TYPE, LoginType.GOOGLE_AUTH.toString());
return new BpmResult();
} catch (RequestFailedException e) {
- deleteLoginData(LoginType.ALL);
+ //deleteLoginData(LoginType.ALL);
return new BpmResult(e.getMessage());
}
}
@@ -199,13 +234,14 @@ private BpmResult logOnGoogleAuth(final LoginData loginData) {
* @return results of the login
*/
private BpmResult logOnPtc(final LoginData loginData) {
- OkHttpClient http;
- CredentialProvider cp;
+ final OkHttpClient http;
+ final CredentialProvider cp;
http = new OkHttpClient();
final String username = loginData.getUsername();
final String password = loginData.getPassword();
final boolean saveAuth = config.getBool(ConfigKey.LOGIN_SAVE_AUTH);
+ config.setString(ConfigKey.LOGIN_POKEHASHKEY, loginData.getHashKey());
try {
cp = new PtcCredentialProvider(http, username, password);
@@ -216,15 +252,55 @@ private BpmResult logOnPtc(final LoginData loginData) {
deleteLoginData(LoginType.PTC);
}
} catch (RequestFailedException e) {
- deleteLoginData(LoginType.PTC);
+ //deleteLoginData(LoginType.PTC);
+ return new BpmResult(e.getMessage());
+ }
+
+ try {
+ prepareLogin(cp, http);
+ config.setString(ConfigKey.LOGIN_LAST_TYPE, LoginType.PTC.toString());
+ return new BpmResult();
+ } catch (RequestFailedException e) {
+ //deleteLoginData(LoginType.ALL);
return new BpmResult(e.getMessage());
}
+ }
+
+ /**
+ * Login using Google App Password.
+ *
+ * @param loginData the login data used to login
+ * @return results of the login
+ */
+ private BpmResult logOnGoogleApp(final LoginData loginData) {
+ final OkHttpClient http;
+ final CredentialProvider cp;
+ http = new OkHttpClient();
+
+ final String username = loginData.getGoogleUsername();
+ final String password = loginData.getGooglePassword();
+ final boolean saveAuth = config.getBool(ConfigKey.LOGIN_SAVE_AUTH);
+ config.setString(ConfigKey.LOGIN_POKEHASHKEY, loginData.getHashKey());
+ try {
+ cp = new GoogleAutoCredentialProvider(http, username, password);
+ config.setString(ConfigKey.LOGIN_GOOGLE_APP_USERNAME, username);
+ if (saveAuth) {
+ config.setString(ConfigKey.LOGIN_GOOGLE_APP_PASSWORD, password);
+ } else {
+ deleteLoginData(LoginType.GOOGLE_APP_PASSWORD);
+ }
+ } catch (RequestFailedException e) {
+ //deleteLoginData(LoginType.PTC);
+ return new BpmResult(e.getMessage());
+ }
+
try {
prepareLogin(cp, http);
+ config.setString(ConfigKey.LOGIN_LAST_TYPE, LoginType.GOOGLE_APP_PASSWORD.toString());
return new BpmResult();
} catch (RequestFailedException e) {
- deleteLoginData(LoginType.ALL);
+ //deleteLoginData(LoginType.ALL);
return new BpmResult(e.getMessage());
}
}
@@ -238,8 +314,8 @@ private BpmResult logOnPtc(final LoginData loginData) {
*/
private void prepareLogin(final CredentialProvider cp, final OkHttpClient http)
throws RequestFailedException {
- go = new PokemonGo(http);
- LoginHelper.login(go, cp, api -> {
+ LoginHelper.login(new PokemonGo(http), cp, api -> {
+ go = api;
playerAccount = new PlayerAccount(go.getPlayerProfile());
initOtherControllers();
});
diff --git a/src/me/corriekay/pokegoutil/data/models/LoginData.java b/src/me/corriekay/pokegoutil/data/models/LoginData.java
index f85c53df..1653926a 100644
--- a/src/me/corriekay/pokegoutil/data/models/LoginData.java
+++ b/src/me/corriekay/pokegoutil/data/models/LoginData.java
@@ -7,6 +7,9 @@ public class LoginData {
private String token;
private String username;
private String password;
+ private String googleUsername;
+ private String googlePassword;
+ private String hashKey;
private LoginType loginType;
private boolean isSavedToken;
@@ -14,23 +17,33 @@ public LoginData() {
this.loginType = LoginType.NONE;
}
- public LoginData(String token) {
+ public LoginData(final String token) {
this.token = token;
this.loginType = LoginType.GOOGLE_AUTH;
}
- public LoginData(String username, String password) {
+ public LoginData(final String username, final String password) {
this.username = username;
this.password = password;
this.loginType = LoginType.PTC;
}
- public LoginData(String username, String password, String token) {
+ public LoginData(final String username, final String password, final String token) {
this.username = username;
this.password = password;
this.token = token;
this.loginType = LoginType.ALL;
}
+
+ public LoginData(final String username, final String password, final String token, final String googleUsername, final String googlePassword, final String hashKey) {
+ this.username = username;
+ this.password = password;
+ this.token = token;
+ this.googleUsername = googleUsername;
+ this.googlePassword = googlePassword;
+ this.hashKey = hashKey;
+ this.loginType = LoginType.ALL;
+ }
public LoginType getLoginType() {
return loginType;
@@ -39,6 +52,10 @@ public LoginType getLoginType() {
public String getPassword() {
return password;
}
+
+ public String getGooglePassword() {
+ return googlePassword;
+ }
public String getToken() {
return token;
@@ -47,13 +64,25 @@ public String getToken() {
public String getUsername() {
return username;
}
+
+ public String getGoogleUsername() {
+ return googleUsername;
+ }
+
+ public String getHashKey() {
+ return hashKey;
+ }
public boolean hasPassword() {
return password != null && password.length() > 0;
}
+
+ public boolean hasGooglePassword() {
+ return googlePassword != null && googlePassword.length() > 0;
+ }
public boolean hasSavedCredentials() {
- return isValidPtcLogin() || isValidGoogleLogin();
+ return isValidPtcLogin() || isValidGoogleLogin() || isValidGoogleAppLogin();
}
public boolean hasToken() {
@@ -63,6 +92,14 @@ public boolean hasToken() {
public boolean hasUsername() {
return username != null && username.length() > 0;
}
+
+ public boolean hasGoogleUsername() {
+ return googleUsername != null && googleUsername.length() > 0;
+ }
+
+ public boolean hasHashKey() {
+ return hashKey != null && hashKey.length() > 0;
+ }
public boolean isSavedToken() {
return isSavedToken;
@@ -71,34 +108,51 @@ public boolean isSavedToken() {
public boolean isValidGoogleLogin() {
return hasToken();
}
+
+ public boolean isValidGoogleAppLogin() {
+ return hasGoogleUsername() && hasGooglePassword();
+ }
public boolean isValidPtcLogin() {
return hasUsername() && hasPassword();
}
- public void setLoginType(LoginType loginType) {
+ public void setLoginType(final LoginType loginType) {
this.loginType = loginType;
}
- public void setPassword(String password) {
+ public void setPassword(final String password) {
this.password = password;
}
+
+ public void setGooglePassword(final String passwordParam) {
+ this.googlePassword = passwordParam;
+ }
- public void setSavedToken(boolean isSavedToken) {
- this.isSavedToken = isSavedToken;
+ public void setSavedToken(final boolean savedToken) {
+ this.isSavedToken = savedToken;
}
- public void setToken(String token) {
+ public void setToken(final String token) {
this.token = token;
}
- public void setUsername(String username) {
+ public void setUsername(final String username) {
this.username = username;
}
+
+ public void setGoogleUsername(final String usernameParam) {
+ this.googleUsername = usernameParam;
+ }
+ public void setHashKey(final String hashKey) {
+ this.hashKey = hashKey;
+ }
+
@Override
public String toString() {
- return String.format("Username: %s | Password: %s | Token: %s | LoginType: %s | isSavedToken %b",
+ return String.format("Username: %s | Password: %s | Token: %s | LoginType: %s | isSavedToken: %b",
username, password, token, loginType, isSavedToken);
}
+
}
diff --git a/src/me/corriekay/pokegoutil/data/models/PokemonModel.java b/src/me/corriekay/pokegoutil/data/models/PokemonModel.java
index 04f66097..9b8e1d35 100644
--- a/src/me/corriekay/pokegoutil/data/models/PokemonModel.java
+++ b/src/me/corriekay/pokegoutil/data/models/PokemonModel.java
@@ -26,6 +26,7 @@
import me.corriekay.pokegoutil.utils.helpers.DateHelper;
import me.corriekay.pokegoutil.utils.pokemon.PokemonCalculationUtils;
import me.corriekay.pokegoutil.utils.pokemon.PokemonUtils;
+import me.corriekay.pokegoutil.windows.PokemonGoMainWindow;
public class PokemonModel {
private static final String UNDERSCORE = "_";
@@ -322,7 +323,7 @@ private void initialze() {
setMaxCpCurrent(maxCpCurrentVar);
// Max CP calculation for highest evolution of current PokemonModel
- final List highest = Evolutions.getHighest(pokemon.getPokemonId());
+ final List highest = PokemonGoMainWindow.getPoGo().getItemTemplates().getEvolutions().getHighest(pokemon.getPokemonId());
int maxEvolvedCpVar = 0;
int maxEvolvedCpCurrentVar = 0;
//If Eeveelutions, Evolutions.getHighest return all evolutions in list, otherwise return just 1 element with the top evolution
diff --git a/src/me/corriekay/pokegoutil/gui/controller/LoginController.java b/src/me/corriekay/pokegoutil/gui/controller/LoginController.java
index 1a6db311..7bfe32f9 100644
--- a/src/me/corriekay/pokegoutil/gui/controller/LoginController.java
+++ b/src/me/corriekay/pokegoutil/gui/controller/LoginController.java
@@ -1,14 +1,22 @@
package me.corriekay.pokegoutil.gui.controller;
+import javax.swing.SwingUtilities;
+
import com.pokegoapi.auth.GoogleUserCredentialProvider;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar.ButtonData;
+import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.PasswordField;
+import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import me.corriekay.pokegoutil.BlossomsPoGoManager;
import me.corriekay.pokegoutil.data.enums.LoginType;
@@ -16,37 +24,61 @@
import me.corriekay.pokegoutil.data.models.BpmResult;
import me.corriekay.pokegoutil.data.models.LoginData;
import me.corriekay.pokegoutil.utils.helpers.Browser;
+import me.corriekay.pokegoutil.utils.helpers.UIHelper;
+import me.corriekay.pokegoutil.windows.PokemonGoMainWindow;
/**
* The LoginController is use to handle all login related actions.
*/
public class LoginController extends BaseController {
+ private static final String BOSSLAND_POKEHASH_SITE = "https://talk.pogodev.org/d/51-api-hashing-service-by-pokefarmer";
+ private static final String GOOGLE_APP_PASSWORD_SITE = "https://security.google.com/settings/security/apppasswords";
private final AccountManager accountManager = AccountManager.getInstance();
private LoginData configLoginData = new LoginData();
+ private ToggleGroup radioGroup = new ToggleGroup();
// UI elements
@FXML
+ private RadioButton ptcRadio;
+ @FXML
+ private RadioButton googleRadio;
+ @FXML
+ private RadioButton googleAppRadio;
+ @FXML
+ private Pane ptcPane;
+ @FXML
+ private HBox googlePane;
+ @FXML
private TextField usernameField;
-
@FXML
private PasswordField passwordField;
-
- @FXML
- private Button ptcLoginBtn;
-
@FXML
private TextField tokenField;
-
@FXML
private Button getTokenBtn;
-
@FXML
- private Button googleAuthBtn;
-
+ private Pane googleAppPane;
+ @FXML
+ private Button helpGoogleBtn;
+ @FXML
+ private TextField googleUsernameField;
+ @FXML
+ private PasswordField googlePasswordField;
+ @FXML
+ private Button helpGoogleAppBtn;
+ @FXML
+ private TextField hashKeyField;
+ @FXML
+ private Button helpBtn;
+ @FXML
+ private Button loginBtn;
@FXML
private CheckBox saveAuthChkbx;
+ /**
+ * Default constructor to initialize the component.
+ */
public LoginController() {
super();
initializeController();
@@ -61,7 +93,7 @@ private void alertFailedLogin(final String message) {
final Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error Login");
alert.setHeaderText("Unfortunately, your login has failed");
- alert.setContentText(message != null ? message : "" + "\nPress OK to try again.");
+ alert.setContentText(message != null ? message : "" + "\nPress OK to go back and try again later.");
alert.showAndWait();
}
@@ -76,14 +108,27 @@ public void setGuiControllerSettings() {
guiControllerSettings.setResizeable(false);
}
+ /**
+ * Initialize method that is called right after the login panel is created.
+ */
@FXML
private void initialize() {
configLoginData = accountManager.getLoginData();
- googleAuthBtn.setOnAction(this::onGoogleAuthBtnClicked);
- ptcLoginBtn.setOnAction(this::onPtcLoginBtnClicked);
+ ptcRadio.setToggleGroup(radioGroup);
+ googleRadio.setToggleGroup(radioGroup);
+ googleAppRadio.setToggleGroup(radioGroup);
+
+ ptcPane.disableProperty().bind(ptcRadio.selectedProperty().not());
+ googlePane.disableProperty().bind(googleRadio.selectedProperty().not());
+ googleAppPane.disableProperty().bind(googleAppRadio.selectedProperty().not());
+
saveAuthChkbx.setOnAction(this::onSaveAuthChkbxChanged);
getTokenBtn.setOnAction(this::ongetTokenBtnClicked);
+ loginBtn.setOnAction(this::onloginBtnClicked);
+ helpGoogleBtn.setOnAction(this::showGoogleHelpMsg);
+ helpGoogleAppBtn.setOnAction(this::showGoogleAppHelpMsg);
+ helpBtn.setOnAction(this::showHashkeyHelpMsg);
final boolean hasSavedCredentials = configLoginData.hasSavedCredentials();
saveAuthChkbx.setSelected(hasSavedCredentials);
@@ -98,6 +143,26 @@ private void initialize() {
passwordField.setText(configLoginData.getPassword());
passwordField.setDisable(true);
}
+
+ if (configLoginData.hasGoogleUsername()) {
+ googleUsernameField.setText(configLoginData.getGoogleUsername());
+ googleUsernameField.setDisable(true);
+ }
+
+ if (configLoginData.hasPassword()) {
+ passwordField.setText(configLoginData.getPassword());
+ passwordField.setDisable(true);
+ }
+
+ if (configLoginData.hasGooglePassword()) {
+ googlePasswordField.setText(configLoginData.getGooglePassword());
+ googlePasswordField.setDisable(true);
+ }
+
+ if (configLoginData.hasHashKey()) {
+ hashKeyField.setText(configLoginData.getHashKey());
+ hashKeyField.setDisable(true);
+ }
if (configLoginData.hasToken()) {
tokenField.setText("Using Previous Token");
@@ -105,6 +170,23 @@ private void initialize() {
getTokenBtn.setDisable(true);
}
}
+
+ final LoginType lastLoginType = configLoginData.getLoginType();
+ if (lastLoginType != null) {
+ if (LoginType.GOOGLE_AUTH.equals(lastLoginType)) {
+ radioGroup.selectToggle(googleRadio);
+ } else if (LoginType.GOOGLE_APP_PASSWORD.equals(lastLoginType)) {
+ radioGroup.selectToggle(googleAppRadio);
+ } else if (LoginType.PTC.equals(lastLoginType)) {
+ radioGroup.selectToggle(ptcRadio);
+ }
+ }
+
+ radioGroup.selectedToggleProperty().addListener(listener -> {
+ if (saveAuthChkbx.isSelected()) {
+ saveAuthChkbx.fire();
+ }
+ });
}
/**
@@ -118,6 +200,87 @@ private void onSaveAuthChkbxChanged(final ActionEvent actionEvent) {
toggleFields(saveCredentials);
}
+ /**
+ * Event handler for loginBtn.
+ *
+ * @param ignored event
+ */
+ public void onloginBtnClicked(final ActionEvent ignored) {
+ if (hashKeyField.textProperty().isNotEmpty().get()) {
+
+ if (ptcRadio.isSelected()) {
+ tryPtcLogin();
+ } else if (googleRadio.isSelected()) {
+ tryGoogleLogin();
+ } else if (googleAppRadio.isSelected()) {
+ tryGoogleAppLogin();
+ }
+ } else {
+ showHashkeyHelpMsg(null);
+ }
+ }
+
+ /**
+ * Show a help message to help how to use Google Auth Token.
+ * @param ignored don't used
+ */
+ private void showGoogleHelpMsg(final ActionEvent ignored) {
+ final StringBuilder msg = new StringBuilder();
+ msg.append("This is the most common and recommend way to login using your Google Account.");
+ msg.append("\nYou will need to provide a google authentication key to log in.");
+ msg.append("\nA webpage will open up when you click \"Get Token\", please allow the permissions, and then copy the token into your clipboard.");
+ msg.append("\nAfter that, just paste the token on \"Google Auth Token\" textfield and you are ready to login.");
+
+ final Alert alert = new Alert(Alert.AlertType.INFORMATION, msg.toString(), ButtonType.OK);
+ alert.setTitle("Google Auth Token");
+ alert.setHeaderText("How to use Google Auth Token");
+ alert.showAndWait();
+ }
+
+ /**
+ * Show a help message to help how to use Google App Password and how to configure it.
+ * @param ignored don't used
+ */
+ private void showGoogleAppHelpMsg(final ActionEvent ignored) {
+ final StringBuilder msg = new StringBuilder();
+ msg.append("If you can't login using Google Auth then you may need to use this method.");
+ msg.append("\nFor that, an app password has to be created.");
+ msg.append("\nIn order to obtain your app password, click on \"Generate App Password\" to access the google account control page where you are able");
+ msg.append("\nto create an app password.");
+ msg.append("\nChoose 'Other' as app and name it something like 'BPGM' or such. Then copy your password.");
+ msg.append("\nDo note: If google tells you you can't configure your App Passwords, then go back to your");
+ msg.append("\ngoogle account control page and enable 2-Step Verification. Then you will be able to.");
+
+ final Alert alert = new Alert(Alert.AlertType.INFORMATION, msg.toString(), new ButtonType("Generate App Password"), ButtonType.OK);
+ alert.setTitle("Google App Passoword");
+ alert.setHeaderText("How to use Google App Password");
+ alert.showAndWait().ifPresent(response -> {
+ if (response.getButtonData().equals(ButtonData.OTHER)) {
+ Browser.openUrl(GOOGLE_APP_PASSWORD_SITE);
+ }
+ });
+ }
+
+ /**
+ * Show a help message to what is a hashkey and how to use it.
+ * @param ignored don't used
+ */
+ private void showHashkeyHelpMsg(final ActionEvent ignored) {
+ final StringBuilder msg = new StringBuilder();
+ msg.append("Since forced update 0.57.4, you can't login using the free API anymore.");
+ msg.append("\nIn order to keep using this tool you will need to fill a hash key to authenticate with Niantic servers.");
+ msg.append("\nIf you don't have one, please go to Pogodev website to buy one by clicking on \"Get Hashkey\".");
+
+ final Alert alert = new Alert(Alert.AlertType.WARNING, msg.toString(), new ButtonType("Get Hashkey"), ButtonType.OK);
+ alert.setTitle("Hashkey Needed");
+ alert.setHeaderText("Unfortunately, a hashkey is mandatory");
+ alert.showAndWait().ifPresent(response -> {
+ if (response.getButtonData().equals(ButtonData.OTHER)) {
+ Browser.openUrl(BOSSLAND_POKEHASH_SITE);
+ }
+ });
+ }
+
/**
* Event handler for getTokenBtn.
*
@@ -129,11 +292,9 @@ private void ongetTokenBtnClicked(final ActionEvent ignored) {
}
/**
- * Event handler for googleAuthBtn.
- *
- * @param ignored event
+ * Try to login with Google account.
*/
- private void onGoogleAuthBtnClicked(final ActionEvent ignored) {
+ private void tryGoogleLogin() {
final LoginData loginData = new LoginData();
if (configLoginData.hasToken()) {
@@ -142,19 +303,34 @@ private void onGoogleAuthBtnClicked(final ActionEvent ignored) {
} else {
loginData.setToken(tokenField.getText());
}
+
+ loginData.setHashKey(hashKeyField.getText());
loginData.setLoginType(LoginType.GOOGLE_AUTH);
tryLogin(loginData);
}
+
+ /**
+ * Try to login with Google App account.
+ */
+ private void tryGoogleAppLogin() {
+ final LoginData loginData = new LoginData();
+
+ loginData.setGoogleUsername(googleUsernameField.getText());
+ loginData.setGooglePassword(googlePasswordField.getText());
+ loginData.setHashKey(hashKeyField.getText());
+ loginData.setLoginType(LoginType.GOOGLE_APP_PASSWORD);
+
+ tryLogin(loginData);
+ }
/**
- * Event handler for ptcLoginBtn.
- *
- * @param ignored event
+ * Try to login with PTC account.
*/
- private void onPtcLoginBtnClicked(final ActionEvent ignored) {
+ private void tryPtcLogin() {
final LoginData loginData = new LoginData();
+ loginData.setHashKey(hashKeyField.getText());
loginData.setUsername(usernameField.getText());
loginData.setPassword(passwordField.getText());
loginData.setLoginType(LoginType.PTC);
@@ -162,10 +338,25 @@ private void onPtcLoginBtnClicked(final ActionEvent ignored) {
tryLogin(loginData);
}
+ /**
+ * After successful login, open the MainWindow.
+ */
private void openMainWindow() {
new MainWindowController();
BlossomsPoGoManager.getPrimaryStage().show();
}
+
+ /**
+ * After successful login, open the OldMainWindow.
+ */
+ private void openOldWindow() {
+ BlossomsPoGoManager.getPrimaryStage().hide();
+ SwingUtilities.invokeLater(() -> {
+ UIHelper.setNativeLookAndFeel();
+ BlossomsPoGoManager.setNewMainWindow(new PokemonGoMainWindow(accountManager.getPokemonGo(), true));
+ BlossomsPoGoManager.getMainWindow().setVisible(true);
+ });
+ }
/**
* Handle enabling and disabling of gui if credentials are saved.
@@ -190,12 +381,18 @@ private void toggleFields(final boolean save) {
} else {
tokenField.setDisable(true);
}
+
+ if (hashKeyField.getText().isEmpty() || !save) {
+ hashKeyField.setDisable(false);
+ } else {
+ hashKeyField.setDisable(true);
+ }
getTokenBtn.setDisable(false);
}
/**
- * Try to login into pokemon go using the provided login credentials.
+ * Try to login into Pokémon GO using the provided login credentials.
*
* @param loginData login credentials
*/
@@ -203,9 +400,22 @@ private void tryLogin(final LoginData loginData) {
final BpmResult loginResult = accountManager.login(loginData);
if (loginResult.isSuccess()) {
- openMainWindow();
+
+ // openMainWindow();
+ openOldWindow();
} else {
alertFailedLogin(loginResult.getErrorMessage());
}
}
+
+ /**
+ * Logoff from main app.
+ */
+ public static void logOff() {
+
+ BlossomsPoGoManager.getMainWindow().setVisible(false);
+ BlossomsPoGoManager.getMainWindow().dispose();
+ BlossomsPoGoManager.setNewMainWindow(null);
+ BlossomsPoGoManager.getPrimaryStage().show();
+ }
}
diff --git a/src/me/corriekay/pokegoutil/utils/ConfigKey.java b/src/me/corriekay/pokegoutil/utils/ConfigKey.java
index 6c77a0d7..e39a1c89 100644
--- a/src/me/corriekay/pokegoutil/utils/ConfigKey.java
+++ b/src/me/corriekay/pokegoutil/utils/ConfigKey.java
@@ -2,11 +2,15 @@
import javax.swing.SortOrder;
+/**
+ * Enum class that handle all the keys and the default values in config.json file.
+ */
public enum ConfigKey {
DEVELOPFLAG("develop", false, Type.BOOLEAN),
LOGIN_SAVE_AUTH("login.saveAuth", false, Type.BOOLEAN),
+ LOGIN_LAST_TYPE("login.lastType", null, Type.STRING),
LOGIN_GOOGLE_AUTH_TOKEN("login.google.authToken", null, Type.STRING),
LOGIN_GOOGLE_APP_USERNAME("login.google.username", null, Type.STRING),
LOGIN_GOOGLE_APP_PASSWORD("login.google.password", null, Type.STRING),
@@ -36,7 +40,8 @@ public enum ConfigKey {
SHOW_BULK_POPUP("settings.popupAfterBulk", true, Type.BOOLEAN),
INCLUDE_FAMILY("settings.includeFamily", true, Type.BOOLEAN),
ALTERNATIVE_IV_CALCULATION("settings.alternativeIvCalculation", false, Type.BOOLEAN),
-
+ HP_SORT_ON_FULL("settings.sortOnFullHP", true, Type.BOOLEAN),
+
LANGUAGE("options.lang", "en", Type.STRING),
FONT_SIZE("options.font.size", 12, Type.INTEGER),
ROW_PADDING("options.row.padding", 3, Type.INTEGER),
@@ -47,8 +52,8 @@ public enum ConfigKey {
DELAY_RENAME_MAX("delay.rename.max", 5000, Type.INTEGER),
DELAY_TRANSFER_MIN("delay.transfer.min", 1000, Type.INTEGER),
DELAY_TRANSFER_MAX("delay.transfer.max", 5000, Type.INTEGER),
- DELAY_EVOLVE_MIN("delay.evolve.min", 3000, Type.INTEGER),
- DELAY_EVOLVE_MAX("delay.evolve.max", 12000, Type.INTEGER),
+ DELAY_EVOLVE_MIN("delay.evolve.min", 18000, Type.INTEGER),
+ DELAY_EVOLVE_MAX("delay.evolve.max", 20000, Type.INTEGER),
DELAY_POWERUP_MIN("delay.powerUp.min", 1000, Type.INTEGER),
DELAY_POWERUP_MAX("delay.powerUp.max", 5000, Type.INTEGER),
DELAY_FAVORITE_MIN("delay.favorite.min", 1000, Type.INTEGER),
@@ -67,21 +72,55 @@ public enum ConfigKey {
DEVICE_INFO_CUSTOM_FIRMWARE_TAGS("deviceInfo.custom.firmware.tags", null, Type.STRING),
DEVICE_INFO_CUSTOM_FIRMWARE_TYPE("deviceInfo.custom.firmware.type", null, Type.STRING),
DEVICE_INFO_CUSTOM_HARDWARE_MANUFACUTER("deviceInfo.custom.hardware.manufacturer", null, Type.STRING),
- DEVICE_INFO_CUSTOM_HARDWARE_MODEL("deviceInfo.custom.hardware.model", null, Type.STRING);
+ DEVICE_INFO_CUSTOM_HARDWARE_MODEL("deviceInfo.custom.hardware.model", null, Type.STRING),
+
+ //Default unicode icons for UnicodeHelper class, it can now be customized in config.json file
+ UNICODE_ICON_TYPE_BUG("unicode.type_bug", 0x2042, Type.INTEGER),
+ UNICODE_ICON_TYPE_DARK("unicode.type_dark", 0x263D, Type.INTEGER),
+ UNICODE_ICON_TYPE_DRAGON("unicode.type_dragon", 0x26E9, Type.INTEGER),
+ UNICODE_ICON_TYPE_ELETRIC("unicode.type_eletric", 0x2607, Type.INTEGER),
+ UNICODE_ICON_TYPE_FAIRY("unicode.type_fairy", 0x2764, Type.INTEGER),
+ UNICODE_ICON_TYPE_FIGHTING("unicode.type_fighting", 0x270A, Type.INTEGER),
+ UNICODE_ICON_TYPE_FIRE("unicode.type_fire", 0x2668, Type.INTEGER),
+ UNICODE_ICON_TYPE_FLYING("unicode.type_flying", 0x2708, Type.INTEGER),
+ UNICODE_ICON_TYPE_GHOST("unicode.type_ghost", 0x26B0, Type.INTEGER),
+ UNICODE_ICON_TYPE_GRASS("unicode.type_grass", 0x2E19, Type.INTEGER),
+ UNICODE_ICON_TYPE_GROUND("unicode.type_ground", 0x26F0, Type.INTEGER),
+ UNICODE_ICON_TYPE_ICE("unicode.type_ice", 0x2744, Type.INTEGER),
+ UNICODE_ICON_TYPE_NORMAL("unicode.type_normal", 0x2734, Type.INTEGER),
+ UNICODE_ICON_TYPE_POISON("unicode.type_poison", 0x2620, Type.INTEGER),
+ UNICODE_ICON_TYPE_PSYCHIC("unicode.type_psychic", 0x269B, Type.INTEGER),
+ UNICODE_ICON_TYPE_ROCK("unicode.type_rock", 0x25C9, Type.INTEGER),
+ UNICODE_ICON_TYPE_STEEL("unicode.type_steel", 0x26D3, Type.INTEGER),
+ UNICODE_ICON_TYPE_WATER("unicode.type_water", 0x26C6, Type.INTEGER),
+ UNICODE_ICON_SHIELD("unicode.shield", 0x26E8, Type.INTEGER),
+ UNICODE_ICON_SWORD("unicode.sword", 0x2694, Type.INTEGER);
public final String keyName;
public final Object defaultValue;
public final Type type;
- ConfigKey(String keyName, Object defaultValue, Type type) {
+ /**
+ * Default constructor for ConfigKey enum.
+ * @param keyName name of the key
+ * @param defaultValue default value of the key
+ * @param type of the key
+ */
+ ConfigKey(final String keyName, final Object defaultValue, final Type type) {
this.keyName = keyName;
this.defaultValue = defaultValue;
this.type = type;
}
+ /**
+ * Auxiliary method to return the defaultValue of the key.
+ * @param the type of the return
+ * @return the default object returned
+ * @throws ClassCastException when a Class can't be cast to T
+ */
@SuppressWarnings("unchecked")
public T getDefaultValue() throws ClassCastException {
- Class> clazz = type.getClazz();
+ final Class> clazz = type.getClazz();
return (T) clazz.cast(defaultValue);
}
@@ -102,7 +141,7 @@ enum Type {
* @param clazz The class to parse.
* @param Type of the class, also return type.
*/
- Type(Class clazz) {
+ Type(final Class clazz) {
this.clazz = clazz;
}
diff --git a/src/me/corriekay/pokegoutil/utils/StringLiterals.java b/src/me/corriekay/pokegoutil/utils/StringLiterals.java
index c350811c..9ffc3ade 100644
--- a/src/me/corriekay/pokegoutil/utils/StringLiterals.java
+++ b/src/me/corriekay/pokegoutil/utils/StringLiterals.java
@@ -9,6 +9,8 @@ public final class StringLiterals {
public static final String UNDERSCORE = "_";
public static final String PERCENTAGE = "%";
public static final String DOT = ".";
+ public static final String MINUS_ONE = "-1";
+ public static final String SLASH = "/";
public static final String NEWLINE = System.lineSeparator();
// Situation specific string literals
diff --git a/src/me/corriekay/pokegoutil/utils/helpers/LoginHelper.java b/src/me/corriekay/pokegoutil/utils/helpers/LoginHelper.java
index d8d8f14e..764f5ff7 100644
--- a/src/me/corriekay/pokegoutil/utils/helpers/LoginHelper.java
+++ b/src/me/corriekay/pokegoutil/utils/helpers/LoginHelper.java
@@ -7,7 +7,6 @@
import com.pokegoapi.api.listener.LoginListener;
import com.pokegoapi.auth.CredentialProvider;
import com.pokegoapi.exceptions.request.RequestFailedException;
-import com.pokegoapi.util.hash.legacy.LegacyHashProvider;
import com.pokegoapi.util.hash.pokehash.PokeHashKey;
import com.pokegoapi.util.hash.pokehash.PokeHashProvider;
@@ -54,10 +53,8 @@ public void onChallenge(final PokemonGo api, final String challengeURL) {
final String pokeHashKey = ConfigNew.getConfig().getString(ConfigKey.LOGIN_POKEHASHKEY);
if (pokeHashKey != null) {
final PokeHashProvider pokeHashProvider = new PokeHashProvider(PokeHashKey.from(pokeHashKey), true);
- pokeHashProvider.setEndpoint("http://pokehash.buddyauth.com/api/v127_4/hash");
+ pokeHashProvider.setEndpoint("http://pokehash.buddyauth.com/api/v133_1/hash");
go.login(credentialProvider, pokeHashProvider);
- } else {
- go.login(credentialProvider, new LegacyHashProvider());
}
}
}
diff --git a/src/me/corriekay/pokegoutil/utils/helpers/UnicodeHelper.java b/src/me/corriekay/pokegoutil/utils/helpers/UnicodeHelper.java
index b8c2fe3b..965c62b4 100644
--- a/src/me/corriekay/pokegoutil/utils/helpers/UnicodeHelper.java
+++ b/src/me/corriekay/pokegoutil/utils/helpers/UnicodeHelper.java
@@ -1,9 +1,13 @@
package me.corriekay.pokegoutil.utils.helpers;
import POGOProtos.Enums.PokemonTypeOuterClass.PokemonType;
+import me.corriekay.pokegoutil.utils.ConfigKey;
+import me.corriekay.pokegoutil.utils.ConfigNew;
-/** Class to Help get the Unicode character.
- * @author Fernando */
+/**
+ * Class to Help get the Unicode character.
+ * @author FernandoTBarros
+ */
public enum UnicodeHelper {
NUMBER_0(0x24EA, "0"),
NUMBER_1(0x2460, "1"),
@@ -21,44 +25,51 @@ public enum UnicodeHelper {
NUMBER_13(0x24ED, "13"),
NUMBER_14(0x24EE, "14"),
NUMBER_15(0x24EF, "15"),
- TYPE_BUG(0x2042, PokemonType.POKEMON_TYPE_BUG.toString()),
- TYPE_DARK(0x263D, PokemonType.POKEMON_TYPE_DARK.toString()),
- TYPE_DRAGON(0x26E9, PokemonType.POKEMON_TYPE_DRAGON.toString()),
- TYPE_ELETRIC(0x2607, PokemonType.POKEMON_TYPE_ELECTRIC.toString()),
- TYPE_FAIRY(0x2764, PokemonType.POKEMON_TYPE_FAIRY.toString()),
- TYPE_FIGHTING(0x270A, PokemonType.POKEMON_TYPE_FIGHTING.toString()),
- TYPE_FIRE(0x2668, PokemonType.POKEMON_TYPE_FIRE.toString()),
- TYPE_FLYING(0x2708, PokemonType.POKEMON_TYPE_FLYING.toString()),
- TYPE_GHOST(0x26B0, PokemonType.POKEMON_TYPE_GHOST.toString()),
- TYPE_GRASS(0x2E19, PokemonType.POKEMON_TYPE_GRASS.toString()),
- TYPE_GROUND(0x26F0, PokemonType.POKEMON_TYPE_GROUND.toString()),
- TYPE_ICE(0x2744, PokemonType.POKEMON_TYPE_ICE.toString()),
- TYPE_NORMAL(0x2734, PokemonType.POKEMON_TYPE_NORMAL.toString()),
- TYPE_POISON(0x2620, PokemonType.POKEMON_TYPE_POISON.toString()),
- TYPE_PSYCHIC(0x269B, PokemonType.POKEMON_TYPE_PSYCHIC.toString()),
- TYPE_ROCK(0x25C9, PokemonType.POKEMON_TYPE_ROCK.toString()),
- TYPE_STEEL(0x26D3, PokemonType.POKEMON_TYPE_STEEL.toString()),
- TYPE_WATER(0x26C6, PokemonType.POKEMON_TYPE_WATER.toString()),
- SHIELD(0x26E8, "shield"),
- SWORD(0x2694, "sword");
+ TYPE_BUG(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_BUG), PokemonType.POKEMON_TYPE_BUG.toString()),
+ TYPE_DARK(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_DARK), PokemonType.POKEMON_TYPE_DARK.toString()),
+ TYPE_DRAGON(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_DRAGON), PokemonType.POKEMON_TYPE_DRAGON.toString()),
+ TYPE_ELETRIC(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_ELETRIC), PokemonType.POKEMON_TYPE_ELECTRIC.toString()),
+ TYPE_FAIRY(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_FAIRY), PokemonType.POKEMON_TYPE_FAIRY.toString()),
+ TYPE_FIGHTING(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_FIGHTING), PokemonType.POKEMON_TYPE_FIGHTING.toString()),
+ TYPE_FIRE(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_FIRE), PokemonType.POKEMON_TYPE_FIRE.toString()),
+ TYPE_FLYING(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_FLYING), PokemonType.POKEMON_TYPE_FLYING.toString()),
+ TYPE_GHOST(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_GHOST), PokemonType.POKEMON_TYPE_GHOST.toString()),
+ TYPE_GRASS(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_GRASS), PokemonType.POKEMON_TYPE_GRASS.toString()),
+ TYPE_GROUND(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_GROUND), PokemonType.POKEMON_TYPE_GROUND.toString()),
+ TYPE_ICE(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_ICE), PokemonType.POKEMON_TYPE_ICE.toString()),
+ TYPE_NORMAL(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_NORMAL), PokemonType.POKEMON_TYPE_NORMAL.toString()),
+ TYPE_POISON(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_POISON), PokemonType.POKEMON_TYPE_POISON.toString()),
+ TYPE_PSYCHIC(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_PSYCHIC), PokemonType.POKEMON_TYPE_PSYCHIC.toString()),
+ TYPE_ROCK(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_ROCK), PokemonType.POKEMON_TYPE_ROCK.toString()),
+ TYPE_STEEL(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_STEEL), PokemonType.POKEMON_TYPE_STEEL.toString()),
+ TYPE_WATER(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_TYPE_WATER), PokemonType.POKEMON_TYPE_WATER.toString()),
+ SHIELD(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_SHIELD), "shield"),
+ SWORD(ConfigNew.getConfig().getInt(ConfigKey.UNICODE_ICON_SWORD), "sword"),
+ FEMALE(0x2640, "female"),
+ MALE(0x2642, "male"),
+ NONE(0x2260, "none");
private int hexaCode;
private String identifier;
- /** Default constructor.
+ /**
+ * Default constructor.
* @param paramHexaCode Unicode character of this Enum
- * @param paramIdentifier String identifier of this Enum */
- UnicodeHelper(int paramHexaCode, String paramIdentifier) {
+ * @param paramIdentifier String identifier of this Enum
+ */
+ UnicodeHelper(final int paramHexaCode, final String paramIdentifier) {
this.hexaCode = paramHexaCode;
this.identifier = paramIdentifier;
}
- /** Method to get Unicode character based on String.
+ /**
+ * Method to get Unicode character based on String.
* @param identifier String to identify the Unicode Character that should be
* returned
- * @return unicode character in String */
- public static String get(String identifier) {
- for (UnicodeHelper uni : values()) {
+ * @return unicode character in String
+ */
+ public static String get(final String identifier) {
+ for (final UnicodeHelper uni : values()) {
if (uni.identifier.equals(identifier)) {
return Character.toString((char) uni.hexaCode);
}
diff --git a/src/me/corriekay/pokegoutil/utils/pokemon/PokeHandler.java b/src/me/corriekay/pokegoutil/utils/pokemon/PokeHandler.java
index 784d2245..4187662d 100644
--- a/src/me/corriekay/pokegoutil/utils/pokemon/PokeHandler.java
+++ b/src/me/corriekay/pokegoutil/utils/pokemon/PokeHandler.java
@@ -10,13 +10,15 @@
import com.pokegoapi.api.pokemon.Pokemon;
import com.pokegoapi.exceptions.request.RequestFailedException;
-import com.pokegoapi.main.PokemonMeta;
+
import POGOProtos.Networking.Responses.NicknamePokemonResponseOuterClass.NicknamePokemonResponse;
import me.corriekay.pokegoutil.data.enums.PokeColumn;
+import me.corriekay.pokegoutil.utils.StringLiterals;
import me.corriekay.pokegoutil.utils.Utilities;
import me.corriekay.pokegoutil.utils.helpers.TriConsumer;
import me.corriekay.pokegoutil.utils.helpers.UnicodeHelper;
+import me.corriekay.pokegoutil.windows.PokemonGoMainWindow;
public class PokeHandler {
@@ -42,7 +44,7 @@ public static PokeNick generatePokemonNickname(final String pattern, final Pokem
}
/**
- * Rename a single Pokemon based on a pattern
+ * Rename a single Pokemon based on a pattern.
*
* @param pattern The pattern to use for renaming
* @param pokemon The Pokemon to rename
@@ -62,8 +64,8 @@ public static NicknamePokemonResponse.Result renameWithPattern(final String patt
return result;
} catch (RequestFailedException e) {
System.out.println("Error while renaming "
- + PokemonUtils.getLocalPokeName(pokemon) + "(" + pokemon.getNickname() + ")! "
- + Utilities.getRealExceptionMessage(e));
+ + PokemonUtils.getLocalPokeName(pokemon) + "(" + pokemon.getNickname() + ")! "
+ + Utilities.getRealExceptionMessage(e));
return NicknamePokemonResponse.Result.UNRECOGNIZED;
}
}
@@ -155,7 +157,7 @@ public String get(final Pokemon p) {
return PokeColumn.CP.get(p).toString();
}
},
- CP_EVOLVED("CP if pokemon was fully evolved (equals %cp% for highest species in the family)") {
+ CP_EVOLVED("CP if Pokémon was fully evolved (equals %cp% for highest species in the family)") {
@Override
public String get(final Pokemon p) {
return PokeColumn.CP_EVOLVED.get(p).toString();
@@ -164,13 +166,14 @@ public String get(final Pokemon p) {
HP("Hit Points") {
@Override
public String get(final Pokemon p) {
- return PokeColumn.HP.get(p).toString();
+ return String.valueOf(p.getMaxStamina());
}
},
LEVEL("Pokémon Level") {
@Override
public String get(final Pokemon p) {
- return PokeColumn.LEVEL.get(p).toString();
+ final int size = 4;
+ return StringUtils.leftPad(PokeColumn.LEVEL.get(p).toString(), size, '0');
}
},
IV_RATING("IV Rating in two digits (XX for 100%) [2]") {
@@ -183,8 +186,8 @@ public String get(final Pokemon p) {
@Override
public String get(final Pokemon p) {
return (Integer.toHexString((int) PokeColumn.IV_ATTACK.get(p))
- + Integer.toHexString((int) PokeColumn.IV_DEFENSE.get(p))
- + Integer.toHexString((int) PokeColumn.IV_STAMINA.get(p))).toUpperCase();
+ + Integer.toHexString((int) PokeColumn.IV_DEFENSE.get(p))
+ + Integer.toHexString((int) PokeColumn.IV_STAMINA.get(p))).toUpperCase();
}
},
IV_ATT("IV Attack [2]") {
@@ -265,31 +268,45 @@ public String get(final Pokemon p) {
return PokeColumn.MAX_CP_40.get(p).toString();
}
},
- MOVE_TYPE_1("Move 1 abbreviated (Ghost = Gh) [2]") {
+ MOVE_1("Move 1 abbreviated (Uppercase with STAB else lowercase) [2]") {
+ @Override
+ public String get(final Pokemon p) {
+ final String move = PokemonUtils.formatMove(p.getMove1());
+ return PokemonUtils.hasStab(p.getPokemonId(), p.getMove1()) ? abbreviateMove(move).toUpperCase() : abbreviateMove(move).toLowerCase();
+ }
+ },
+ MOVE_2("Move 2 abbreviated (Uppercase with STAB else lowercase) [2]") {
@Override
public String get(final Pokemon p) {
- final String type = PokemonUtils.formatType(PokemonMeta.getMoveSettings(p.getMove1()).getPokemonType());
+ final String move = PokemonUtils.formatMove(p.getMove2());
+ return PokemonUtils.hasStab(p.getPokemonId(), p.getMove2()) ? abbreviateMove(move).toUpperCase() : abbreviateMove(move).toLowerCase();
+ }
+ },
+ MOVE_TYPE_1("Move Type 1 abbreviated (Uppercase with STAB else lowercase) [2]") {
+ @Override
+ public String get(final Pokemon p) {
+ final String type = PokemonUtils.formatType(PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(p.getMove1()).getPokemonType());
return PokemonUtils.hasStab(p.getPokemonId(), p.getMove1()) ? abbreviateType(type).toUpperCase() : abbreviateType(type).toLowerCase();
}
},
- MOVE_TYPE_2("Move 2 abbreviated (Ghost = Gh) [2]") {
+ MOVE_TYPE_2("Move Type 2 abbreviated (Uppercase with STAB else lowercase) [2]") {
@Override
public String get(final Pokemon p) {
- final String type = PokemonUtils.formatType(PokemonMeta.getMoveSettings(p.getMove2()).getPokemonType());
+ final String type = PokemonUtils.formatType(PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(p.getMove2()).getPokemonType());
return PokemonUtils.hasStab(p.getPokemonId(), p.getMove2()) ? abbreviateType(type).toUpperCase() : abbreviateType(type).toLowerCase();
}
},
- MOVE_TYPE_1_UNI("Move 1 abbreviated (Eletric = ⚡) [1]") {
+ MOVE_TYPE_1_UNI("Move Type 1 abbreviated (Electric = ⚡) [1]") {
@Override
public String get(final Pokemon p) {
- final String type = PokemonMeta.getMoveSettings(p.getMove1()).getPokemonType().toString();
+ final String type = PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(p.getMove1()).getPokemonType().toString();
return UnicodeHelper.get(type);
}
},
- MOVE_TYPE_2_UNI("Move 2 abbreviated (Eletric = ⚡) [1]") {
+ MOVE_TYPE_2_UNI("Move Type 2 abbreviated (Electric = ⚡) [1]") {
@Override
public String get(final Pokemon p) {
- final String type = PokemonMeta.getMoveSettings(p.getMove2()).getPokemonType().toString();
+ final String type = PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(p.getMove2()).getPokemonType().toString();
return UnicodeHelper.get(type);
}
},
@@ -320,25 +337,27 @@ public String get(final Pokemon p) {
TYPE_1("Pokémon Type 1 abbreviated (Ghost = Gh) [2]") {
@Override
public String get(final Pokemon p) {
- final String type = p.getSettings().getType().toString();
+ // need to strip "pokemon_type_" prefix or "pokemon_type_none"
+ final String type = PokemonUtils.formatType(p.getSettings().getType());
return abbreviateType(type);
}
},
TYPE_2("Pokémon Type 2 abbreviated (Ghost = Gh) [2]") {
@Override
public String get(final Pokemon p) {
- final String type = p.getSettings().getType2().toString();
+ // need to strip "pokemon_type_" prefix or "pokemon_type_none"
+ final String type = PokemonUtils.formatType(p.getSettings().getType2());
return abbreviateType(type);
}
},
- TYPE_1_UNI("Pokémon Type 1 Unicode (Eletric = ⚡) [1]") {
+ TYPE_1_UNI("Pokémon Type 1 Unicode (Electric = ⚡) [1]") {
@Override
public String get(final Pokemon p) {
final String type = p.getSettings().getType().toString();
return UnicodeHelper.get(type);
}
},
- TYPE_2_UNI("Pokémon Type 2 Unicode (Eletric = ⚡) [1]") {
+ TYPE_2_UNI("Pokémon Type 2 Unicode (Electric = ⚡) [1]") {
@Override
public String get(final Pokemon p) {
final String type = p.getSettings().getType2().toString();
@@ -363,8 +382,40 @@ public String get(final Pokemon p) {
final int length = 3;
return pad((int) PokeColumn.POKEDEX_ID.get(p), length);
}
+ },
+ GENDER("Gender symbol [1]") {
+ @Override
+ public String get(final Pokemon p) {
+ final String gender = PokeColumn.GENDER.get(p).toString();
+ final String gChar;
+ if ("FEMALE".equals(gender)) {
+ gChar = UnicodeHelper.get("female");
+ } else if ("MALE".equals(gender)) {
+ gChar = UnicodeHelper.get("male");
+ } else {
+ gChar = UnicodeHelper.get("none");
+ }
+ return gChar;
+ }
};
+ /**
+ * Abbreviate Move to two characters.
+ * @param move The move.
+ * @return The abbreviated move with two characters.
+ */
+ private static String abbreviateMove(final String move) {
+ // check if move has two words
+ if (move.indexOf(StringLiterals.SPACE) > 0) {
+ final String[] moveWords = move.split(StringLiterals.SPACE);
+ // too many charge moves have the same initials so we do not make exceptions for them.
+ // this is further complicated because the moves can have STAB which is indicated by uppercase
+ return moveWords[0].substring(0, 1) + moveWords[1].substring(0, 1);
+ } else {
+ return move.substring(0, 2);
+ }
+ }
+
/**
* Abbreviate Movement/Pokémon type, to two character.
* "Gr" is Grass, so we make Ground "Gd". "Fi" is Fire, so we make Fighting "Fg".
@@ -373,10 +424,11 @@ public String get(final Pokemon p) {
* @return The abbreviated type with two characters.
*/
private static String abbreviateType(final String type) {
- if ("none".equalsIgnoreCase(type)) {
+ //we need to check if the returned type is empty
+ if (type.isEmpty()) {
return "__";
} else if ("fighting".equalsIgnoreCase(type) || "ground".equalsIgnoreCase(type)) {
- // "Gr" is Grass, so we make Ground "Gd". "Fi" is Fire, so we make Fighting "Fg"
+ //"Gr" is Grass, so we make Ground "Gd". "Fi" is Fire, so we make Fighting "Fg"
return type.substring(0, 1).toUpperCase() + type.substring(type.length() - 1).toLowerCase();
} else {
return StringUtils.capitalize(type.substring(0, 2).toLowerCase());
diff --git a/src/me/corriekay/pokegoutil/utils/pokemon/PokemonCalculationUtils.java b/src/me/corriekay/pokegoutil/utils/pokemon/PokemonCalculationUtils.java
index 7f01ac7c..89cd5b08 100644
--- a/src/me/corriekay/pokegoutil/utils/pokemon/PokemonCalculationUtils.java
+++ b/src/me/corriekay/pokegoutil/utils/pokemon/PokemonCalculationUtils.java
@@ -3,7 +3,6 @@
import java.util.List;
import com.pokegoapi.api.pokemon.Pokemon;
-import com.pokegoapi.main.PokemonMeta;
import POGOProtos.Enums.PokemonIdOuterClass.PokemonId;
import POGOProtos.Enums.PokemonMoveOuterClass.PokemonMove;
@@ -13,6 +12,7 @@
import me.corriekay.pokegoutil.utils.ConfigKey;
import me.corriekay.pokegoutil.utils.ConfigNew;
import me.corriekay.pokegoutil.utils.Utilities;
+import me.corriekay.pokegoutil.windows.PokemonGoMainWindow;
/**
* A Utility class providing several methods to calculate stats and values of Pokémon.
@@ -85,7 +85,7 @@ public static double dpsForMove(final Pokemon p, final boolean primary) {
* @return The clean dps.
*/
private static double dpsForMove(final PokemonId pokemonId, final PokemonMove move, final boolean primary) {
- final MoveSettings moveMeta = PokemonMeta.getMoveSettings(move);
+ final MoveSettings moveMeta = PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(move);
final int moveDelay = primary ? 0 : MOVE2_CHARGE_DELAY_MS;
double dps = (double) moveMeta.getPower() / (double) (moveMeta.getDurationMs() + moveDelay) * MILLISECONDS_FACTOR;
if (PokemonUtils.hasStab(pokemonId, move)) {
@@ -102,7 +102,7 @@ private static double dpsForMove(final PokemonId pokemonId, final PokemonMove mo
* @return The percentage rating how good it is compared to the best.
*/
public static double moveRating(final Pokemon p, final boolean primary) {
- final PokemonSettings pMeta = PokemonMeta.getPokemonSettings(p.getPokemonId());
+ final PokemonSettings pMeta = PokemonGoMainWindow.getPoGo().getItemTemplates().getPokemonSettings(p.getPokemonId());
double highestDps = 0;
final List moves = primary ? pMeta.getQuickMovesList() : pMeta.getCinematicMovesList();
for (final PokemonMove move : moves) {
@@ -177,7 +177,7 @@ public static double gymOffense(final Pokemon p) {
* @link i607ch00
*/
public static double gymOffense(final PokemonId pokemonId, final PokemonMove move1, final PokemonMove move2, final int attackIV) {
- final PokemonSettings meta = PokemonMeta.getPokemonSettings(pokemonId);
+ final PokemonSettings meta = PokemonGoMainWindow.getPoGo().getItemTemplates().getPokemonSettings(pokemonId);
return Math.max(
PokemonCalculationUtils.dpsForMove(pokemonId, move1, true) * WEAVE_LENGTH_SECONDS,
PokemonCalculationUtils.weaveDps(pokemonId, move1, move2, 0)
@@ -215,7 +215,7 @@ public static long gymDefense(final PokemonId pokemonId,
final PokemonMove move1, final PokemonMove move2,
final int attackIV, final int defenseIV, final int staminaIV) {
final double gymDefense = PokemonCalculationUtils.weaveDps(pokemonId, move1, move2, MOVE_2_ADDITIONAL_DELAY)
- * (PokemonMeta.getPokemonSettings(pokemonId).getStats().getBaseAttack() + attackIV)
+ * (PokemonGoMainWindow.getPoGo().getItemTemplates().getPokemonSettings(pokemonId).getStats().getBaseAttack() + attackIV)
* PokemonCalculationUtils.tankiness(pokemonId, defenseIV, staminaIV);
return Math.round(gymDefense);
}
@@ -249,7 +249,7 @@ public static long tankiness(final Pokemon p) {
* @link i607ch00
*/
public static long tankiness(final PokemonId pokemonId, final int defenseIV, final int staminaIV) {
- final PokemonSettings meta = PokemonMeta.getPokemonSettings(pokemonId);
+ final PokemonSettings meta = PokemonGoMainWindow.getPoGo().getItemTemplates().getPokemonSettings(pokemonId);
return (meta.getStats().getBaseStamina() + staminaIV) * (meta.getStats().getBaseDefense() + defenseIV);
}
@@ -284,8 +284,8 @@ public static double weaveDps(final Pokemon p, final int additionalDelay) {
* @link i607ch00
*/
public static double weaveDps(final PokemonId pokemonId, final PokemonMove move1, final PokemonMove move2, final int additionalDelay) {
- final MoveSettings pm1 = PokemonMeta.getMoveSettings(move1);
- final MoveSettings pm2 = PokemonMeta.getMoveSettings(move2);
+ final MoveSettings pm1 = PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(move1);
+ final MoveSettings pm2 = PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(move2);
final double moveOneStab = PokemonUtils.hasStab(pokemonId, move1) ? STAB_MULTIPLIER : NORMAL_MULTIPLIER;
final double moveTwoStab = PokemonUtils.hasStab(pokemonId, move2) ? STAB_MULTIPLIER : NORMAL_MULTIPLIER;
diff --git a/src/me/corriekay/pokegoutil/utils/pokemon/PokemonPerformanceCache.java b/src/me/corriekay/pokegoutil/utils/pokemon/PokemonPerformanceCache.java
index 5ddf43e5..8348c79a 100644
--- a/src/me/corriekay/pokegoutil/utils/pokemon/PokemonPerformanceCache.java
+++ b/src/me/corriekay/pokegoutil/utils/pokemon/PokemonPerformanceCache.java
@@ -2,12 +2,12 @@
import java.util.EnumMap;
-import com.pokegoapi.main.PokemonMeta;
-
import POGOProtos.Enums.PokemonIdOuterClass.PokemonId;
import POGOProtos.Enums.PokemonMoveOuterClass.PokemonMove;
import POGOProtos.Settings.Master.PokemonSettingsOuterClass.PokemonSettings;
+import me.corriekay.pokegoutil.windows.PokemonGoMainWindow;
+
/**
* A Cache class which calculates and saves several values for Pokémon to make them easily available.
*/
@@ -31,7 +31,7 @@ public final class PokemonPerformanceCache {
continue;
}
- final PokemonSettings settings = PokemonMeta.getPokemonSettings(pokemonId);
+ final PokemonSettings settings = PokemonGoMainWindow.getPoGo().getItemTemplates().getPokemonSettings(pokemonId);
PokemonPerformance highestDuelAbility = PokemonPerformance.DEFAULT_LONG;
PokemonPerformance highestGymOffense = PokemonPerformance.DEFAULT_DOUBLE;
diff --git a/src/me/corriekay/pokegoutil/utils/pokemon/PokemonUtils.java b/src/me/corriekay/pokegoutil/utils/pokemon/PokemonUtils.java
index 46ed642b..5a33ecfd 100644
--- a/src/me/corriekay/pokegoutil/utils/pokemon/PokemonUtils.java
+++ b/src/me/corriekay/pokegoutil/utils/pokemon/PokemonUtils.java
@@ -9,7 +9,6 @@
import com.pokegoapi.api.player.Team;
import com.pokegoapi.api.pokemon.Pokemon;
-import com.pokegoapi.main.PokemonMeta;
import com.pokegoapi.util.PokeDictionary;
import POGOProtos.Enums.PokemonIdOuterClass.PokemonId;
@@ -20,6 +19,7 @@
import me.corriekay.pokegoutil.utils.ConfigKey;
import me.corriekay.pokegoutil.utils.ConfigNew;
import me.corriekay.pokegoutil.utils.StringLiterals;
+import me.corriekay.pokegoutil.windows.PokemonGoMainWindow;
/**
* General Pokemon helper functions.
@@ -150,8 +150,8 @@ public static boolean hasStab(final Pokemon p, final boolean primary) {
* @return Weather or not the Pokémon has STAB.
*/
public static boolean hasStab(final PokemonId pokemonId, final PokemonMove move) {
- final PokemonSettings settings = PokemonMeta.getPokemonSettings(pokemonId);
- final MoveSettings moveSettings = PokemonMeta.getMoveSettings(move);
+ final PokemonSettings settings = PokemonGoMainWindow.getPoGo().getItemTemplates().getPokemonSettings(pokemonId);
+ final MoveSettings moveSettings = PokemonGoMainWindow.getPoGo().getItemTemplates().getMoveSettings(move);
return settings.getType().equals(moveSettings.getPokemonType()) || settings.getType2().equals(moveSettings.getPokemonType());
}
}
diff --git a/src/me/corriekay/pokegoutil/utils/windows/renderer/CellRendererHelper.java b/src/me/corriekay/pokegoutil/utils/windows/renderer/CellRendererHelper.java
index d6c67089..1535f3c7 100644
--- a/src/me/corriekay/pokegoutil/utils/windows/renderer/CellRendererHelper.java
+++ b/src/me/corriekay/pokegoutil/utils/windows/renderer/CellRendererHelper.java
@@ -9,6 +9,7 @@ public final class CellRendererHelper {
// Default renderer
public static final DefaultCellRenderer DEFAULT = new DefaultCellRenderer();
public static final NumberCellRenderer NUMBER = new NumberCellRenderer();
+ public static final NumberStringCellRenderer NUMBER_STRING = new NumberStringCellRenderer();
public static final PercentageCellRenderer PERCENTAGE = new PercentageCellRenderer();
public static final DpsCellRenderer DPS1VALUE = new DpsCellRenderer().withRatingColors(0, 17);
public static final DpsCellRenderer DPS2VALUE = new DpsCellRenderer().withRatingColors(0, 45);
diff --git a/src/me/corriekay/pokegoutil/utils/windows/renderer/DpsCellRenderer.java b/src/me/corriekay/pokegoutil/utils/windows/renderer/DpsCellRenderer.java
index 93657f25..dc876c11 100644
--- a/src/me/corriekay/pokegoutil/utils/windows/renderer/DpsCellRenderer.java
+++ b/src/me/corriekay/pokegoutil/utils/windows/renderer/DpsCellRenderer.java
@@ -8,12 +8,12 @@
import me.corriekay.pokegoutil.utils.Utilities;
/**
- * A cell renderer that displays DPS values in the format "xx.x".
+ * A cell renderer that displays DPS values in the format "xx.xx".
*/
public class DpsCellRenderer extends NumberCellRenderer {
-
- private final DecimalFormat decimalFormatter = new DecimalFormat("0.0");
+ // add another decimal so it's consistent with how it was displayed with the move.
+ private final DecimalFormat decimalFormatter = new DecimalFormat("0.00");
/**
* Creates an instance of the PercentageCellRenderer, with rating colors between 0 and 1.
diff --git a/src/me/corriekay/pokegoutil/utils/windows/renderer/NumberStringCellRenderer.java b/src/me/corriekay/pokegoutil/utils/windows/renderer/NumberStringCellRenderer.java
new file mode 100644
index 00000000..9475422b
--- /dev/null
+++ b/src/me/corriekay/pokegoutil/utils/windows/renderer/NumberStringCellRenderer.java
@@ -0,0 +1,31 @@
+package me.corriekay.pokegoutil.utils.windows.renderer;
+
+import java.awt.Component;
+
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.table.TableCellRenderer;
+
+/**
+ * A cell renderer that displays Number_String values centered.
+ */
+
+public class NumberStringCellRenderer extends JLabel implements TableCellRenderer {
+
+ private static final long serialVersionUID = -8702214651553397401L;
+
+ /**
+ * Makes number_string values display centered.
+ */
+ @Override
+ public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected,
+ final boolean hasFocus, final int rowIndex, final int columnIndex) {
+ if (value != null) {
+ final DefaultCellRenderer numberStringCellRenderer = new DefaultCellRenderer();
+ numberStringCellRenderer.setHorizontalAlignment(JLabel.CENTER);
+ table.getColumnModel().getColumn(columnIndex).setCellRenderer(numberStringCellRenderer);
+ }
+ return this;
+ }
+
+}
diff --git a/src/me/corriekay/pokegoutil/windows/MenuBar.java b/src/me/corriekay/pokegoutil/windows/MenuBar.java
index c5152587..3ea8dc42 100644
--- a/src/me/corriekay/pokegoutil/windows/MenuBar.java
+++ b/src/me/corriekay/pokegoutil/windows/MenuBar.java
@@ -40,7 +40,7 @@ public MenuBar(PokemonGo go, PokemonTab pokemonTab) {
});
file.add(trainerStats);
- JMenuItem logout = new JMenuItem("Logout");
+ JMenuItem logout = new JMenuItem("Exit");
logout.addActionListener(al -> {
try {
logout();
@@ -117,12 +117,12 @@ public MenuBar(PokemonGo go, PokemonTab pokemonTab) {
});
help.add(checkUpdates);
- JMenuItem about = new JMenuItem("About");
+ final JMenuItem about = new JMenuItem("About");
about.addActionListener(l -> JOptionPane.showMessageDialog(null,
"Version: " + Updater.getUpdater().currentVersion
+ StringLiterals.NEWLINE
+ StringLiterals.NEWLINE + "Original Author: Corrie 'Blossom' Kay"
- + StringLiterals.NEWLINE + "Current Author: Wolfsblvt"
+ + StringLiterals.NEWLINE + "Current Authors: Wolfsblvt, FernandoTBarros"
+ StringLiterals.NEWLINE
+ StringLiterals.NEWLINE + "Collaborators: Ljay, naderki, wullxz,"
+ StringLiterals.NEWLINE + "Cryptically, eralpsahin, weblue,"
@@ -138,6 +138,8 @@ public MenuBar(PokemonGo go, PokemonTab pokemonTab) {
+ StringLiterals.NEWLINE
+ StringLiterals.NEWLINE + "Thanks to Grover for providing"
+ StringLiterals.NEWLINE + "such a great API."
+ + StringLiterals.NEWLINE + "Thanks to gegy1000 for keeping up"
+ + StringLiterals.NEWLINE + "Grover's work."
+ StringLiterals.NEWLINE
+ StringLiterals.NEWLINE + "Thanks to Draseart for "
+ "the icon art.",
@@ -148,7 +150,7 @@ public MenuBar(PokemonGo go, PokemonTab pokemonTab) {
}
private void logout() throws Exception {
- AccountController.logOff();
+ System.exit(0);
}
private void displayTrainerStats() throws Exception {
diff --git a/src/me/corriekay/pokegoutil/windows/PokemonGoMainWindow.java b/src/me/corriekay/pokegoutil/windows/PokemonGoMainWindow.java
index fbf90665..9e350963 100644
--- a/src/me/corriekay/pokegoutil/windows/PokemonGoMainWindow.java
+++ b/src/me/corriekay/pokegoutil/windows/PokemonGoMainWindow.java
@@ -37,7 +37,7 @@ public class PokemonGoMainWindow extends JFrame {
private static final long serialVersionUID = -6224748358995357643L;
private static final int TEXT_AREA_HEIGHT = 150;
- private final PokemonGo go;
+ private static PokemonGo go;
private final PlayerProfile pp;
private final JTabbedPane tab = new JTabbedPane();
@@ -137,7 +137,7 @@ public static PokemonGoMainWindow getInstance() {
return instance;
}
- public PokemonGo getPoGo() {
+ public static PokemonGo getPoGo() {
return go;
}
diff --git a/src/me/corriekay/pokegoutil/windows/PokemonTab.java b/src/me/corriekay/pokegoutil/windows/PokemonTab.java
index 4ae16675..f32d1ee0 100644
--- a/src/me/corriekay/pokegoutil/windows/PokemonTab.java
+++ b/src/me/corriekay/pokegoutil/windows/PokemonTab.java
@@ -365,7 +365,7 @@ private void transferSelected() {
});
if (finalSelection.size() > 0) {
- System.out.println(String.format("Multi-Transfering %d pokemons, %d skipped", finalSelection.size(), skipped.intValue()));
+ System.out.println(String.format((total.intValue() > 1 ? "Multi-" : "") + "Transfering %d Pokémon, %d skipped", finalSelection.size(), skipped.intValue()));
try {
final Map transferResult = go.getInventories().getPokebank().releasePokemon(finalSelection.toArray(new Pokemon[1]));
transferResult.forEach((pokeFamilyID, candies) -> {
@@ -385,7 +385,7 @@ private void transferSelected() {
}
selectedRowsList = null;
SwingUtilities.invokeLater(this::refreshList);
- showFinishedText("Pokémon multi-transfer complete!", total.intValue(), success, skipped, err);
+ showFinishedText("Pokémon " + (total.intValue() > 1 ? "multi-" : "") + "transfer complete!", total.intValue(), success, skipped, err);
}
private void evolveSelected() {