[2.9.1] Bugfixes

Fixed #70 #69 #68 #67 #66 #64
- Changed some things to use Map instead of HashMap
This commit is contained in:
Rsl1122 2017-03-31 16:41:41 +03:00
parent 769fc0d27e
commit aaae83cb0a
16 changed files with 272 additions and 108 deletions

View File

@ -12,7 +12,7 @@
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- SoftDepended Plugins-->
<!-- SoftDepended Plugins-->
<dependency>
<groupId>com.hm</groupId>
<artifactId>advanced.achievements</artifactId>
@ -55,7 +55,7 @@
<version>0.91.4.0</version>
<scope>provided</scope>
</dependency>
<!-- -->
<!-- -->
</dependencies>
<build>
<defaultGoal>clean package install</defaultGoal>
@ -104,7 +104,7 @@
</configuration>
</plugin>
<!-- <plugin>
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>

View File

@ -152,7 +152,8 @@ public enum Phrase {
COMMAND_REQUIRES_ARGUMENTS(ChatColor.RED + "" + PREFIX + "Command requires arguments. REPLACE0"),
COMMAND_ADD_CONFIRMATION_ARGUMENT(ChatColor.RED + "" + PREFIX + "Add -a to confirm execution! REPLACE0"),
COMMAND_REQUIRES_ARGUMENTS_ONE(ChatColor.RED + "" + PREFIX + "Command requires one argument."),
COMMAND_NO_PERMISSION(ChatColor.RED + "" + PREFIX + "You do not have the required permmission.");
COMMAND_NO_PERMISSION(ChatColor.RED + "" + PREFIX + "You do not have the required permmission."),
ERROR_TOO_SMALL_QUEUE("Queue size is too small! (REPLACE0), change the setting to a higher number! (Currently REPLACE1)");
private String text;
private ChatColor color;

View File

@ -1,5 +1,7 @@
package main.java.com.djrapitops.plan.data;
import java.util.Arrays;
import java.util.Objects;
import main.java.com.djrapitops.plan.ui.Html;
/**
@ -67,8 +69,118 @@ public class AnalysisData {
playersDataArray = new String[]{"[0]","[\"No data\"]","[0]","[\"No data\"]","[0]","[\"No data\"]"};
genderData = new int[]{0,0,0};
}
// Getters and setters v---------------------------------v
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final AnalysisData other = (AnalysisData) obj;
if (this.averagePlayTime != other.averagePlayTime) {
return false;
}
if (this.totalPlayTime != other.totalPlayTime) {
return false;
}
if (Double.doubleToLongBits(this.averageAge) != Double.doubleToLongBits(other.averageAge)) {
return false;
}
if (this.totalCommands != other.totalCommands) {
return false;
}
if (this.newPlayersMonth != other.newPlayersMonth) {
return false;
}
if (this.newPlayersWeek != other.newPlayersWeek) {
return false;
}
if (this.newPlayersDay != other.newPlayersDay) {
return false;
}
if (Double.doubleToLongBits(this.gm0Perc) != Double.doubleToLongBits(other.gm0Perc)) {
return false;
}
if (Double.doubleToLongBits(this.gm1Perc) != Double.doubleToLongBits(other.gm1Perc)) {
return false;
}
if (Double.doubleToLongBits(this.gm2Perc) != Double.doubleToLongBits(other.gm2Perc)) {
return false;
}
if (Double.doubleToLongBits(this.gm3Perc) != Double.doubleToLongBits(other.gm3Perc)) {
return false;
}
if (this.banned != other.banned) {
return false;
}
if (this.active != other.active) {
return false;
}
if (this.inactive != other.inactive) {
return false;
}
if (this.joinleaver != other.joinleaver) {
return false;
}
if (this.total != other.total) {
return false;
}
if (this.totalPlayers != other.totalPlayers) {
return false;
}
if (this.totalLoginTimes != other.totalLoginTimes) {
return false;
}
if (this.ops != other.ops) {
return false;
}
if (this.totalkills != other.totalkills) {
return false;
}
if (this.totalmobkills != other.totalmobkills) {
return false;
}
if (this.totaldeaths != other.totaldeaths) {
return false;
}
if (this.sessionAverage != other.sessionAverage) {
return false;
}
if (!Objects.equals(this.commandUseTableHtml, other.commandUseTableHtml)) {
return false;
}
if (!Objects.equals(this.top20ActivePlayers, other.top20ActivePlayers)) {
return false;
}
if (!Objects.equals(this.recentPlayers, other.recentPlayers)) {
return false;
}
if (!Objects.equals(this.sortablePlayersTable, other.sortablePlayersTable)) {
return false;
}
if (!Objects.equals(this.geomapCountries, other.geomapCountries)) {
return false;
}
if (!Objects.equals(this.geomapZ, other.geomapZ)) {
return false;
}
if (!Objects.equals(this.geomapCodes, other.geomapCodes)) {
return false;
}
if (!Arrays.deepEquals(this.playersDataArray, other.playersDataArray)) {
return false;
}
if (!Arrays.equals(this.genderData, other.genderData)) {
return false;
}
return true;
}
public String getGeomapCountries() {
return geomapCountries;

View File

@ -3,6 +3,7 @@ package main.java.com.djrapitops.plan.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
@ -25,12 +26,12 @@ public class RawAnalysisData {
private long totalDeaths;
private int ops;
private List<Integer> ages;
private HashMap<String, Long> latestLogins;
private HashMap<String, Long> playtimes;
private Map<String, Long> latestLogins;
private Map<String, Long> playtimes;
private List<SessionData> sessiondata;
private HashMap<String, Integer> commandUse;
private HashMap<String, Integer> geolocations;
private HashMap<String, String> geocodes;
private Map<String, Integer> commandUse;
private Map<String, Integer> geolocations;
private Map<String, String> geocodes;
private List<Long> registered;
private int[] genders;
@ -83,11 +84,11 @@ public class RawAnalysisData {
}
}
public HashMap<String, Integer> getGeolocations() {
public Map<String, Integer> getGeolocations() {
return geolocations;
}
public HashMap<String, String> getGeocodes() {
public Map<String, String> getGeocodes() {
return geocodes;
}
@ -327,7 +328,7 @@ public class RawAnalysisData {
*
* @return
*/
public HashMap<String, Long> getLatestLogins() {
public Map<String, Long> getLatestLogins() {
return latestLogins;
}
@ -335,7 +336,7 @@ public class RawAnalysisData {
*
* @return
*/
public HashMap<String, Long> getPlaytimes() {
public Map<String, Long> getPlaytimes() {
return playtimes;
}
@ -359,7 +360,7 @@ public class RawAnalysisData {
*
* @return
*/
public HashMap<String, Integer> getCommandUse() {
public Map<String, Integer> getCommandUse() {
return commandUse;
}

View File

@ -4,6 +4,7 @@ import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import static org.bukkit.Bukkit.getOfflinePlayer;
@ -42,7 +43,11 @@ public class DataCacheClearQueue {
* @param uuids
*/
public void scheduleForClear(Collection<UUID> uuids) {
q.addAll(uuids);
try {
q.addAll(uuids);
} catch (IllegalStateException e) {
getPlugin(Plan.class).logError(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Clear Queue", Settings.PROCESS_CLEAR_LIMIT.getNumber() + ""));
}
}
/**

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.database.Database;
@ -38,12 +39,16 @@ public class DataCacheGetQueue {
* @param processors
*/
public void scheduleForGet(UUID uuid, DBCallableProcessor... processors) {
HashMap<UUID, List<DBCallableProcessor>> map = new HashMap<>();
if (map.get(uuid) == null) {
map.put(uuid, new ArrayList<>());
try {
HashMap<UUID, List<DBCallableProcessor>> map = new HashMap<>();
if (map.get(uuid) == null) {
map.put(uuid, new ArrayList<>());
}
map.get(uuid).addAll(Arrays.asList(processors));
q.add(map);
} catch (IllegalStateException e) {
getPlugin(Plan.class).logError(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Get Queue", Settings.PROCESS_GET_LIMIT.getNumber()+""));
}
map.get(uuid).addAll(Arrays.asList(processors));
q.add(map);
}
/**

View File

@ -44,9 +44,9 @@ public class DataCacheHandler {
private final SessionHandler sessionHandler;
// Queues
private final DataCacheSaveQueue saveTask;
private final DataCacheClearQueue clearTask;
private final DataCacheGetQueue getTask;
private DataCacheSaveQueue saveTask;
private DataCacheClearQueue clearTask;
private DataCacheGetQueue getTask;
// Variables
private int timesSaved;
@ -220,7 +220,6 @@ public class DataCacheHandler {
}
// Should only be called from Async thread
/**
*
*/
@ -405,7 +404,7 @@ public class DataCacheHandler {
}
this.cancel();
}
}).runTaskAsynchronously(plugin);
}).runTaskAsynchronously(plugin);
}
/**

View File

@ -4,6 +4,7 @@ import java.sql.SQLException;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.UserData;
@ -34,7 +35,11 @@ public class DataCacheSaveQueue {
* @param data
*/
public void scheduleForSave(UserData data) {
q.add(data);
try {
q.add(data);
} catch (IllegalStateException e) {
getPlugin(Plan.class).logError(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Save Queue", Settings.PROCESS_SAVE_LIMIT.getNumber() + ""));
}
}
/**
@ -42,7 +47,11 @@ public class DataCacheSaveQueue {
* @param data
*/
public void scheduleForSave(Collection<UserData> data) {
q.addAll(data);
try {
q.addAll(data);
} catch (IllegalStateException e) {
getPlugin(Plan.class).logError(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Save Queue", Settings.PROCESS_SAVE_LIMIT.getNumber() + ""));
}
}
/**
@ -50,9 +59,13 @@ public class DataCacheSaveQueue {
* @param data
*/
public void scheduleNewPlayer(UserData data) {
q.add(data);
try {
q.add(data);
} catch (IllegalStateException e) {
getPlugin(Plan.class).logError(Phrase.ERROR_TOO_SMALL_QUEUE.parse("Save Queue", Settings.PROCESS_SAVE_LIMIT.getNumber() + ""));
}
}
/**
*
*/

View File

@ -54,6 +54,9 @@ public class GamemodeTimesHandler {
GameMode oldGM = data.getLastGamemode();
HashMap<GameMode, Long> times = data.getGmTimes();
Long currentGMTime = times.get(oldGM);
if (currentGMTime == null) {
currentGMTime = 0L;
}
handler.getActivityHandler().saveToCache(data);
long lastSwap = data.getLastGmSwapTime();
long playTime = data.getPlayTime();
@ -74,9 +77,13 @@ public class GamemodeTimesHandler {
}
HashMap<GameMode, Long> times = data.getGmTimes();
handler.getActivityHandler().saveToCache(data);
Long currentGMTime = times.get(currentGM);
if (currentGMTime == null) {
currentGMTime = 0L;
}
long lastSwap = data.getLastGmSwapTime();
long playtime = data.getPlayTime();
data.setGMTime(currentGM, times.get(currentGM) + (playtime - lastSwap));
data.setGMTime(currentGM, currentGMTime + (playtime - lastSwap));
data.setLastGmSwapTime(playtime);
}

View File

@ -1,8 +1,8 @@
package main.java.com.djrapitops.plan.ui;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import main.java.com.djrapitops.plan.utilities.comparators.MapComparator;
/**
@ -18,7 +18,7 @@ public class RecentPlayersButtonsCreator {
* @param limit How many playes will be shown
* @return html p-tag list of recent logins.
*/
public static String createRecentLoginsButtons(HashMap<String, Long> map, int limit) {
public static String createRecentLoginsButtons(Map<String, Long> map, int limit) {
List<String[]> sorted = MapComparator.sortByValueLong(map);
String html = "<p>";
if (sorted.isEmpty()) {

View File

@ -1,8 +1,8 @@
package main.java.com.djrapitops.plan.ui.tables;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.comparators.MapComparator;
@ -19,7 +19,7 @@ public class SortableCommandUseTableCreator {
* @param commandUse
* @return
*/
public static String createSortedCommandUseTable(HashMap<String, Integer> commandUse) {
public static String createSortedCommandUseTable(Map<String, Integer> commandUse) {
List<String[]> sorted = MapComparator.sortByValue(commandUse);
String html = "";
if (sorted.isEmpty()) {

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@ -13,6 +14,7 @@ import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.api.Gender;
import main.java.com.djrapitops.plan.data.AnalysisData;
import main.java.com.djrapitops.plan.data.DemographicsData;
import main.java.com.djrapitops.plan.data.KillData;
import main.java.com.djrapitops.plan.data.RawAnalysisData;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.UserData;
@ -26,9 +28,6 @@ import org.bukkit.GameMode;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*
@ -144,12 +143,22 @@ public class Analysis {
analysisData.setSortablePlayersTable(AnalysisUtils.createSortablePlayersTable(rawData));
sorted.fillGeolocations();
// Fill Dataset with userdata.
rawData.parallelStream().forEach((uData) -> {
try {
HashMap<GameMode, Long> gmTimes = uData.getGmTimes();
sorted.addToGmZero(gmTimes.get(GameMode.SURVIVAL));
sorted.addToGmOne(gmTimes.get(GameMode.CREATIVE));
sorted.addToGmTwo(gmTimes.get(GameMode.ADVENTURE));
rawData.stream().forEach((uData) -> {
// try {
HashMap<GameMode, Long> gmTimes = uData.getGmTimes();
if (gmTimes != null) {
Long survival = gmTimes.get(GameMode.SURVIVAL);
if (survival != null) {
sorted.addToGmZero(survival);
}
Long creative = gmTimes.get(GameMode.CREATIVE);
if (creative != null) {
sorted.addToGmOne(creative);
}
Long adventure = gmTimes.get(GameMode.ADVENTURE);
if (adventure != null) {
sorted.addToGmTwo(adventure);
}
try {
Long gm = gmTimes.get(GameMode.SPECTATOR);
if (gm != null) {
@ -157,55 +166,68 @@ public class Analysis {
}
} catch (NoSuchFieldError e) {
}
long playTime = uData.getPlayTime();
sorted.addTotalPlaytime(playTime);
String playerName = uData.getName();
String url = HtmlUtils.getInspectUrl(playerName);
String html = Html.BUTTON.parse(url, playerName);
sorted.getLatestLogins().put(html, uData.getLastPlayed());
sorted.addTotalLoginTimes(uData.getLoginTimes());
DemographicsData demData = uData.getDemData();
int age = demData.getAge();
if (age != -1) {
sorted.getAges().add(age);
}
if (uData.isOp()) {
sorted.addOps(1);
}
if (uData.isBanned()) {
sorted.addTotalBanned(1);
} else if (uData.getLoginTimes() == 1) {
sorted.addJoinleaver(1);
} else if (AnalysisUtils.isActive(uData.getLastPlayed(), playTime, uData.getLoginTimes())) {
sorted.addActive(1);
sorted.getPlaytimes().put(html, playTime);
} else {
sorted.addInactive(1);
}
sorted.addTotalKills(uData.getPlayerKills().size());
sorted.addTotalMobKills(uData.getMobKills());
sorted.addTotalDeaths(uData.getDeaths());
List<SessionData> sessions = uData.getSessions();
if (!sessions.isEmpty()) {
sorted.getSessiondata().addAll(sessions);
}
sorted.getRegistered().add(uData.getRegistered());
sorted.addGeoloc(demData.getGeoLocation());
uData.stopAccessing();
Gender gender = demData.getGender();
if (gender == Gender.MALE) {
sorted.addToGender(0, 1);
} else if (gender == Gender.FEMALE) {
sorted.addToGender(1, 1);
} else {
sorted.addToGender(2, 1);
}
} catch (NullPointerException e) {
plugin.logError(Phrase.DATA_CORRUPTION_WARN.parse(uData.getUuid() + ""));
plugin.toLog(this.getClass().getName(), e);
}
});
long playTime = uData.getPlayTime();
sorted.addTotalPlaytime(playTime);
String playerName = uData.getName();
String url = HtmlUtils.getInspectUrl(playerName);
String html = Html.BUTTON.parse(url, playerName);
sorted.getLatestLogins().put(html, uData.getLastPlayed());
sorted.addTotalLoginTimes(uData.getLoginTimes());
DemographicsData demData = uData.getDemData();
if (demData == null) {
demData = new DemographicsData();
}
int age = demData.getAge();
if (age != -1) {
sorted.getAges().add(age);
}
if (uData.isOp()) {
sorted.addOps(1);
}
if (uData.isBanned()) {
sorted.addTotalBanned(1);
} else if (uData.getLoginTimes() == 1) {
sorted.addJoinleaver(1);
} else if (AnalysisUtils.isActive(uData.getLastPlayed(), playTime, uData.getLoginTimes())) {
sorted.addActive(1);
sorted.getPlaytimes().put(html, playTime);
} else {
sorted.addInactive(1);
}
List<KillData> playerKills = uData.getPlayerKills();
if (playerKills != null) {
sorted.addTotalKills(playerKills.size());
}
sorted.addTotalMobKills(uData.getMobKills());
sorted.addTotalDeaths(uData.getDeaths());
List<SessionData> sessions = uData.getSessions();
if (!sessions.isEmpty()) {
sorted.getSessiondata().addAll(sessions);
}
sorted.getRegistered().add(uData.getRegistered());
sorted.addGeoloc(demData.getGeoLocation());
uData.stopAccessing();
Gender gender = demData.getGender();
if (null != gender) {
switch (gender) {
case MALE:
sorted.addToGender(0, 1);
break;
case FEMALE:
sorted.addToGender(1, 1);
break;
default:
sorted.addToGender(2, 1);
break;
}
}
//} catch (NullPointerException e) {
// plugin.logError(Phrase.DATA_CORRUPTION_WARN.parse(uData.getUuid() + ""));
// plugin.toLog(this.getClass().getName(), e);
// }
});
createCloroplethMap(analysisData, sorted.getGeolocations(), sorted.getGeocodes());
// Analyze & Save RawAnalysisData to AnalysisData
createPlayerActivityGraphs(analysisData, sorted.getSessiondata(), sorted.getRegistered());
@ -231,9 +253,9 @@ public class Analysis {
}
private void createCommandUseTable(final RawAnalysisData raw, AnalysisData data) {
HashMap<String, Integer> commandUse = raw.getCommandUse();
Map<String, Integer> commandUse = raw.getCommandUse();
if (!commandUse.isEmpty()) {
data.setCommandUseTableHtml(AnalysisUtils.createTableOutOfHashMap(commandUse));
data.setCommandUseTableHtml(AnalysisUtils.createTableOutOfMap(commandUse));
data.setTotalCommands(commandUse.size());
} else {
data.setCommandUseTableHtml(Html.ERROR_TABLE_2.parse());
@ -303,16 +325,16 @@ public class Analysis {
}
}
private void createCloroplethMap(AnalysisData aData, HashMap<String, Integer> geolocations, HashMap<String, String> geocodes) {
private void createCloroplethMap(AnalysisData aData, Map<String, Integer> geolocations, Map<String, String> geocodes) {
String locations = "[";
String z = "[";
String text = "[";
for (String c : geolocations.keySet()) {
locations += "\""+c+"\"" + ",";
locations += "\"" + c + "\"" + ",";
z += geolocations.get(c) + ",";
String code = geocodes.get(c);
if (code != null) {
text += "\""+code+"\"" + ",";
text += "\"" + code + "\"" + ",";
} else {
text += "\"UNK\",";
}

View File

@ -1,10 +1,9 @@
package main.java.com.djrapitops.plan.utilities;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.SessionData;
@ -41,7 +40,7 @@ public class AnalysisUtils {
return false;
}
static String createTableOutOfHashMap(HashMap<String, Integer> commandUse) {
static String createTableOutOfMap(Map<String, Integer> commandUse) {
return SortableCommandUseTableCreator.createSortedCommandUseTable(commandUse);
}

View File

@ -141,13 +141,13 @@ public class PlaceholderUtils {
gm3 = (long) 0;
}
gmThree = gm3;
} catch (NoSuchFieldError e) {
} catch (NoSuchFieldError | NullPointerException e) {
gmThree = 0;
}
long[] gmData = new long[]{
gmTimes.get(GameMode.SURVIVAL),
gmTimes.get(GameMode.CREATIVE),
gmTimes.get(GameMode.ADVENTURE),
(gmTimes.get(GameMode.SURVIVAL) != null ? gmTimes.get(GameMode.SURVIVAL):0L),
(gmTimes.get(GameMode.CREATIVE) != null ? gmTimes.get(GameMode.CREATIVE):0L),
(gmTimes.get(GameMode.ADVENTURE) != null ? gmTimes.get(GameMode.ADVENTURE):0L),
gmThree
};
long total = gmData[0] + gmData[1] + gmData[2] + gmData[3];

View File

@ -2,8 +2,8 @@ package main.java.com.djrapitops.plan.utilities.comparators;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
@ -18,7 +18,7 @@ public class MapComparator {
* @return List with String Array, where first value is the value and second
* is the key.
*/
public static List<String[]> sortByValue(HashMap<String, Integer> hashMap) {
public static List<String[]> sortByValue(Map<String, Integer> hashMap) {
List<String[]> sortedList = new ArrayList<>();
hashMap.keySet().stream().forEach((key) -> {
sortedList.add(new String[]{"" + hashMap.get(key), key});
@ -32,7 +32,7 @@ public class MapComparator {
* @param hashMap
* @return
*/
public static List<String[]> sortByValueLong(HashMap<String, Long> hashMap) {
public static List<String[]> sortByValueLong(Map<String, Long> hashMap) {
List<String[]> sortedList = new ArrayList<>();
hashMap.keySet().stream().forEach((key) -> {
sortedList.add(new String[]{"" + hashMap.get(key), key});

View File

@ -1,7 +1,7 @@
name: Plan
author: Rsl1122
main: main.java.com.djrapitops.plan.Plan
version: 2.9.0
version: 2.9.1
softdepend:
- OnTime