topN = PrisonRanks.getInstance().getPlayerManager().getTopNPlayers().getTopNList();
String header = alt ?
RankPlayer.printRankScoreLine2Header() :
RankPlayer.printRankScoreLine1Header();
sender.sendMessage( header );
- for ( int i = posStart; i < posEnd && i < topN.size(); i++ ) {
- RankPlayer rPlayer = topN.get(i);
+ for ( int i = posStart; i < posEnd; i++ ) {
- String message = alt ?
- rPlayer.printRankScoreLine2( i + 1 ) :
- rPlayer.printRankScoreLine1( i + 1 );
+ RankPlayer rPlayer =
+ archived ?
+ TopNPlayers.getInstance().getTopNRankArchivedPlayer( i ) :
+ TopNPlayers.getInstance().getTopNRankPlayer( i );
+
+
+// PrisonRanks.getInstance().getPlayerManager().getTopNRankPlayer( i );
- sender.sendMessage(message);
+ if ( rPlayer != null ) {
+
+ String message = alt ?
+ rPlayer.printRankScoreLine2( i + 1 ) :
+ rPlayer.printRankScoreLine1( i + 1 );
+
+ sender.sendMessage(message);
+ }
}
-
}
+ private boolean contains( String search, String... values ) {
+ boolean results = false;
+
+ if ( search != null && values != null ) {
+
+ search = search.trim().toLowerCase();
+
+ for (String val : values) {
+ if ( val.toLowerCase().contains(search) ) {
+ results = true;
+ break;
+ }
+ }
+ }
+
+ return results;
+ }
+
// /**
// * This function is just an arbitrary test to access the various components.
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java
index eca72d87b..4fbcc41a0 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java
@@ -254,6 +254,19 @@ protected String ranksListLadderCostMultiplierMsg( double multiplier ) {
.localize();
}
+ protected String ranksListLadderApplyRankCostMultiplierMsg( boolean applyRankCostMultiplier ) {
+
+ // Apply global Rank Cost Multipliers to this Rank?
+
+ return PrisonRanks.getInstance().getRanksMessages()
+ .getLocalizable( "ranks_rankCommands__ranks_list_ladder_apply_ranks_cost_multplier" )
+ .withReplacements(
+ Boolean.toString( applyRankCostMultiplier ) )
+ .localize();
+ }
+
+
+
protected String ranksListEditLadderCostMultiplierMsg() {
return PrisonRanks.getInstance().getRanksMessages()
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLadders.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLadders.java
index 58c6b5f4c..cdd2dc265 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLadders.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PrisonSortableLadders.java
@@ -6,6 +6,7 @@
import java.util.TreeSet;
import tech.mcprison.prison.ranks.PrisonRanks;
+import tech.mcprison.prison.ranks.managers.LadderManager;
import tech.mcprison.prison.sorting.PrisonSorter;
public class PrisonSortableLadders
@@ -26,10 +27,10 @@ public int compare( RankLadder l1, RankLadder l2 ) {
else if ( l2 == null ) {
results = 1;
}
- else if ( "default".equalsIgnoreCase( l1.getName() ) ) {
+ else if ( LadderManager.LADDER_DEFAULT.equalsIgnoreCase( l1.getName() ) ) {
results = -999999;
}
- else if ( "prestige".equalsIgnoreCase( l1.getName() )) {
+ else if ( LadderManager.LADDER_PRESTIGES.equalsIgnoreCase( l1.getName() )) {
results = 999999;
}
else {
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java
index 370e82f2e..e3964f7cf 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadderFactory.java
@@ -114,7 +114,18 @@ else if ( rankPrison != null) {
Double rankCostMultiplier = (Double) document.get( "rankCostMultiplierPerRank" );
rankLadder.setRankCostMultiplierPerRank( rankCostMultiplier == null ? 0 : rankCostMultiplier );
+ Boolean applyRankCostMultiplierToLadder = (Boolean) document.get( "applyRankCostMultiplierToLadder" );
+ if ( applyRankCostMultiplierToLadder != null ) {
+
+ rankLadder.setApplyRankCostMultiplierToLadder( applyRankCostMultiplierToLadder );
+ }
+ else {
+ rankLadder.setApplyRankCostMultiplierToLadder( true );
+ isDirty = true;
+ }
+
+
// getPermissions().clear();
// Object perms = document.get( "permissions" );
// if ( perms != null ) {
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java
index 4e5316303..96fb1163c 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerFactory.java
@@ -12,7 +12,9 @@
import tech.mcprison.prison.output.Output;
import tech.mcprison.prison.ranks.FirstJoinHandlerMessages;
import tech.mcprison.prison.ranks.PrisonRanks;
+import tech.mcprison.prison.ranks.commands.RankUpCommand;
import tech.mcprison.prison.ranks.events.FirstJoinEvent;
+import tech.mcprison.prison.ranks.managers.LadderManager;
import tech.mcprison.prison.store.Document;
import tech.mcprison.prison.util.ConversionUtil;
@@ -103,7 +105,8 @@ public Document toDocument( RankPlayer rankPlayer ) {
* the default ladder. If not, then it will add them.
*
*
- * This is safe to run on anyone, even if they already are on the default ladder.
+ *
This is safe to run on anyone, even if they already are on the default ladder
+ * since it will skip processing for them.
*
*
* Note, this will not save the player's new rank. The save function must be
@@ -119,9 +122,15 @@ public void firstJoin( RankPlayer rankPlayer) {
Optional firstRank = defaultLadder.getLowestRank();
if ( firstRank.isPresent() ) {
- Rank rank = firstRank.get();
+ Rank defaultRank = firstRank.get();
- rankPlayer.addRank( rank );
+
+ RankUpCommand rankupCommands = PrisonRanks.getInstance().getRankManager().getRankupCommands();
+
+ rankupCommands.setPlayerRankFirstJoin( rankPlayer, defaultRank );
+
+
+// rankPlayer.addRank( defaultRank );
Prison.get().getEventBus().post(new FirstJoinEvent( rankPlayer ));
@@ -146,12 +155,12 @@ public void firstJoin( RankPlayer rankPlayer) {
*/
public boolean removeLadder( RankPlayer rankPlayer, String ladderName ) {
boolean results = false;
- if ( !ladderName.equalsIgnoreCase("default") ) {
+ if ( !ladderName.equalsIgnoreCase(LadderManager.LADDER_DEFAULT) ) {
Integer id = rankPlayer.getRanksRefs().remove(ladderName);
results = (id != null);
RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName );
- if ( ladder != null && !ladder.getName().equalsIgnoreCase( "default" ) ) {
+ if ( ladder != null && !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) ) {
rankPlayer.getLadderRanks().remove( ladder );
}
}
@@ -253,6 +262,15 @@ public PlayerRank getRank( RankPlayer rankPlayer, RankLadder ladder ) {
// }
+ /**
+ * This function is used when setting up a RankPlayer after loading from the
+ * file system. This takes the magic numbers that are used for ranks/ladders and
+ * finds the correct matches, which results in actual Rank objects. These ranks are
+ * then saved within the RankPlayer object for each player.
+ *
+ *
+ * @param rankPlayer
+ */
public void setupLadderRanks( RankPlayer rankPlayer ) {
if ( rankPlayer.getLadderRanks().isEmpty() && !rankPlayer.getRanksRefs().isEmpty() ) {
@@ -270,7 +288,8 @@ public void setupLadderRanks( RankPlayer rankPlayer ) {
for ( Rank rank : ladder.getRanks() ) {
if ( rank.getId() == rankId ) {
- PlayerRank pRank = createPlayerRank( rank );
+ PlayerRank pRank = rankPlayer.calculateTargetPlayerRank( rank );
+// PlayerRank pRank = createPlayerRank( rank );
rankPlayer.getLadderRanks().put( ladder, pRank );
break;
@@ -279,7 +298,7 @@ public void setupLadderRanks( RankPlayer rankPlayer ) {
}
}
- // Need to recalculate all rank multipliers:
+ // Need to recalculate all rank multipliers: This may be redundant.
rankPlayer.recalculateRankMultipliers();
}
@@ -307,6 +326,19 @@ public PlayerRank getRank( RankPlayer rankPlayer, String ladderName ) {
}
+ /**
+ * This function will create a PlayerRank without a player. This is to be
+ * used only with caution and where a player cannot be created, such as
+ * a command to list generic PlayerRanks.
+ *
+ *
+ * This is only used in one location:
+ * tech.mcprison.prison.ranks.commands.RanksCommands.rankInfoDetails(CommandSender, Rank, String)
+ *
+ *
+ * @param rank
+ * @return
+ */
public PlayerRank createPlayerRank( Rank rank ) {
PlayerRank results = new PlayerRank( rank );
@@ -317,37 +349,37 @@ public PlayerRank createPlayerRank( Rank rank ) {
return results;
}
- private PlayerRank createPlayerRank( Rank rank, double rankMultiplier ) {
- PlayerRank results = new PlayerRank( rank, rankMultiplier );
-
- return results;
- }
+// private PlayerRank createPlayerRank( Rank rank, double rankMultiplier ) {
+// PlayerRank results = new PlayerRank( rank, rankMultiplier );
+//
+// return results;
+// }
public PlayerRank getTargetPlayerRankForPlayer( PlayerRank playerRank,
RankPlayer player, Rank targetRank ) {
- PlayerRank targetPlayerRank = null;
+ PlayerRank targetPlayerRank = player.calculateTargetPlayerRank( targetRank );
- if ( targetRank != null ) {
-
- double targetRankMultiplier = playerRank.getLadderBasedRankMultiplier( targetRank );
-
- PlayerRank pRankForPLayer = getRank( player, targetRank.getLadder() );
- double existingRankMultiplier = pRankForPLayer == null ? 0 :
- playerRank.getLadderBasedRankMultiplier( pRankForPLayer.getRank() );
-
- // Get the player's total rankMultiplier from the default ladder
- // because they will always have a rank there:
- PlayerRank pRank = getRank( player, "default" );
- double playerMultipler = pRank == null ? 0 : pRank.getRankMultiplier();
-
- // So the actual rank multiplier that needs to be used, is based upon the
- // Player's current multiplier PLUS the multiplier for the target rank
- // AND MINUS the multiplier for the current rank the player has within the
- // target rank's ladder.
- double rankMultiplier = playerMultipler + targetRankMultiplier - existingRankMultiplier;
-
- targetPlayerRank = createPlayerRank( targetRank, rankMultiplier );
- }
+// if ( targetRank != null ) {
+//
+// double targetRankMultiplier = playerRank.getLadderBasedRankMultiplier( targetRank );
+//
+// PlayerRank pRankForPLayer = getRank( player, targetRank.getLadder() );
+// double existingRankMultiplier = pRankForPLayer == null ? 0 :
+// playerRank.getLadderBasedRankMultiplier( pRankForPLayer.getRank() );
+//
+// // Get the player's total rankMultiplier from the default ladder
+// // because they will always have a rank there:
+// PlayerRank pRank = getRank( player, LadderManager.LADDER_DEFAULT );
+// double playerMultipler = pRank == null ? 0 : pRank.getRankMultiplier();
+//
+// // So the actual rank multiplier that needs to be used, is based upon the
+// // Player's current multiplier PLUS the multiplier for the target rank
+// // AND MINUS the multiplier for the current rank the player has within the
+// // target rank's ladder.
+// double rankMultiplier = playerMultipler + targetRankMultiplier - existingRankMultiplier;
+//
+// targetPlayerRank = createPlayerRank( targetRank, rankMultiplier );
+// }
return targetPlayerRank;
}
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java
index a0505eb78..8a5185a09 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayerSortableLadderRankBalance.java
@@ -165,7 +165,8 @@ private double calculateTopScore( RankPlayer rp1, Rank rank, double balance ) {
// PlayerRank pRank = rp1.getRank( rank.getLadder() );
// This calculates the target rank, and takes in to consideration the player's existing rank:
- PlayerRank pRankNext = pRank.getTargetPlayerRankForPlayer( rp1, nextRank );
+ PlayerRank pRankNext = rp1.calculateTargetPlayerRank( nextRank );
+// PlayerRank pRankNext = pRank.getTargetPlayerRankForPlayer( rp1, nextRank );
// PlayerRank pRankNext = nextRank == null ? null :
// new PlayerRank( nextRank, pRank.getRankMultiplier() );
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java
new file mode 100644
index 000000000..e19114800
--- /dev/null
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java
@@ -0,0 +1,591 @@
+package tech.mcprison.prison.ranks.data;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import tech.mcprison.prison.Prison;
+import tech.mcprison.prison.file.FileIOData;
+import tech.mcprison.prison.file.JsonFileIO;
+import tech.mcprison.prison.internal.Player;
+import tech.mcprison.prison.ranks.PrisonRanks;
+import tech.mcprison.prison.ranks.tasks.TopNPlayerUpdateAsyncTask;
+
+public class TopNPlayers
+ implements FileIOData {
+
+ private static TopNPlayers instance = null;
+
+ public static final transient String PATH__TOP_N_PLAYERS = "data_storage";
+ public static final transient String FILE_NAME__TOP_N_PLAYERS_JSON = "prisonTopN.json";
+
+ public static final transient long DELAY_THIRTY_SECONDS_TICKS = 20 * 30;
+ public static final transient long INTERVAL_FIVE_MINUTES_TICKS = 20 * 60 * 5;
+
+ public static final long ONE_DAY_MS = 24 * 60 * 60 * 1000; // 1 day in ms
+
+ public static final long ARCHIVE_CUTOFF_DAYS = 90; // 90 days
+
+ private transient long archiveCutoffDaysMS;
+
+ public transient File saveFile = null;
+
+ private ArrayList topNList;
+ private transient TreeMap topNMap;
+
+ private ArrayList archivedList;
+ private transient TreeMap archivedMap;
+
+ private transient boolean calculatedRankScores = false;
+
+ private transient boolean dirty = false;
+
+ private TopNPlayers() {
+ super();
+
+ this.topNList = new ArrayList<>();
+ this.topNMap = new TreeMap<>();
+
+ this.archivedList = new ArrayList<>();
+ this.archivedMap = new TreeMap<>();
+
+ this.dirty = false;
+
+ this.archiveCutoffDaysMS =
+ ONE_DAY_MS * Prison.get().getPlatform().getConfigLong(
+ "topNPlayers.archive.cutoff-days", ARCHIVE_CUTOFF_DAYS );
+
+// launchTopNPlayerUpdateAsyncTask();
+
+ }
+
+ public static TopNPlayers getInstance() {
+
+ if ( instance == null ) {
+ synchronized ( TopNPlayers.class ) {
+ if ( instance == null ) {
+ instance = new TopNPlayers();
+
+ instance.loadSaveFile();
+
+ instance.launchTopNPlayerUpdateAsyncTask();
+ }
+ }
+ }
+
+ return instance;
+ }
+
+ /**
+ * The PlayerState will identify
+ * @author Blue
+ *
+ */
+ public enum PlayerState {
+// unknown,
+ offline,
+ online,
+ archived;
+ }
+
+ public File getSaveFile() {
+ if ( this.saveFile == null ) {
+
+ File directory = new File( Prison.get().getDataFolder(), PATH__TOP_N_PLAYERS );
+
+ this.saveFile = new File( directory, FILE_NAME__TOP_N_PLAYERS_JSON );
+ }
+ return saveFile;
+ }
+
+ private void launchTopNPlayerUpdateAsyncTask() {
+
+ Long delayTicks = Prison.get().getPlatform().getConfigLong(
+ "topNPlayers.refresh.delay-ticks", DELAY_THIRTY_SECONDS_TICKS );
+ Long intervalTicks = Prison.get().getPlatform().getConfigLong(
+ "topNPlayers.refresh.interval-ticks", INTERVAL_FIVE_MINUTES_TICKS );
+
+
+ TopNPlayerUpdateAsyncTask.submitTaskTimerAsync( this, delayTicks, intervalTicks );
+ }
+
+ /**
+ *
Upon server startup, in an asynch thread, this function should be called
+ * to load the saved data from the file system. If there is no saved data,
+ * then this function will access the PlayerManager and build an initial
+ * collection from the existing players.
+ *
+ *
+ * If any changes were made to any collections, or preexisting topN entries,
+ * then this class will be marked as dirty so this loader would know that
+ * it needs to update the save file. It will then save it changes.
+ *
+ */
+ public void loadSaveFile() {
+ JsonFileIO jfio = new JsonFileIO();
+
+ TopNPlayers temp = (TopNPlayers) jfio.readJsonFile( getSaveFile(), this );
+
+ if ( temp != null &&
+ (temp.getTopNList().size() > 0 ||
+ temp.getArchivedList().size() > 0 )) {
+
+ // Load from file was successful!
+ setTopNList( temp.getTopNList() );
+ setTopNMap( temp.getTopNMap() );
+ setArchivedList( temp.getArchivedList() );
+ setArchivedMap( temp.getArchivedMap() );
+
+ // Since loading from a file, some players may now need to be archived:
+ checkArchives();
+ }
+ else {
+ // load from file was not successful, probably because there is no file.
+ // So create a new collection of players from the PlayerManager:
+ List players = PrisonRanks.getInstance().getPlayerManager().getPlayers();
+
+ for (RankPlayer rankPlayer : players) {
+
+ addPlayerData( rankPlayer );
+ }
+
+ // Do not need to check archives since the last seen date is processed
+ // when adding the player data.
+ }
+
+
+ // Sort:
+ sortTopN();
+
+
+ if ( isDirty() ) {
+ saveToJson();
+ }
+ }
+
+ public void forceReloadAllPlayers() {
+
+ getTopNList().clear();
+ getTopNMap().clear();
+
+ getArchivedList().clear();
+ getArchivedMap().clear();
+
+
+ // load from file was not successful, probably because there is no file.
+ // So create a new collection of players from the PlayerManager:
+ List players = PrisonRanks.getInstance().getPlayerManager().getPlayers();
+
+ for (RankPlayer rankPlayer : players) {
+
+ addPlayerData( rankPlayer );
+ }
+
+ this.dirty = true;
+
+ // Sort:
+ sortTopN();
+
+ saveToJson();
+
+ }
+
+ public void saveToJson() {
+ JsonFileIO jfio = new JsonFileIO();
+
+ jfio.saveJsonFile( getSaveFile(), this );
+ }
+
+ private void checkArchives() {
+
+ ArrayList temp = new ArrayList<>();
+
+ long archiveDate = System.currentTimeMillis() - archiveCutoffDaysMS;
+
+ // Locate the entries that need to be archived:
+ for ( TopNPlayersData topN : topNList ) {
+ if ( topN.getLastSeen() < archiveDate ) {
+ temp.add(topN);
+ }
+ }
+
+ // Now move them to the archived state:
+ for (TopNPlayersData topN : temp) {
+
+ // remove from list and map:
+ getTopNList().remove(topN);
+ getTopNMap().remove( topN.getKey() );
+
+ // Change the status:
+ topN.setPlayerState( PlayerState.archived );
+
+ getArchivedList().add(topN);
+ getArchivedMap().put( topN.getKey(), topN );
+ }
+
+ if ( temp.size() > 0 ) {
+
+ setDirty( true );
+ }
+
+ }
+
+
+ /**
+ * This adds the topN player data. This player may already be in the
+ * collection, so if they are, then this is treated more like an update.
+ *
+ *
+ * @param topN
+ */
+ private void addPlayerData( TopNPlayersData topN, PlayerState activePlayerState ) {
+
+ long archiveDate = System.currentTimeMillis() - archiveCutoffDaysMS;
+
+ // First remove the player from all collections since it will be added back.
+ // Since the last seen date may have changed, it may be added to a different
+ // collection, hence why it needs to be first removed.
+ if ( getTopNMap().containsKey( topN.getKey() ) ) {
+
+ TopNPlayersData temp = getTopNMap().remove( topN.getKey() );
+ getTopNList().remove( temp );
+
+ setDirty( true );
+ }
+
+ // Remove the player from both the archive map and list:
+ if ( getArchivedMap().containsKey( topN.getKey() ) ) {
+
+ TopNPlayersData temp = getArchivedMap().remove( topN.getKey() );
+ getArchivedList().remove( temp );
+
+ setDirty( true );
+ }
+
+
+ // If they were last seen past the archive date, then archive them:
+ if ( topN.getLastSeen() < archiveDate ) {
+ topN.setPlayerState( PlayerState.archived );
+
+ getArchivedList().add(topN);
+ getArchivedMap().put( topN.getKey(), topN );
+
+ setDirty( true );
+ }
+ else {
+
+ topN.setPlayerState( activePlayerState );
+
+ getTopNList().add(topN);
+ getTopNMap().put( topN.getKey(), topN );
+
+ setDirty( true );
+ }
+
+ }
+
+ public void refreshAndSort() {
+
+ if ( !calculatedRankScores ) {
+
+ calculateAllRankScores( getTopNList() );
+ calculateAllRankScores( getArchivedList() );
+
+ calculatedRankScores = true;
+ }
+
+ // Get online players:
+ List onlinePlayer = Prison.get().getPlatform().getOnlinePlayers();
+
+
+
+ // Set all topNList entries to offline:
+ for ( TopNPlayersData topN : topNList ) {
+ if ( topN.getPlayerState() == PlayerState.online ) {
+
+ topN.setPlayerState( PlayerState.offline );
+ }
+ }
+
+ // Apply online only to online players:
+ for (Player player : onlinePlayer) {
+
+ RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(player);
+
+ // Recalculate rankScore:
+ rPlayer.calculateRankScore();
+
+ TopNPlayersData topN = null;
+
+ String key = player.getPlayerFileName();
+ if ( getTopNMap().containsKey(key) ) {
+ topN = getTopNMap().get(key);
+
+ // Set the RankPlayer object if it has not been set already:
+ if ( topN.getrPlayer() == null ) {
+ topN.setrPlayer( rPlayer );
+ }
+
+ topN.updateRankPlayer( rPlayer );
+ }
+ if ( getArchivedMap().containsKey(key) ) {
+ // The player was archived. Remove them from the archive and add them back
+ // to the topN:
+ topN = getArchivedMap().get(key);
+
+ // Set the RankPlayer object if it has not been set already:
+ if ( topN.getrPlayer() == null ) {
+ topN.setrPlayer( rPlayer );
+ }
+
+ topN.updateRankPlayer( rPlayer );
+
+ }
+ else {
+ // Player is online, but yet they are not in the topN:
+ topN = new TopNPlayersData( rPlayer );
+ }
+
+ // Set last seen date:
+ topN.setLastSeen( System.currentTimeMillis() );
+
+ addPlayerData( topN, PlayerState.online );
+
+ // Add player will always set the PlayerState to offline, so need to set it to
+ // online after addPlayerData() is called;
+// topN.setPlayerState( PlayerState.online );
+
+
+ setDirty( true );
+
+ }
+
+ ArrayList newTopNList = new ArrayList<>();
+ newTopNList.addAll( getTopNMap().values() );
+
+ ArrayList newArchivedList = new ArrayList<>();
+ newArchivedList.addAll( getArchivedMap().values() );
+
+
+ TopNPlayersData comparator = new TopNPlayersData();
+
+ Collections.sort( newTopNList, comparator );
+ Collections.sort( newArchivedList, comparator );
+
+ setTopNList(newTopNList);
+ setArchivedList(newArchivedList);
+
+// // sort:
+// sortTopN();
+
+ // If there has been any changes since the last save, then
+ // save it:
+ if ( isDirty() ) {
+ setDirty( false );
+ saveToJson();
+ }
+ }
+
+ private void calculateAllRankScores( ArrayList topNList ) {
+
+ for ( TopNPlayersData topN : topNList ) {
+
+ RankPlayer rPlayer = topN.getrPlayer();
+
+ if ( rPlayer == null ) {
+ UUID nullUuid = null;
+ rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( nullUuid, topN.getName() );
+ topN.setrPlayer(rPlayer);
+ }
+
+ if ( rPlayer != null ) {
+ rPlayer.calculateRankScore();
+
+ // This will not update lastSeen:
+ topN.updateRankPlayer( rPlayer );
+ }
+
+ }
+ }
+
+ /**
+ * This sorts both the topNList and the archivedList.
+ *
+ */
+ private void sortTopN() {
+
+ TopNPlayersData comparator = new TopNPlayersData();
+
+ Collections.sort( getTopNList(), comparator );
+ Collections.sort( getArchivedList(), comparator );
+ }
+
+
+ /**
+ * This function will add the RankPlayer data to the topN collections.
+ * This does NOT sort any of the results, so this is to be used to add a lot
+ * of entries, such as on server startup, or with updating with OnlinePlayers.
+ *
+ *
+ * See updatePlayerData() if being used with a single player, such as with rankup.
+ *
+ *
+ * @param rPlayer
+ */
+ public void addPlayerData( RankPlayer rPlayer ) {
+
+ // Recalculate the rankScore for the player:
+ rPlayer.calculateRankScore();
+
+ TopNPlayersData topN = getTopNPlayer( rPlayer );
+
+ // Since this is used when the players are being loaded, assume all are offline for now.
+ // The recurring task of processing online players will set them to online.
+ addPlayerData( topN, PlayerState.offline );
+
+ }
+
+ private TopNPlayersData getTopNPlayer(RankPlayer rPlayer) {
+
+ TopNPlayersData topN = null;
+
+ String key = rPlayer.getPlayerFileName();
+
+ if ( getTopNMap().containsKey( key ) ) {
+
+ topN = getTopNMap().get( key );
+ }
+ else if ( getArchivedMap().containsKey( key ) ) {
+
+ topN = getArchivedMap().get( key );
+ }
+ else {
+
+ topN = new TopNPlayersData( rPlayer );
+ }
+
+ return topN;
+ }
+
+ /**
+ * This function will update, or add, a player's information within topN. and when
+ * The first thing this function does, is to calculate the rankScore for the RankPlayer.
+ * It will then add the player to the topN. When finished it will provide a
+ * simple sort of the topN results. This will allow the player
+ * who just ranked up to reflect their changes in topN without having to
+ * wait until the whole topN set is refreshed. The sorting used here will not update
+ * any of the other player's balances or status, so this has a low-cost sorting.
+ *
+ *
+ * @param rPlayer
+ */
+ public void updatePlayerData( RankPlayer rPlayer ) {
+
+ addPlayerData( rPlayer);
+
+ sortTopN();
+ }
+
+ public int getTopNSize() {
+ return getTopNList().size();
+ }
+ public int getArchivedSize() {
+ return getArchivedList().size();
+ }
+
+ public RankPlayer getTopNRankPlayer( int rankPosition ) {
+ return getTopNRankPlayer( rankPosition, false );
+ }
+
+ public RankPlayer getTopNRankArchivedPlayer( int rankPosition ) {
+ return getTopNRankPlayer( rankPosition, true );
+ }
+
+ /**
+ * This function will return the RankPlayer that is at the given rankPosition
+ * within the topN collection. If rankPosition is out of range, then it will return
+ * a null value.
+ *
+ *
+ * @param rankPosition
+ * @return
+ */
+ private RankPlayer getTopNRankPlayer( int rankPosition, boolean archived ) {
+ RankPlayer rPlayer = null;
+
+ ArrayList tList =
+ archived ?
+ getArchivedList() :
+ getTopNList();
+
+ if ( rankPosition >= 0 && tList.size() > rankPosition ) {
+
+ TopNPlayersData topN = tList.get( rankPosition );
+
+ rPlayer = topN.getrPlayer();
+
+ if ( rPlayer == null ) {
+
+ UUID nullUuid = null;
+ rPlayer = PrisonRanks.getInstance().getPlayerManager()
+ .getPlayer( nullUuid, topN.getName() );
+ }
+
+ // The topN has the last extracted values, so copy them to the rPlayer if
+ // it has not been updated. This would be good for the archives.
+ if ( rPlayer != null && topN.getRankScore() != 0 && rPlayer.getRankScore() == 0 ) {
+
+ rPlayer.setRankScore( topN.getRankScore() );
+ rPlayer.setRankScorePenalty( topN.getRankScorePenalty() );
+
+ rPlayer.setRankScoreBalance( topN.getBalance() );
+ rPlayer.setRankScoreCurrency( topN.getBalanceCurrency() );
+
+ }
+
+ }
+
+
+
+ return rPlayer;
+ }
+
+
+ public ArrayList getTopNList() {
+ return topNList;
+ }
+ public void setTopNList(ArrayList topNList) {
+ this.topNList = topNList;
+ }
+
+ public TreeMap getTopNMap() {
+ return topNMap;
+ }
+ public void setTopNMap(TreeMap topNMap) {
+ this.topNMap = topNMap;
+ }
+
+ public ArrayList getArchivedList() {
+ return archivedList;
+ }
+ public void setArchivedList(ArrayList archivedList) {
+ this.archivedList = archivedList;
+ }
+
+ public TreeMap getArchivedMap() {
+ return archivedMap;
+ }
+ public void setArchivedMap(TreeMap archivedMap) {
+ this.archivedMap = archivedMap;
+ }
+
+ public boolean isDirty() {
+ return dirty;
+ }
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+}
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java
new file mode 100644
index 000000000..10aa7d42e
--- /dev/null
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayersData.java
@@ -0,0 +1,234 @@
+package tech.mcprison.prison.ranks.data;
+
+import java.text.SimpleDateFormat;
+import java.util.Comparator;
+import java.util.Date;
+
+import tech.mcprison.prison.ranks.data.TopNPlayers.PlayerState;
+
+/**
+ * This class represent a player within the topN rankings.
+ * Since PlayerState has three values:
+ *
+ *
+ * The way that the rank scores are calculated are rather complex, but this class
+ * tries to simplify the details.
+ *
+ *
+ * The primary way topN is sorted is by **current** rank positions for both the
+ * default ladder and the prestiges ladder. For the prestiges ladder, if they do not have
+ * a current rank on that ladder, then they would have a rank-ladder position of zero.
+ *
+ *
+ *
+ * These rank position values become the first and second tier of sorting.
+ *
+ *
+ *
+ * @author Blue
+ *
+ */
+public class TopNPlayersData
+ implements Comparator,
+ Comparable
+{
+
+ private String name;
+ private String playerFileName;
+
+ private PlayerState playerState;
+
+ // For report generation, not sorting:
+ private transient RankPlayer rPlayer;
+
+ private long lastSeen;
+ private String lastSeenFormatted;
+
+ private String balanceCurrency;
+ private double balance;
+
+ private double rankScore;
+ private double rankScorePenalty;
+
+ private int rankPositionDefault;
+ private int rankPositionPrestiges;
+
+ private static transient SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd kk:mm:ss" );
+
+ public TopNPlayersData() {
+ super();
+
+ this.playerState = PlayerState.offline;
+ }
+
+ public TopNPlayersData( RankPlayer rPlayer) {
+ this();
+
+ this.rPlayer = rPlayer;
+
+ this.name = rPlayer.getName();
+ this.playerFileName = rPlayer.getPlayerFileName();
+
+// // Note: the nextPlayer rank could be in either the default ladder,
+// // or the next prestige rank if at end of default ladder.
+// PlayerRank nextRank = rPlayer.getNextPlayerRank();
+
+
+ // This may be expensive getting lastSeen from the player's cache data:
+ setLastSeen( rPlayer.getPlayerCachePlayerData().getLastSeenDate() );
+
+// this.lastSeenFormatted = sdFmt.format( new Date( this.lastSeen ) );
+
+ updateRankPlayer( rPlayer );
+
+ }
+
+ public void updateRankPlayer( RankPlayer rPlayer ) {
+
+ setRankScore( rPlayer.getRankScore() );
+ setRankScorePenalty( rPlayer.getRankScorePenalty() );
+
+ setBalance( rPlayer.getRankScoreBalance() );
+ setBalanceCurrency( rPlayer.getRankScoreCurrency() );
+
+ setRankPositionDefault( rPlayer.getRankPositonDefault() );
+ setRankPositionPrestiges( rPlayer.getRankPositonPrestiges() );
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( getPlayerState().name() ).append( " " );
+
+ sb.append( getName() ).append( " " );
+ sb.append( getRankPositionPrestiges() ).append( " " );
+ sb.append( getRankPositionDefault() ).append( " " );
+
+ sb.append( getRankScore() ).append( " " );
+ sb.append( getLastSeenFormatted() ).append( " " );
+
+ return sb.toString();
+ }
+
+ @Override
+ public int compareTo(TopNPlayersData o) {
+
+ int results = Integer.compare( o.getRankPositionPrestiges(), getRankPositionPrestiges() );
+
+ if ( results == 0 ) {
+
+ results = Integer.compare( o.getRankPositionDefault(), getRankPositionDefault() );
+
+ if ( results == 0 ) {
+ results = Double.compare( o.getRankScore(), getRankScore() );
+
+ if ( results == 0 ) {
+ results = o.getName().compareToIgnoreCase( getName() );
+ }
+ }
+ }
+
+ return results;
+ }
+
+ @Override
+ public int compare(TopNPlayersData o1, TopNPlayersData o2) {
+
+ int results = o1.compareTo( o2 );
+ return results;
+ }
+
+ public String getKey() {
+ return getPlayerFileName();
+ }
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPlayerFileName() {
+ return playerFileName;
+ }
+ public void setPlayerFileName(String playerFileName) {
+ this.playerFileName = playerFileName;
+ }
+
+ public PlayerState getPlayerState() {
+ return playerState;
+ }
+ public void setPlayerState(PlayerState playerState) {
+ this.playerState = playerState;
+ }
+
+ public RankPlayer getrPlayer() {
+ return rPlayer;
+ }
+ public void setrPlayer(RankPlayer rPlayer) {
+ this.rPlayer = rPlayer;
+ }
+
+ public long getLastSeen() {
+ return lastSeen;
+ }
+ public void setLastSeen(long lastSeen) {
+
+ this.lastSeen = lastSeen;
+
+ this.lastSeenFormatted = sdFmt.format( new Date( lastSeen) );
+ }
+
+ public String getLastSeenFormatted() {
+ return lastSeenFormatted;
+ }
+ public void setLastSeenFormatted(String lastSeenFormatted) {
+ this.lastSeenFormatted = lastSeenFormatted;
+ }
+
+ public double getBalance() {
+ return balance;
+ }
+ public void setBalance(double balance) {
+ this.balance = balance;
+ }
+
+ public String getBalanceCurrency() {
+ return balanceCurrency;
+ }
+ public void setBalanceCurrency(String balanceCurrency) {
+ this.balanceCurrency = balanceCurrency;
+ }
+
+ public double getRankScore() {
+ return rankScore;
+ }
+ public void setRankScore(double rankScore) {
+ this.rankScore = rankScore;
+ }
+
+ public double getRankScorePenalty() {
+ return rankScorePenalty;
+ }
+ public void setRankScorePenalty(double rankScorePenalty) {
+ this.rankScorePenalty = rankScorePenalty;
+ }
+
+ public int getRankPositionDefault() {
+ return rankPositionDefault;
+ }
+ public void setRankPositionDefault(int rankPositionDefault) {
+ this.rankPositionDefault = rankPositionDefault;
+ }
+
+ public int getRankPositionPrestiges() {
+ return rankPositionPrestiges;
+ }
+ public void setRankPositionPrestiges(int rankPositionPrestiges) {
+ this.rankPositionPrestiges = rankPositionPrestiges;
+ }
+
+
+}
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java
index 399452417..2e9d420f0 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java
@@ -18,6 +18,7 @@
package tech.mcprison.prison.ranks.managers;
import java.io.IOException;
+import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -39,6 +40,9 @@
*/
public class LadderManager
extends LadderManagerMessages {
+
+ public static final String LADDER_DEFAULT = "default";
+ public static final String LADDER_PRESTIGES = "prestiges";
/*
* Fields & Constants
@@ -329,4 +333,40 @@ public RankLadder getLadder( Rank rank ) {
return results;
}
+
+ public String printRankLadderInfoHeader() {
+
+ String header = String.format(
+ "&d%-12s %16s %5s %-12s %-12s",
+ "Ladder",
+ "Rank Cost Mult",
+ "Ranks",
+ "First Rank",
+ "Last Rank"
+ );
+
+ return header;
+ }
+
+ public String printRankLadderInfoDetail( RankLadder ladder ) {
+
+ DecimalFormat dFmt = new DecimalFormat( "#,##0.0000" );
+
+ int rankCount = ladder.getRanks() == null ? 0 : ladder.getRanks().size();
+
+ Rank firstRank = rankCount == 0 ? null : ladder.getRanks().get(0);
+ Rank lastRank = rankCount == 0 ? null : ladder.getRanks().get( rankCount - 1 );
+
+ String ladderInfo = String.format(
+ "&7%-12s %16s %5d %-12s %-12s",
+ ladder.getName(),
+ dFmt.format( ladder.getRankCostMultiplierPerRank() ),
+ rankCount,
+ (firstRank == null ? "" : firstRank.getName()),
+ (lastRank == null ? "" : lastRank.getName())
+ );
+
+ return ladderInfo;
+ }
+
}
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java
index 4ee6189a9..e8d0e4c6e 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java
@@ -20,7 +20,6 @@
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -71,9 +70,6 @@ public class PlayerManager
private List players;
private TreeMap playersByName;
- private RankPlayerSortOrderTopRanked sorterTopN;
- private List playersByTop;
-
private List translatedPlaceHolderKeys;
@@ -87,11 +83,9 @@ public PlayerManager(Collection collection) {
this.players = new ArrayList<>();
this.playersByName = new TreeMap<>();
- this.sorterTopN = new RankPlayerSortOrderTopRanked();
- this.playersByTop= new ArrayList<>();
-
this.playerErrors = new HashSet<>();
-
+
+
Prison.get().getEventBus().register(this);
}
@@ -149,25 +143,17 @@ public void loadPlayers() throws IOException {
}
- playersByTop.add( rankPlayer );
-
}
- // NOTE: The following is very expensive operation if the players balance
- // needs to be retrieved:
- // sortPlayerByTopRanked();
-
// players.forEach(
// document ->
// this.players.add(
// rankPlayerFactory.createRankPlayer(document) ));
+
}
- public void sortPlayerByTopRanked() {
-
- Collections.sort( playersByTop, sorterTopN );
- }
+
/**
* Saves a {@link RankPlayer} to disk.
@@ -225,6 +211,26 @@ public void savePlayers() throws IOException {
}
}
+ /**
+ * If the player does not have a default rank, then assign it to them and
+ * then save their new settings.
+ *
+ *
+ * @param rPlayer
+ */
+ public void checkPlayerDefaultRank( RankPlayer rPlayer ) {
+
+ if ( rPlayer.getPlayerRankDefault() == null ) {
+
+ // Try to perform the first join processing to give them the default rank:
+ RankPlayerFactory rankPlayerFactory = new RankPlayerFactory();
+ rankPlayerFactory.firstJoin( rPlayer );
+
+ PrisonRanks.getInstance().getPlayerManager().savePlayer( rPlayer );
+
+ }
+ }
+
/**
* This function will add all the players to all of the ranks they
* are associated with.
@@ -253,9 +259,9 @@ public TreeMap getPlayersByName() {
return playersByName;
}
- public List getPlayersByTop() {
- return playersByTop;
- }
+// public List getPlayersByTop() {
+// return playersByTop;
+// }
public Set getPlayerErrors() {
return playerErrors;
@@ -582,7 +588,7 @@ public String getPlayerNextRankCost( RankPlayer rankPlayer, String ladderName,
if ( ladderName == null ||
ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) {
- boolean isDefault = ladder.getName().equals( "default" ) ;
+ boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ;
PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder );
Rank nextRank = pRank.getRank().getRankNext();
@@ -593,7 +599,8 @@ public String getPlayerNextRankCost( RankPlayer rankPlayer, String ladderName,
nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank );
// This calculates the target rank, and takes in to consideration the player's existing rank:
- PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
+ PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank );
+// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
//PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() );
@@ -635,7 +642,7 @@ private Rank getNextPrestigeRank( RankPlayer rankPlayer, boolean isDefault, Rank
isDefault &&
Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ) ) {
- RankLadder rLadder = PrisonRanks.getInstance().getLadderManager().getLadder( "prestiges" );
+ RankLadder rLadder = PrisonRanks.getInstance().getLadderManager().getLadder( LadderManager.LADDER_PRESTIGES );
if ( rLadder != null ) {
@@ -668,7 +675,7 @@ public String getPlayerNextRankCostPercent( RankPlayer rankPlayer, String ladder
if ( ladderName == null ||
ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) {
- boolean isDefault = ladder.getName().equals( "default" ) ;
+ boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ;
PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder );
Rank nextRank = pRank.getRank().getRankNext();
@@ -679,7 +686,8 @@ public String getPlayerNextRankCostPercent( RankPlayer rankPlayer, String ladder
nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank );
// This calculates the target rank, and takes in to consideration the player's existing rank:
- PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
+ PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank );
+// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() );
@@ -723,7 +731,7 @@ public String getPlayerNextRankCostBar( RankPlayer rankPlayer, String ladderName
if ( ladderName == null ||
ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) {
- boolean isDefault = ladder.getName().equals( "default" ) ;
+ boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ;
PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder );
Rank rank = pRank.getRank();
@@ -735,7 +743,8 @@ public String getPlayerNextRankCostBar( RankPlayer rankPlayer, String ladderName
nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank );
// This calculates the target rank, and takes in to consideration the player's existing rank:
- PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
+ PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank );
+// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() );
@@ -788,7 +797,7 @@ public String getPlayerNextRankCostRemaining( RankPlayer rankPlayer, String ladd
if ( ladderName == null ||
ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) {
- boolean isDefault = ladder.getName().equals( "default" ) ;
+ boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ;
PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder );
Rank rank = pRank.getRank();
@@ -800,7 +809,8 @@ public String getPlayerNextRankCostRemaining( RankPlayer rankPlayer, String ladd
nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank );
// This calculates the target rank, and takes in to consideration the player's existing rank:
- PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
+ PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank );
+// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() );
@@ -857,7 +867,7 @@ public String getPlayerNextRankCostRemainingPercent( RankPlayer rankPlayer, Stri
if ( ladderName == null ||
ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) {
- boolean isDefault = ladder.getName().equals( "default" ) ;
+ boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ;
PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder );
Rank rank = pRank.getRank();
@@ -869,7 +879,8 @@ public String getPlayerNextRankCostRemainingPercent( RankPlayer rankPlayer, Stri
nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank );
// This calculates the target rank, and takes in to consideration the player's existing rank:
- PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
+ PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank );
+// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() );
@@ -920,7 +931,7 @@ public String getPlayerNextRankCostRemainingBar( RankPlayer rankPlayer, String l
if ( ladderName == null ||
ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) {
- boolean isDefault = ladder.getName().equals( "default" ) ;
+ boolean isDefault = ladder.getName().equals( LadderManager.LADDER_DEFAULT ) ;
PlayerRank pRank = rankPlayerFactory.getRank( rankPlayer, ladder );
Rank rank = pRank.getRank();
@@ -933,7 +944,8 @@ public String getPlayerNextRankCostRemainingBar( RankPlayer rankPlayer, String l
nextRank = getNextPrestigeRank( rankPlayer, isDefault, nextRank );
// This calculates the target rank, and takes in to consideration the player's existing rank:
- PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
+ PlayerRank nextPRank = rankPlayer.calculateTargetPlayerRank( nextRank );
+// PlayerRank nextPRank = pRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() );
@@ -1234,6 +1246,112 @@ public String getPlayerNextRankName( RankPlayer rankPlayer, String ladderName )
return sb.toString();
}
+
+ public String getPlayerNextLinkedRankTag( RankPlayer rankPlayer, String ladderName ) {
+ StringBuilder sb = new StringBuilder();
+
+ // Must always have a default rank:
+ PlayerRank pRankDefault = rankPlayer.getPlayerRankDefault();
+
+ // Prestiges ladder may not be enabled, or this may be null because they have not yet prestiged:
+ PlayerRank pRankPrestiges = rankPlayer.getPlayerRankPrestiges();
+
+ if ( ladderName == null || ladderName.equalsIgnoreCase( LadderManager.LADDER_PRESTIGES ) ) {
+
+
+ // If default rank is the last rank, or at the last prestiges rank,
+ // then get next prestige rank for player:
+ if ( pRankDefault.getRank().getRankNext() == null ) {
+
+ // If the player does not have a prestiges rank, then get the first one:
+ if ( pRankPrestiges == null && PrisonRanks.getInstance().getPrestigesLadder() != null ) {
+
+ Rank firstPrestigeRank = PrisonRanks.getInstance().getPrestigesLadder().getLowestRank().orElse(null);
+ if ( firstPrestigeRank != null ) {
+ sb.append( firstPrestigeRank.getTag() );
+ }
+ }
+ // Else if player has a prestige rank, and there is a next prestige rank, get it's tag:
+ else if ( pRankPrestiges != null && pRankPrestiges.getRank().getRankNext() != null ) {
+ sb.append( pRankPrestiges.getRank().getRankNext().getTag() );
+
+ }
+
+ // else, if player has a prestige rank, and it's the last one, then just get that tag:
+ else if ( pRankPrestiges != null ) {
+ sb.append( pRankPrestiges.getRank().getTag() );
+
+ }
+
+ }
+ // else just get current prestige rank for player:
+ else if ( pRankPrestiges != null ) {
+
+ sb.append( pRankPrestiges.getRank().getTag() );
+ }
+ }
+ if ( ladderName == null || ladderName.equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) ) {
+
+ boolean showFirstRank = false;
+ boolean showNextRank = true;
+
+
+ // If at last default rank, then get the default ladder's first rank's tag or just show current tag:
+ if ( pRankDefault.getRank().getRankNext() == null ) {
+
+ // Since the current default rank is the last, cannot show next default rank:
+ showNextRank = false;
+
+ Rank firstPrestigeRank = PrisonRanks.getInstance().getPrestigesLadder().getLowestRank().orElse(null);
+
+ // If firstPrestigeRank is null, then prestiges is not enabled, so cannot show first rank:
+ if ( firstPrestigeRank == null ) {
+ showFirstRank = false;
+// showNextRank = false;
+ }
+
+ // If current presetiges is null, then use the first prestiges rank:
+ else if ( pRankPrestiges == null ) {
+ showFirstRank = true;
+// showNextRank = false;
+
+ }
+ else if ( pRankPrestiges.getRank().getRankNext() == null ) {
+ // At the last presetiges rank... so do not reset the default ranks:
+ showFirstRank = false;
+ }
+
+ else {
+ // Presetige is possible, so show first default rank:
+ showFirstRank = true;
+
+ }
+
+ }
+
+
+ if ( !showFirstRank && !showNextRank ) {
+ // Show current rank:
+
+ sb.append( pRankDefault.getRank().getTag() );
+ }
+ else if ( showFirstRank ) {
+
+ Rank firstDefaultRank = PrisonRanks.getInstance().getDefaultLadder().getLowestRank().orElse(null);
+ sb.append( firstDefaultRank.getTag() );
+ }
+ else {
+ // Show next rank:
+
+ // Not at last default rank, so get next rank tag:
+ sb.append( pRankDefault.getRank().getRankNext().getTag() );
+ }
+
+ }
+
+ return sb.toString();
+ }
+
public String getPlayerNextRankTag( RankPlayer rankPlayer, String ladderName ) {
StringBuilder sb = new StringBuilder();
@@ -1292,7 +1410,7 @@ public String getPlayerNextRankTag( RankPlayer rankPlayer, String ladderName ) {
// from the language file to display in the place of the empty tag.
// The idea is that if prestiges is enabled, then this is a way to
// indicate the player could prestige as the next step.
- if ( sb.length() == 0 && "default".equalsIgnoreCase( ladderName ) ) {
+ if ( sb.length() == 0 && LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladderName ) ) {
String replacementText = lastRankMessageForDefaultLadder();
if ( replacementText != null && !replacementText.trim().isEmpty() ) {
@@ -1458,6 +1576,13 @@ public String getTranslatePlayerPlaceHolder( PlaceholderIdentifier identifier )
results = getPlayerNextRankTag( rankPlayer, ladderName );
break;
+ case prison_rlrt:
+ case prison_rankup_linked_rank_tag:
+ case prison_rlrt_laddername:
+ case prison_rankup_linked_rank_tag_laddername:
+ results = getPlayerNextLinkedRankTag( rankPlayer, ladderName );
+ break;
+
case prison_pb:
case prison_player_balance:
case prison_pb_laddername:
@@ -1837,6 +1962,15 @@ public List getTranslatedPlaceHolderKeys() {
List ladders = PrisonRanks.getInstance().getLadderManager().getLadders();
for ( RankLadder ladder : ladders ) {
for ( PrisonPlaceHolders ph : placeHolders ) {
+
+ if ( ph.hasFlag( PlaceholderFlags.ONLY_DEFAULT_OR_PRESTIGES ) &&
+ !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_DEFAULT ) &&
+ !ladder.getName().equalsIgnoreCase( LadderManager.LADDER_PRESTIGES )
+ ) {
+ // Placeholder is invalid for ladders that are not default or prestiges, so skip:
+ continue;
+ }
+
String key = ph.name().replace(
PlaceholderManager.PRISON_PLACEHOLDER_LADDERNAME_SUFFIX, "_" + ladder.getName() ).
toLowerCase();
@@ -1876,4 +2010,6 @@ public void reloadPlaceholders() {
// Regenerate the translated placeholders:
getTranslatedPlaceHolderKeys();
}
+
+
}
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java
index 3bd6f03ba..71db7695a 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java
@@ -54,6 +54,7 @@
import tech.mcprison.prison.ranks.data.RankPlayer;
import tech.mcprison.prison.ranks.data.RankPlayerFactory;
import tech.mcprison.prison.ranks.data.StatsRankPlayerBalanceData;
+import tech.mcprison.prison.ranks.data.TopNPlayers;
import tech.mcprison.prison.store.Collection;
import tech.mcprison.prison.store.Document;
@@ -843,26 +844,26 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) {
- default:
-
- identifier.setFoundAMatch( false );
-
- Output.get().logInfo(
- "RankManager TranslateRanksPlaceHolder: Warning: a placeholder '%s' (%s) was selected " +
- "to be processed in this manager, but the placeholder is not included in the swich. " +
- "Please report to support team.",
- identifier.getPlaceholderKey().getPlaceholder().name(),
- PlaceholderFlags.STATSPLAYERS.name() );
-
- break;
- }
- }
-
- else if ( placeHolder.hasFlag( PlaceholderFlags.STATSPLAYERS ) ) {
-
- identifier.setFoundAMatch( true );
-
- switch ( placeHolder ) {
+// default:
+//
+// identifier.setFoundAMatch( false );
+//
+// Output.get().logInfo(
+// "RankManager TranslateRanksPlaceHolder: Warning: a placeholder '%s' (%s) was selected " +
+// "to be processed in this manager, but the placeholder is not included in the swich. " +
+// "Please report to support team. (1)",
+// identifier.getPlaceholderKey().getPlaceholder().name(),
+// PlaceholderFlags.STATSPLAYERS.name() );
+//
+// break;
+// }
+// }
+//
+// else if ( placeHolder.hasFlag( PlaceholderFlags.STATSPLAYERS ) ) {
+//
+// identifier.setFoundAMatch( true );
+//
+// switch ( placeHolder ) {
case prison_top_player_line1_headers__tp:
case prison_tpl1h__tp:
@@ -1081,34 +1082,81 @@ else if ( placeHolder == PrisonPlaceHolders.prison_top_player_penalty_raw_nnn_tp
break;
-
-
- default:
-
- identifier.setFoundAMatch( false );
-
- break;
- }
-
- if ( attributeText != null ) {
- results = attributeText.format( results );
+ case prison_top_rank_balance_name_nnn_rankname:
+ case prison_trbn_nnn_rankname:
+ {
+ StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 );
+ if ( stats != null ) {
+
+ results = stats.getPlayer() == null ? "" : stats.getPlayer().getName();
+ }
+ else {
+ results = "";
+ }
+ }
- Output.get().logInfo(
- "RankManager TranslateRanksPlaceHolder: Warning: a placeholder '%s' (%s) was selected " +
- "to be processed in this manager, but the placeholder is not included in the swich. " +
- "Please report to support team.",
- identifier.getPlaceholderKey().getPlaceholder().name(),
- PlaceholderFlags.STATSPLAYERS.name() );
- }
- }
-
- else if ( rank != null ) {
-
- identifier.setFoundAMatch( true );
-
- switch ( placeHolder ) {
+ break;
+
+ case prison_top_rank_balance_score_nnn_rankname:
+ case prison_trbs_nnn_rankname:
+ {
+ StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 );
+ if ( stats != null ) {
+
+ results = dFmt.format( stats.getScore());
+ }
+ else {
+ results = "";
+ }
+ }
+ break;
+
+ case prison_top_rank_balance_balance_nnn_rankname:
+ case prison_trbb_nnn_rankname:
+ {
+ StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 );
+ if ( stats != null ) {
+
+ results = stats.getPlayer() == null ? "" :
+ dFmt.format( stats.getPlayer().getBalance( rank.getCurrency()) );
+ }
+ else {
+ results = "";
+ }
+ }
+
+ break;
+
+
+
+// default:
+//
+// identifier.setFoundAMatch( false );
+//
+// break;
+// }
+//
+// if ( attributeText != null ) {
+//
+// results = attributeText.format( results );
+//
+// Output.get().logInfo(
+// "x` Warning: a placeholder '%s' (%s) was selected " +
+// "to be processed in this manager, but the placeholder is not included in the swich. " +
+// "Please report to support team. (2)",
+// identifier.getPlaceholderKey().getPlaceholder().name(),
+// PlaceholderFlags.STATSPLAYERS.name() );
+// }
+// }
+//
+// else if ( rank != null ) {
+//
+// identifier.setFoundAMatch( true );
+//
+// switch ( placeHolder ) {
+//
case prison_rank__name_rankname:
case prison_r_n_rankname:
@@ -1143,8 +1191,10 @@ else if ( rank != null ) {
case prison_rank__cost_multiplier_rankname:
case prison_r_cm_rankname:
- RankPlayerFactory rankPlayerFactory = new RankPlayerFactory();
- PlayerRank pRank = rankPlayerFactory.createPlayerRank( rank );
+ PlayerRank pRank = rankPlayer.calculateTargetPlayerRank( rank );
+
+// RankPlayerFactory rankPlayerFactory = new RankPlayerFactory();
+// PlayerRank pRank = rankPlayerFactory.createPlayerRank( rank );
results = Double.toString( pRank.getLadderBasedRankMultiplier() );
break;
@@ -1169,63 +1219,34 @@ else if ( rank != null ) {
case prison_rank__linked_mines_rankname:
case prison_r_lm_rankname:
- StringBuilder sb = new StringBuilder();
- for ( ModuleElement mine : rank.getMines() ) {
- if ( sb.length() > 0 ) {
- sb.append( ", " );
- }
- sb.append( mine.getName() );
- }
-
- results = sb.toString();
- break;
-
-
- case prison_top_rank_balance_name_nnn_rankname:
- case prison_trbn_nnn_rankname:
{
- StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 );
- if ( stats != null ) {
-
- results = stats.getPlayer() == null ? "" : stats.getPlayer().getName();
- }
- else {
- results = "";
+ StringBuilder sb = new StringBuilder();
+ for ( ModuleElement mine : rank.getMines() ) {
+ if ( sb.length() > 0 ) {
+ sb.append( ", " );
+ }
+ sb.append( mine.getName() );
}
+
+ results = sb.toString();
}
-
break;
- case prison_top_rank_balance_score_nnn_rankname:
- case prison_trbs_nnn_rankname:
+ case prison_rank__linked_mines_tag_rankname:
+ case prison_r_lmt_rankname:
{
- StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 );
- if ( stats != null ) {
-
- results = dFmt.format( stats.getScore());
- }
- else {
- results = "";
+ StringBuilder sb = new StringBuilder();
+ for ( ModuleElement mine : rank.getMines() ) {
+ if ( sb.length() > 0 ) {
+ sb.append( ", " );
+ }
+ sb.append( mine.getTag() );
}
+
+ results = sb.toString();
}
-
break;
- case prison_top_rank_balance_balance_nnn_rankname:
- case prison_trbb_nnn_rankname:
- {
- StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 );
- if ( stats != null ) {
-
- results = stats.getPlayer() == null ? "" :
- dFmt.format( stats.getPlayer().getBalance( rank.getCurrency()) );
- }
- else {
- results = "";
- }
- }
-
- break;
default:
@@ -1235,7 +1256,7 @@ else if ( rank != null ) {
Output.get().logInfo(
"RankManager TranslateRanksPlaceHolder: Warning: a placeholder '%s' was selected " +
"to be processed in this manager, but the placeholder is not included in the swich. " +
- "Please report to support team.",
+ "Please report to support team. (3)",
identifier.getPlaceholderKey().getPlaceholder().name() );
@@ -1258,61 +1279,202 @@ else if ( rank != null ) {
private RankPlayer getTopNRankPlayer( int rankPosition ) {
- RankPlayer topRankPlayer = null;
- PlayerManager pm = PrisonRanks.getInstance().getPlayerManager();
- if ( rankPosition >= 0 && rankPosition < pm.getPlayersByTop().size() ) {
-
- topRankPlayer = pm.getPlayersByTop().get(rankPosition);
- }
-
- return topRankPlayer;
+ return TopNPlayers.getInstance().getTopNRankPlayer( rankPosition );
}
- private double calculateRankCost( RankPlayer rankPlayer, Rank rank )
+ private double calculateRankCost( RankPlayer rankPlayer, Rank targetRank )
{
double cost = 0;
// Get player's rank:
RankPlayerFactory rankPlayerFactory = new RankPlayerFactory();
- PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, rank.getLadder() );
- if ( playerRank != null ) {
+ Rank rankDefault = rankPlayer.getPlayerRankDefault().getRank();
+
+ Rank rankPrestige = null;
+ PlayerRank prPrestige = rankPlayer.getPlayerRankPrestiges();
+ if ( prPrestige != null ) {
+ rankPrestige = prPrestige.getRank();
+ }
+
+ // Only continue with the processing if the target rank is a higher rank than
+ // either the current default rank or the current prestige rank. If it's not,
+ // then the player has already bought that rank so their cost will be zero:
+ if ( rankDefault.getLadder().equals( targetRank.getLadder()) &&
+ rankDefault.getPosition() < targetRank.getPosition() ||
+
+ // They have not yet prestiged:
+ rankPrestige == null ||
+
+ // Trying to calculate a prestige rank higher than their current prestige rank:
+ rankPrestige.getLadder().equals( targetRank.getLadder()) &&
+ rankPrestige.getPosition() < targetRank.getPosition()
+ ) {
+
+ ArrayList ranksList = getAllRanks( rankPlayer, rankDefault, rankPrestige, targetRank );
- // If the player is at a higher rank, or the same rank, then the cost will be
- // zero for the rank that is being passed in, since the player has
- // already paid for that rank.
- if ( rank.getPosition() <= playerRank.getRank().getPosition() ) {
- cost = 0;
- }
- else {
- //cost = playerRank.getRankCost();
- Rank nextRank = playerRank.getRank();
+ for (Rank rank : ranksList) {
- while ( nextRank != null &&
- nextRank.getPosition() <= rank.getPosition() ) {
-
- // Need to calculate the next PlayerRank value for the next rank:
-
- // This calculates the target rank, and takes in to consideration the player's existing rank:
- playerRank = playerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
-
-
-// playerRank = rankPlayerFactory.createPlayerRank( nextRank );
-// playerRank = new PlayerRank(nextRank);
+ PlayerRank pR = rankPlayerFactory.getTargetPlayerRankForPlayer(
+ rankPlayer.getPlayerRankDefault(), rankPlayer, rank );
+
+ if ( pR != null ) {
- cost += playerRank.getRankCost();
- nextRank = nextRank.getRankNext();
+ cost += pR.getRankCost();
}
}
+
}
+
+// PlayerRank playerRank = rankPlayerFactory.getRank( rankPlayer, targetRank.getLadder() );
+
+
+// if ( playerRank != null ) {
+//
+//
+//// List
+//
+//
+// // If the player is at a higher rank, or the same rank, then the cost will be
+// // zero for the rank that is being passed in, since the player has
+// // already paid for that rank.
+// if ( rank.getPosition() <= playerRank.getRank().getPosition() ) {
+// cost = 0;
+// }
+// else {
+// //cost = playerRank.getRankCost();
+// Rank nextRank = playerRank.getRank();
+//
+// while ( nextRank != null &&
+// nextRank.getPosition() <= targetRank.getPosition() ) {
+//
+// // Need to calculate the next PlayerRank value for the next rank:
+//
+// // This calculates the target rank, and takes in to consideration the player's existing rank:
+// playerRank = playerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank );
+//
+//
+//// playerRank = rankPlayerFactory.createPlayerRank( nextRank );
+//// playerRank = new PlayerRank(nextRank);
+//
+// cost += playerRank.getRankCost();
+// nextRank = nextRank.getRankNext();
+// }
+// }
+// }
return cost;
}
+
+ private ArrayList getAllRanks( RankPlayer rPlayer,
+ Rank rankDefault, Rank rankPrestige, Rank targetRank ) {
+
+ ArrayList totalRanks = new ArrayList<>();
+
+ // rankDefault is the current default rank for the player. So if rankDefault
+ // is the same as the targetRank, then exit because they already paid for the
+ // current rank, so there is no need to calculate anything else.
+ if ( !rankDefault.equals( targetRank ) ) {
+
+ // We cannot add the current default rank to the totalRanks, so get the next
+ // rank then continue. From here on out, all ranks have to be added to the
+ // the totalRanks including the targetRank.
+ Rank nextRank = rankDefault.getRankNext();
+
+ findNextRank( nextRank, rankPrestige, targetRank, totalRanks);
+ }
+
+ return totalRanks;
+ }
+
+
+ /**
+ * This function will take the default rank (result parameter) and the rankPrestige
+ * and use them to talk the ladders to find a match for the targetRank.
+ *
+ *
+ * The result Rank that is returned from this function is only useful for
+ * internal use since it will prevent the clearing of the totalRanks list
+ * when coming out of recursion. When outside of this function, then real
+ * value is within totalRanks.
+ *
+ *
+ * @param result
+ * @param rankPrestige
+ * @param targetRank
+ * @param totalRanks
+ * @return
+ */
+ private Rank findNextRank( Rank result, Rank rankPrestige, Rank targetRank, ArrayList totalRanks) {
+
+ // Search for the targetRank in the rest of the default ranks:
+ result = findNextRanksOnDefaultLadder( result, targetRank, totalRanks );
+
+ // if result is null, then not found on the default ladder, so then
+ // we must jump to the next prestige rank:
+ if ( result == null ) {
+ rankPrestige = rankPrestige == null ?
+ PrisonRanks.getInstance().getLadderManager()
+ .getLadderPrestiges().getLowestRank().orElse(null) :
+ rankPrestige.getRankNext();
+ result = rankPrestige;
+
+ if ( result != null ) {
+
+ // Need to add the result rank to the totalRanks:
+ totalRanks.add( result );
+
+ if ( !result.equals( targetRank ) ) {
+
+ // Have not found it... Set result to rank A and start over searching:
+ result = PrisonRanks.getInstance().getLadderManager()
+ .getLadderDefault().getLowestRank().orElse(null);
+
+ if ( result != null ) {
+ // recursively call it again...
+ result = findNextRank( result, rankPrestige, targetRank, totalRanks);
+ }
+ }
+ }
+ }
+
+ if ( result == null || !result.equals( targetRank ) ) {
+ // Warning: We have gone through all ranks and all prestige ranks and have not
+ // found the targetRank. That means the player has already reached
+ // the targetRank. So we MUST clear the totalRanks list so there will
+ // be no charges.
+ totalRanks.clear();
+ }
+
+ return result;
+ }
+
+ private Rank findNextRanksOnDefaultLadder( Rank rankDefault, Rank targetRank, ArrayList totalRanks ) {
+
+ Rank result = rankDefault;
+
+ if ( rankDefault != null ) {
+
+ // We need to add the current rankDefault before getting the next ranks:
+ totalRanks.add( result );
+
+ while ( result != null && !result.equals( targetRank ) ) {
+ result = result.getRankNext();
+
+ if ( result != null ) {
+
+ totalRanks.add( result );
+ }
+ }
+ }
+
+ return result;
+ }
@Override
public List getTranslatedPlaceHolderKeys() {
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankPlayerSortOrderTopRanked.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankPlayerSortOrderTopRanked.java
deleted file mode 100644
index a11570c67..000000000
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankPlayerSortOrderTopRanked.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package tech.mcprison.prison.ranks.managers;
-
-import java.util.Comparator;
-
-import tech.mcprison.prison.ranks.data.RankPlayer;
-
-public class RankPlayerSortOrderTopRanked
- implements Comparator
-{
-
-
- public RankPlayerSortOrderTopRanked() {
- super();
-
- }
-
-
- @Override
- public int compare( RankPlayer rp1, RankPlayer rp2 )
- {
- int results = 0;
-
- if ( rp1 == null && rp2 == null ) {
- results = 0;
- }
- else if ( rp1 == null ) {
- results = -1;
- }
- else if ( rp2 == null ) {
- results = 1;
- }
- else {
- results = compareLadderPrestiges( rp1, rp2 );
-
- if ( results == 0 ) {
-
- results = compareLadderDefault( rp1, rp2 );
-
- if ( results == 0 ) {
- results = Double.compare( rp1.getRankScore(), rp2.getRankScore() );
- }
- }
- }
-
- return results;
- }
-
- private int compareLadderPrestiges( RankPlayer rp1, RankPlayer rp2 ) {
- int results = 0;
-
- if ( rp1.getPlayerRankPrestiges() == null && rp2.getPlayerRankPrestiges() == null ) {
- results = 0;
- }
- else if ( rp2.getPlayerRankPrestiges() == null ) {
-// Handled when comparing PlayerRanks... ??
- results = -1;
- }
- else if ( rp1.getPlayerRankPrestiges() == null ) {
- results = 1;
- }
- else {
- results = rp2.getPlayerRankPrestiges().compareTo( rp1.getPlayerRankPrestiges() );
- }
-
- return results;
- }
-
- private int compareLadderDefault( RankPlayer rp1, RankPlayer rp2 ) {
- int results = 0;
-
- if ( rp1.getPlayerRankDefault() == null && rp2.getPlayerRankDefault() == null ) {
- results = 0;
- }
- else if ( rp2.getPlayerRankDefault() == null ) {
-// Handled when comparing PlayerRanks...
- results = -1;
- }
- else if ( rp1.getPlayerRankDefault() == null ) {
- results = 1;
- }
- else {
- results = rp2.getPlayerRankDefault().compareTo( rp1.getPlayerRankDefault() );
- }
-
- return results;
- }
-
-}
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/RanksStartupPlayerValidationsAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/RanksStartupPlayerValidationsAsyncTask.java
index be2d02fae..a4cdf427c 100644
--- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/RanksStartupPlayerValidationsAsyncTask.java
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/RanksStartupPlayerValidationsAsyncTask.java
@@ -1,6 +1,8 @@
package tech.mcprison.prison.ranks.tasks;
+import tech.mcprison.prison.output.Output;
import tech.mcprison.prison.ranks.PrisonRanks;
+import tech.mcprison.prison.ranks.data.TopNPlayers;
import tech.mcprison.prison.tasks.PrisonRunnable;
import tech.mcprison.prison.tasks.PrisonTaskSubmitter;
@@ -17,10 +19,18 @@ public RanksStartupPlayerValidationsAsyncTask( PrisonRanks pRanks ) {
public static void submitTaskSync( PrisonRanks pRanks ) {
- RanksStartupPlayerValidationsAsyncTask rspvaTask =
- new RanksStartupPlayerValidationsAsyncTask( pRanks );
-
- PrisonTaskSubmitter.runTaskLaterAsync( rspvaTask, 0 );
+ if ( PrisonRanks.getInstance().getDefaultLadderRankCount() != 0 ) {
+
+ RanksStartupPlayerValidationsAsyncTask rspvaTask =
+ new RanksStartupPlayerValidationsAsyncTask( pRanks );
+
+ PrisonTaskSubmitter.runTaskLaterAsync( rspvaTask, 0 );
+ }
+ else {
+ Output.get().logInfo( "Bypassing player validation task since no ranks have been " +
+ "defined yet.");
+ }
+
}
@Override
@@ -29,10 +39,16 @@ public void run() {
pRanks.checkAllPlayersForJoin();
- // The following can take awhile to run if there are a lot of players
- // and if they need to load their balance. This is impacted moreso if
- // there is a high cost to get the balance.
- pRanks.getPlayerManager().sortPlayerByTopRanked();
+ // Start up the TopNPlayer's collections after all players have been loaded:
+ // NOTE: getting the instance of TopNPlayers must be done "after" player validation.
+ // So that thread needs to initiate it after done validating and fixing all players.
+ TopNPlayers.getInstance();
+
+
+// // The following can take awhile to run if there are a lot of players
+// // and if they need to load their balance. This is impacted more so if
+// // there is a high cost to get the balance.
+// pRanks.getPlayerManager().sortPlayerByTopRanked();
}
}
diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/TopNPlayerUpdateAsyncTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/TopNPlayerUpdateAsyncTask.java
new file mode 100644
index 000000000..f9be9af9a
--- /dev/null
+++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/tasks/TopNPlayerUpdateAsyncTask.java
@@ -0,0 +1,42 @@
+package tech.mcprison.prison.ranks.tasks;
+
+import tech.mcprison.prison.ranks.data.TopNPlayers;
+import tech.mcprison.prison.tasks.PrisonRunnable;
+import tech.mcprison.prison.tasks.PrisonTaskSubmitter;
+
+public class TopNPlayerUpdateAsyncTask
+ implements PrisonRunnable {
+
+ private TopNPlayers topNPlayers;
+
+// private boolean startup = true;
+
+ public TopNPlayerUpdateAsyncTask( TopNPlayers topNPlayers ) {
+ super();
+
+ this.topNPlayers = topNPlayers;
+ }
+
+ public static void submitTaskTimerAsync( TopNPlayers topNPlayers,
+ Long delayTicks, long intervalTicks ) {
+
+ TopNPlayerUpdateAsyncTask asyncTask =
+ new TopNPlayerUpdateAsyncTask( topNPlayers );
+
+ PrisonTaskSubmitter.runTaskTimerAsync( asyncTask, delayTicks, intervalTicks );
+ }
+
+ @Override
+ public void run() {
+
+// if ( startup ) {
+// startup = false;
+//
+// topNPlayers.loadSaveFile();
+// }
+
+ topNPlayers.refreshAndSort();
+
+ }
+
+}
diff --git a/prison-ranks/src/test/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersTest.java b/prison-ranks/src/test/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersTest.java
index fdb23d1b0..a2bb33628 100644
--- a/prison-ranks/src/test/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersTest.java
+++ b/prison-ranks/src/test/java/tech/mcprison/prison/ranks/data/PrisonSortableLaddersTest.java
@@ -8,6 +8,8 @@
import org.junit.Test;
+import tech.mcprison.prison.ranks.managers.LadderManager;
+
public class PrisonSortableLaddersTest
extends PrisonSortableLadders
{
@@ -16,9 +18,9 @@ public class PrisonSortableLaddersTest
public void testGetSortedSet()
{
RankLadder ladderDefault = new RankLadder();
- ladderDefault.setName( "default" );
+ ladderDefault.setName( LadderManager.LADDER_DEFAULT );
RankLadder ladderPrestige = new RankLadder();
- ladderPrestige.setName( "prestige" );
+ ladderPrestige.setName( LadderManager.LADDER_PRESTIGES );
RankLadder ladderMods = new RankLadder();
ladderMods.setName( "mods" );
@@ -41,7 +43,7 @@ public void testGetSortedSet()
assertEquals( "ZaPpS", unsortedList.get( 0 ).getName() );
assertEquals( "Donors", unsortedList.get( 1 ).getName() );
- assertEquals( "prestige", unsortedList.get( 2 ).getName() );
+ assertEquals( "prestiges", unsortedList.get( 2 ).getName() );
assertEquals( "mods", unsortedList.get( 3 ).getName() );
assertEquals( "Animals", unsortedList.get( 4 ).getName() );
assertEquals( "default", unsortedList.get( 5 ).getName() );
@@ -62,7 +64,7 @@ public void testGetSortedSet()
assertEquals( "Donors", sortedList.get( 2 ).getName() );
assertEquals( "mods", sortedList.get( 3 ).getName() );
assertEquals( "ZaPpS", sortedList.get( 4 ).getName() );
- assertEquals( "prestige", sortedList.get( 5 ).getName() );
+ assertEquals( "prestiges", sortedList.get( 5 ).getName() );
}
diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle
index c92ce18ff..b7349d3bb 100644
--- a/prison-spigot/build.gradle
+++ b/prison-spigot/build.gradle
@@ -116,7 +116,8 @@ dependencies {
// implementation 'com.github.cryptomorin:xseries:b95d195482'
// https://mvnrepository.com/artifact/com.github.cryptomorin/XSeries
- implementation 'com.github.cryptomorin:XSeries:8.8.0'
+ implementation 'com.github.cryptomorin:XSeries:9.0.0'
+ //implementation 'com.github.cryptomorin:XSeries:8.8.0'
@@ -208,7 +209,8 @@ shadowJar {
include(dependency('me.clip:placeholderapi:2.10.9'))
- include(dependency('com.github.cryptomorin:XSeries:8.8.0'))
+ include(dependency('com.github.cryptomorin:XSeries:9.0.0'))
+ //include(dependency('com.github.cryptomorin:XSeries:8.8.0'))
include(dependency('de.tr7zw:item-nbt-api-plugin:2.10.0'))
diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java
index f4bdcb071..772c02ab8 100644
--- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java
+++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java
@@ -303,7 +303,7 @@ public class OnPlayerChatListener
@EventHandler(priority=EventPriority.NORMAL)
public void onPlayerChat(AsyncPlayerChatEvent e) {
- String message = e.getMessage();
+// String message = e.getMessage();
String format = e.getFormat();
SpigotPlayer p = new SpigotPlayer( e.getPlayer() );
diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java
index 31ff7da59..9e945d4da 100644
--- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java
+++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java
@@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -40,6 +41,7 @@
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.SimpleCommandMap;
+import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerChatEvent;
@@ -53,8 +55,10 @@
import tech.mcprison.prison.Prison;
import tech.mcprison.prison.PrisonCommand;
+import tech.mcprison.prison.PrisonCommand.RegisteredPluginsData;
import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures;
import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper;
+import tech.mcprison.prison.chat.FancyMessage;
import tech.mcprison.prison.commands.PluginCommand;
import tech.mcprison.prison.convert.ConversionManager;
import tech.mcprison.prison.convert.ConversionResult;
@@ -88,10 +92,12 @@
import tech.mcprison.prison.output.DisplayComponent;
import tech.mcprison.prison.output.LogLevel;
import tech.mcprison.prison.output.Output;
+import tech.mcprison.prison.output.RowComponent;
import tech.mcprison.prison.ranks.PrisonRanks;
import tech.mcprison.prison.ranks.commands.RanksCommands;
import tech.mcprison.prison.ranks.data.PlayerRank;
import tech.mcprison.prison.ranks.data.Rank;
+import tech.mcprison.prison.ranks.data.RankLadder;
import tech.mcprison.prison.ranks.data.RankPlayer;
import tech.mcprison.prison.ranks.data.RankPlayerFactory;
import tech.mcprison.prison.ranks.managers.PlayerManager;
@@ -287,7 +293,8 @@ public void getWorldLoadErrors( ChatDisplay display ) {
@Override public List getOnlinePlayers() {
return Bukkit.getOnlinePlayers().stream()
- .map(player -> getPlayer(player.getUniqueId()).get()).collect(Collectors.toList());
+ .map(player -> getPlayer(player.getUniqueId()).get())
+ .collect(Collectors.toList());
}
@Override
@@ -714,8 +721,29 @@ private boolean isDoor(Material block) {
return capabilities;
}
+ /**
+ * This can be useful to see if a given plugin is active. The returned
+ * data, RegisteredPluginData, has additional information pertaining to the
+ * plugin. If the plugin is not found, then this will return a null value.
+ *
+ *
+ * @param pluginName
+ * @return
+ */
+ public RegisteredPluginsData identifyRegisteredPlugin( String pluginName ) {
+ identifyRegisteredPlugins( false );
+
+ RegisteredPluginsData plugin = Prison.get().getPrisonCommands().getRegisteredPluginData().get( pluginName );
+
+ return plugin;
+ }
+
@Override
public void identifyRegisteredPlugins() {
+ identifyRegisteredPlugins( true );
+ }
+
+ public void identifyRegisteredPlugins( boolean checkForWarnings ) {
PrisonCommand cmdVersion = Prison.get().getPrisonCommands();
// reset so it will reload cleanly:
@@ -752,7 +780,7 @@ public void identifyRegisteredPlugins() {
}
}
- if ( isPlugManPresent ) {
+ if ( checkForWarnings && isPlugManPresent ) {
ChatDisplay chatDisplay = new ChatDisplay("&d* *&5 WARNING: &d PlugMan &5 Detected! &d* *");
chatDisplay.addText( "&7The use of PlugMan on this Prison server will corrupt internals" );
chatDisplay.addText( "&7of Prison and may lead to a non-functional state, or even total" );
@@ -1531,7 +1559,10 @@ public void autoCreateMineBlockAssignment( List rankMineNames, boolean f
// Turn on sellall:
- SpigotPrison.getInstance().getConfig().set( "sellall", true );
+ YamlConfiguration modulesConf = SpigotPrison.getInstance().loadConfig("modules.yml");
+ modulesConf.set( "sellall", Boolean.TRUE );
+ SpigotPrison.getInstance().saveConfig("modules.yml", modulesConf );
+
PrisonSpigotSellAllCommands sellall = PrisonSpigotSellAllCommands.get();
@@ -2236,7 +2267,7 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) {
results.add( String.format("Sellall Enabled:&b %s",
- getConfigBooleanFalse( "sellall" )) );
+ Boolean.toString( SpigotPrison.getInstance().isSellAllEnabled() )) );
results.add( String.format("Backpacks Enabled:&b %s",
@@ -2299,6 +2330,18 @@ else if ( !isBasic ) {
display.addText("&7Integrations:");
IntegrationManager im = Prison.get().getIntegrationManager();
+
+// Set inTypeKeys = im.getIntegrations().keySet();
+// for (IntegrationType inTypeKey : inTypeKeys ) {
+// List integrations = im.getIntegrations().get( inTypeKey );
+//
+// for (Integration integration : integrations) {
+//
+//
+//
+// }
+// }
+
String permissions =
(im.hasForType(IntegrationType.PERMISSION) ?
" " + im.getForType(IntegrationType.PERMISSION).get().getDisplayName() :
@@ -2771,4 +2814,95 @@ public void setActionBar( Player player, String actionBar ) {
public int compareServerVerisonTo( String comparisonVersion ) {
return new BluesSpigetSemVerComparator().compareMCVersionTo( comparisonVersion );
}
+
+ @Override
+ public void checkPlayerDefaultRank( RankPlayer rPlayer ) {
+
+ PrisonRanks.getInstance().getPlayerManager().checkPlayerDefaultRank( rPlayer );
+ }
+
+
+ @Override
+ public void listAllMines(tech.mcprison.prison.internal.CommandSender sender, Player player) {
+
+ RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(player);
+ List mines = new ArrayList<>();
+
+ if ( rPlayer != null ) {
+
+ Set keys = rPlayer.getLadderRanks().keySet();
+ for ( RankLadder key : keys ) {
+ PlayerRank pRank = rPlayer.getLadderRanks().get(key);
+
+ listMines( sender, player, pRank, mines );
+ }
+
+
+ if ( mines.size() > 0 ) {
+
+ // String builder will be used to track what the "real" text width is:
+ StringBuilder sb = new StringBuilder();
+
+ RowComponent row = new RowComponent();
+ row.addTextComponent( "&3Mines: " );
+ sb.append( "&3Mines: " );
+
+ for ( Mine mine : mines ) {
+
+ FancyMessage msgMine = new FancyMessage( String.format( "%s", mine.getTag() ) )
+ .suggest( "/mines tp " + mine.getName() )
+ .tooltip("Click to teleport to mine");
+
+ row.addFancy( msgMine );
+ sb.append( mine.getTag() );
+
+ row.addTextComponent( " " );
+ sb.append( " " );
+
+ String noColor = Text.stripColor( sb.toString() );
+
+ if ( noColor.length() > 50 ) {
+
+ // Send the player the mines list:
+ row.send( sender );
+
+ // Reset the row and sb to start on the next row of mines:
+ row = new RowComponent();
+ sb.setLength( 0 );
+
+ // Setup the start of the row:
+ row.addTextComponent( "&3Mines: " );
+ sb.append( "&3Mines: " );
+
+ }
+ }
+ if ( sb.length() > 0 ) {
+ // Send the player the mines list:
+ row.send( sender );
+ }
+ }
+
+ }
+ }
+
+ private void listMines(tech.mcprison.prison.internal.CommandSender sender,
+ Player player, PlayerRank pRank, List mines ) {
+
+ Rank rank = pRank.getRank();
+
+ while ( rank != null ) {
+
+ for ( ModuleElement mElement : rank.getMines() ) {
+ Mine mine = PrisonMines.getInstance().getMine( mElement.getName() );
+
+ if ( mine.hasMiningAccess( player ) ) {
+ mines.add( mine );
+ }
+ }
+
+ rank = rank.getRankPrior();
+ }
+ }
+
+
}
diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java
index 5bdd5e890..0500e4926 100644
--- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java
+++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java
@@ -19,18 +19,11 @@
package tech.mcprison.prison.spigot;
import java.io.File;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.Callable;
-
-import org.bstats.bukkit.Metrics;
-import org.bstats.charts.MultiLineChart;
-import org.bstats.charts.SimpleBarChart;
-import org.bstats.charts.SimplePie;
+
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.SimpleCommandMap;
@@ -45,7 +38,9 @@
import tech.mcprison.prison.Prison;
import tech.mcprison.prison.PrisonAPI;
import tech.mcprison.prison.PrisonCommand;
+import tech.mcprison.prison.PrisonCommand.RegisteredPluginsData;
import tech.mcprison.prison.alerts.Alerts;
+import tech.mcprison.prison.backups.PrisonBackups;
import tech.mcprison.prison.integration.Integration;
import tech.mcprison.prison.integration.IntegrationType;
import tech.mcprison.prison.internal.block.PrisonBlockTypes;
@@ -69,6 +64,7 @@
import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents;
import tech.mcprison.prison.spigot.backpacks.BackpacksListeners;
import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener;
+import tech.mcprison.prison.spigot.bstats.PrisonBStats;
import tech.mcprison.prison.spigot.commands.PrisonSpigotBackpackCommands;
import tech.mcprison.prison.spigot.commands.PrisonSpigotGUICommands;
import tech.mcprison.prison.spigot.commands.PrisonSpigotMinesCommands;
@@ -141,7 +137,13 @@ public class SpigotPrison
private File moduleDataFolder;
private List registeredBlockListeners;
+
+
+ private PrisonBStats prisonBStats;
+// private Metrics bStatsMetrics = null;
+// private PrisonMetrics bStatsMetrics = null;
+
public static SpigotPrison getInstance(){
return config;
}
@@ -158,6 +160,11 @@ public SpigotPrison() {
@Override
public void onLoad() {
+ // Startup bStats: Not needed with the new PrisonMetrics class.
+ this.prisonBStats = new PrisonBStats( this );
+ prisonBStats.initMetricsOnLoad();
+
+
/**
* Old versions of prison MUST be upgraded with v3.0.x or even v3.1.1.
* Upgrading from old versions of prison to v3.2.x is not supported.
@@ -213,7 +220,16 @@ public void onEnable() {
// Show Prison's splash screen and setup the core components:
Prison.get()
- .init(platform, Bukkit.getVersion());
+ .init( platform, Bukkit.getVersion(), getDataFolder() );
+
+
+
+ // If prison version is new, then make a copy of all config files that may change on startup:
+ PrisonBackups backups = new PrisonBackups();
+ backups.initialStartupVersionCheck();
+
+
+
// Enable the spigot locale manager:
getLocaleManager();
@@ -235,8 +251,26 @@ public void onEnable() {
boolean delayedPrisonStartup = getConfig().getBoolean("delayedPrisonStartup.enabled", false);
+
if ( !delayedPrisonStartup ) {
- onEnableStartup();
+
+ // Check to see if CMI is an active plugin. If it is, then let's enable the delayed startup.
+ // It should be noted that just because CMI is detected, it does not mean that the CMI Economy
+ // is being used. Use a flexible startup which means it will start if any vault economy
+ // is found.
+ RegisteredPluginsData cmiPlugin = platform.identifyRegisteredPlugin( "CMI" );
+ if ( cmiPlugin != null ) {
+ String cmiMessage = String.format(
+ "CMI was detected and Prison's delayed startup has been enabled: %s - %s ",
+ cmiPlugin.getPluginName(), cmiPlugin.getPluginVersion() );
+ Output.get().logInfo( cmiMessage );
+
+ onEnableDelayedStartFlexible();
+ }
+ else {
+
+ onEnableStartup();
+ }
}
else {
onEnableDelayedStart();
@@ -245,6 +279,13 @@ public void onEnable() {
}
+ protected void onEnableDelayedStartFlexible() {
+
+ SpigotPrisonDelayedStartupTask delayedStartupTask = new SpigotPrisonDelayedStartupTask( this );
+ delayedStartupTask.setUseAnyVaultEconomy( true );
+ delayedStartupTask.submit();
+ }
+
protected void onEnableDelayedStart() {
SpigotPrisonDelayedStartupTask delayedStartupTask = new SpigotPrisonDelayedStartupTask( this );
@@ -284,20 +325,14 @@ public void onEnableStartup() {
Bukkit.getPluginManager().registerEvents(new BackpacksListeners(), this);
}
- try {
- isSellAllEnabled = getConfig().getBoolean("sellall");
- } catch (NullPointerException ignored){}
-
- if (isSellAllEnabled){
- SellAllUtil.get();
- }
-
initIntegrations();
-
+ // Sellall set to disabled since it will be set to the correct value in enableModulesAndCommands():
+ isSellAllEnabled = false;
// This is the loader for modules and commands:
enableModulesAndCommands();
+
// // NOTE: Put all commands within the initModulesAndCommands() function.
// initModulesAndCommands();
@@ -314,14 +349,12 @@ public void onEnableStartup() {
getBlockBreakEventListeners().registerAllBlockBreakEvents( this );
- initMetrics();
-
-
// These stats are displayed within the initDeferredModules():
//Prison.get().getPlatform().getPlaceholders().printPlaceholderStats();
- PrisonCommand cmdVersion = Prison.get().getPrisonCommands();
+ @SuppressWarnings("unused")
+ PrisonCommand cmdVersion = Prison.get().getPrisonCommands();
// if (doAlertAboutConvert) {
// Alerts.getInstance().sendAlert(
@@ -358,6 +391,18 @@ public void onEnableStartup() {
if ( getConfig().getBoolean("prison-block-compatibility-report") ) {
SpigotUtil.testAllPrisonBlockTypes();
}
+
+
+ // Startup bStats:
+ prisonBStats.initMetricsOnEnable();
+
+
+
+ // Force a backup if prison version is new:
+ PrisonBackups backups = new PrisonBackups();
+ backups.serverStartupVersionCheck();
+
+
Output.get().logInfo( "Prison - Finished loading." );
@@ -510,79 +555,302 @@ public static String stripColor(String format){
// return format == null ? null : ChatColor.stripColor(format);
}
- /**
- * bStats reporting
- *
- * https://github.com/Bastian/bStats-Metrics/tree/master/base/src/main/java/org/bstats/charts
- *
- */
- private void initMetrics() {
- if (!getConfig().getBoolean("send-metrics", true)) {
- return; // Don't check if they don't want it
- }
-
- int pluginId = 657;
- Metrics metrics = new Metrics( this, pluginId );
-
- // Report the modules being used
- SimpleBarChart sbcModulesUsed = new SimpleBarChart("modules_used", () -> {
- Map valueMap = new HashMap<>();
- for (Module m : PrisonAPI.getModuleManager().getModules()) {
- valueMap.put(m.getName(), 1);
- }
- return valueMap;
- });
- metrics.addCustomChart( sbcModulesUsed );
-
- // Report the API level
- SimplePie spApiLevel =
- new SimplePie("api_level", () ->
- "API Level " + Prison.API_LEVEL + "." + Prison.API_LEVEL_MINOR );
- metrics.addCustomChart( spApiLevel );
-
-
- Optional prisonMinesOpt = Prison.get().getModuleManager().getModule( PrisonMines.MODULE_NAME );
- Optional prisonRanksOpt = Prison.get().getModuleManager().getModule( PrisonRanks.MODULE_NAME );
-
- int mineCount = prisonMinesOpt.map(module -> ((PrisonMines) module).getMineManager().getMines().size()).orElse(0);
- int rankCount = prisonRanksOpt.map(module -> ((PrisonRanks) module).getRankCount()).orElse(0);
-
- int defaultRankCount = prisonRanksOpt.map(module -> ((PrisonRanks) module).getDefaultLadderRankCount()).orElse(0);
- int prestigesRankCount = prisonRanksOpt.map(module -> ((PrisonRanks) module).getPrestigesLadderRankCount()).orElse(0);
- int otherRankCount = rankCount - defaultRankCount - prestigesRankCount;
-
- int ladderCount = prisonRanksOpt.map(module -> ((PrisonRanks) module).getladderCount()).orElse(0);
- int playerCount = prisonRanksOpt.map(module -> ((PrisonRanks) module).getPlayersCount()).orElse(0);
-
- MultiLineChart mlcMinesRanksAndLadders =
- new MultiLineChart("mines_ranks_and_ladders", new Callable