mcMMO - Now with 100% more scoreboards!

mcMMO now allows for the use of scoreboards to display information in
several instances. By default, all scoreboards are enabled in the config,
and will only display for 10 seconds. After 10 seconds, the scoreboard
will go away and revert to the previously displayed scoreboard, if one
exists.

A global scoreboard now exists for tracking all player stats, and will be
displayed when /mctop is used. Your name will be highlighted in gold when
looking through the scoreboard. Additionally, the scoreboard will display
players in groups of 15, rather than groups of 10 like in chat.
Unfortunately, due to the limitations of scoreboards, the player's rank
will not be displayed in front of their name.

The scoreboard area is now also used for displaying data for /mcrank,
/inspect. and /mcstats. Due to the way scoreboards are handled, the power
level is not guarenteed to show up at any given location in the
scoreboard, but is instead displayed in gold so that it can be easily
found.

Lastly, the scoreboard area is also now used for displaying current data
on skills when the relevant /<skillname> command is used. The effects and
ability stats will still be shown in chat, but the current level, xp, and
remaining xp will be shown in the scoreboard.
This commit is contained in:
GJ 2013-04-13 23:16:25 -04:00
parent 339a54b0ac
commit 50c9649b23
15 changed files with 497 additions and 69 deletions

View File

@ -8,6 +8,8 @@ Key:
- Removal - Removal
Version 1.4.06-dev Version 1.4.06-dev
+ Added global scoreboards to track skill rankings (display using /mctop)
+ Added per-player scoreboard displays for the /inspect, /mcrank, /mcstats, and /<skillname> commands
+ Added tab-complete support for all commands + Added tab-complete support for all commands
+ Added ability to configure drops from Shake in treasures.yml + Added ability to configure drops from Shake in treasures.yml
+ Added "Master Angler" ability to Fishing. + Added "Master Angler" ability to Fishing.

View File

@ -10,6 +10,7 @@ import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile; import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.SkillType;
@ -17,6 +18,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -25,6 +27,10 @@ public class InspectCommand implements TabExecutor {
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
switch (args.length) { switch (args.length) {
case 1: case 1:
if (sender instanceof Player && Config.getInstance().getInspectScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(sender.getName());
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]); McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
// If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process. // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
@ -35,6 +41,11 @@ public class InspectCommand implements TabExecutor {
return true; return true;
} }
if (sender instanceof Player && Config.getInstance().getInspectScoreboardEnabled()) {
ScoreboardManager.enablePlayerInspectScoreboardOffline((Player) sender, profile);
return true;
}
sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", args[0])); sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", args[0]));
sender.sendMessage(LocaleLoader.getString("Stats.Header.Gathering")); sender.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
@ -62,6 +73,11 @@ public class InspectCommand implements TabExecutor {
return true; return true;
} }
if (sender instanceof Player && Config.getInstance().getInspectScoreboardEnabled()) {
ScoreboardManager.enablePlayerInspectScoreboardOnline((Player) sender, mcMMOPlayer);
return true;
}
sender.sendMessage(LocaleLoader.getString("Inspect.Stats", target.getName())); sender.sendMessage(LocaleLoader.getString("Inspect.Stats", target.getName()));
CommandUtils.printGatheringSkills(target, sender); CommandUtils.printGatheringSkills(target, sender);
CommandUtils.printCombatSkills(target, sender); CommandUtils.printCombatSkills(target, sender);

View File

@ -7,15 +7,18 @@ import java.util.Set;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile; import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.runnables.commands.McrankCommandAsyncTask; import com.gmail.nossr50.runnables.commands.McrankCommandAsyncTask;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
public class McrankCommand implements TabExecutor { public class McrankCommand implements TabExecutor {
@ -32,7 +35,14 @@ public class McrankCommand implements TabExecutor {
return true; return true;
} }
display(sender, sender.getName()); if (Config.getInstance().getMcrankScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(sender.getName());
ScoreboardManager.enablePlayerRankScoreboard((Player) sender);
}
else {
display(sender, sender.getName());
}
return true; return true;
case 1: case 1:
@ -55,7 +65,13 @@ public class McrankCommand implements TabExecutor {
return true; return true;
} }
display(sender, playerName); if (sender instanceof Player && Config.getInstance().getMcrankScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(sender.getName());
ScoreboardManager.enablePlayerRankScoreboardOthers((Player) sender, playerName);
}
else {
display(sender, playerName);
}
return true; return true;
default: default:

View File

@ -12,7 +12,7 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
public class McstatsCommand implements TabExecutor { public class McstatsCommand implements TabExecutor {
@ -27,20 +27,26 @@ public class McstatsCommand implements TabExecutor {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName()); McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
Player player = mcMMOPlayer.getPlayer(); Player player = mcMMOPlayer.getPlayer();
player.sendMessage(LocaleLoader.getString("Stats.Own.Stats")); if (Config.getInstance().getMcstatsScoreboardsEnabled()) {
player.sendMessage(LocaleLoader.getString("mcMMO.NoSkillNote")); ScoreboardManager.setupPlayerScoreboard(player.getName());
ScoreboardManager.enablePlayerStatsScoreboard(mcMMOPlayer);
CommandUtils.printGatheringSkills(player);
CommandUtils.printCombatSkills(player);
CommandUtils.printMiscSkills(player);
int powerLevelCap = Config.getInstance().getPowerLevelCap();
if (powerLevelCap != Integer.MAX_VALUE) {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));
} }
else { else {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", UserManager.getPlayer(player).getPowerLevel())); player.sendMessage(LocaleLoader.getString("Stats.Own.Stats"));
player.sendMessage(LocaleLoader.getString("mcMMO.NoSkillNote"));
CommandUtils.printGatheringSkills(player);
CommandUtils.printCombatSkills(player);
CommandUtils.printMiscSkills(player);
int powerLevelCap = Config.getInstance().getPowerLevelCap();
if (powerLevelCap != Integer.MAX_VALUE) {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));
}
else {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", UserManager.getPlayer(player).getPowerLevel()));
}
} }
return true; return true;

View File

@ -7,17 +7,20 @@ import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.FlatfileDatabaseManager; import com.gmail.nossr50.database.FlatfileDatabaseManager;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.runnables.commands.MctopCommandAsyncTask; import com.gmail.nossr50.runnables.commands.MctopCommandAsyncTask;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -77,11 +80,16 @@ public class MctopCommand implements TabExecutor {
return; return;
} }
if (Config.getInstance().getUseMySQL()) { if (sender instanceof Player && Config.getInstance().getMctopScoreboardEnabled()) {
sqlDisplay(page, skill, sender); ScoreboardManager.enableGlobalStatsScoreboard((Player) sender, skill, page);
} }
else { else {
flatfileDisplay(page, skill, sender); if (Config.getInstance().getUseMySQL()) {
sqlDisplay(page, skill, sender);
}
else {
flatfileDisplay(page, skill, sender);
}
} }
} }
@ -97,21 +105,11 @@ public class MctopCommand implements TabExecutor {
int position = (page * 10) - 9; int position = (page * 10) - 9;
for (String playerStat : FlatfileDatabaseManager.retrieveInfo(skill, page)) { for (PlayerStat stat : FlatfileDatabaseManager.retrieveInfo(skill, page, 10)) {
if (playerStat == null) { String digit = (position < 10) ? "0" : "" + String.valueOf(position);
continue;
}
String digit = String.valueOf(position);
if (position < 10) {
digit = "0" + digit;
}
String[] splitStat = playerStat.split(":");
// Format: 1. Playername - skill value // Format: 1. Playername - skill value
sender.sendMessage(digit + ". " + ChatColor.GREEN + splitStat[1] + " - " + ChatColor.WHITE + splitStat[0]); sender.sendMessage(digit + ". " + ChatColor.GREEN + stat.name + " - " + ChatColor.WHITE + stat.statVal);
position++; position++;
} }

View File

@ -11,6 +11,7 @@ import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile; import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.SkillType;
@ -20,6 +21,7 @@ import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.PerksUtils; import com.gmail.nossr50.util.skills.PerksUtils;
import com.gmail.nossr50.util.skills.SkillUtils; import com.gmail.nossr50.util.skills.SkillUtils;
@ -71,7 +73,14 @@ public abstract class SkillCommand implements TabExecutor {
if (!skill.isChildSkill()) { if (!skill.isChildSkill()) {
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName)); player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString())))); player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, profile.getSkillXpLevel(skill), profile.getXpToLevel(skill)));
if (Config.getInstance().getSkillScoreboardEnabled()) {
ScoreboardManager.setupPlayerScoreboard(player.getName());
ScoreboardManager.enablePlayerSkillScoreboard(mcMMOPlayer, skill);
}
else {
player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, profile.getSkillXpLevel(skill), profile.getXpToLevel(skill)));
}
} }
else { else {
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName + " " + LocaleLoader.getString("Skills.Child"))); player.sendMessage(LocaleLoader.getString("Skills.Header", skillName + " " + LocaleLoader.getString("Skills.Child")));

View File

@ -61,6 +61,22 @@ public class Config extends AutoUpdateConfigLoader {
public int getMobHealthbarTime() { return config.getInt("Mob_Healthbar.Display_Time", 3); } public int getMobHealthbarTime() { return config.getInt("Mob_Healthbar.Display_Time", 3); }
/* Scoreboards */
public boolean getMcrankScoreboardEnabled() { return config.getBoolean("Scoreboards.Mcrank.Use", true); }
public int getMcrankScoreboardTime() { return config.getInt("Scoreboards.Mcrank.Display_Time", 10); }
public boolean getMcstatsScoreboardsEnabled() { return config.getBoolean("Scoreboards.Mcstats.Use", true); }
public int getMcstatsScoreboardTime() { return config.getInt("Scoreboards.Mctop.Display_Time", 10); }
public boolean getMctopScoreboardEnabled() { return config.getBoolean("Scoreboards.Mctop.Use", true); }
public int getMctopScoreboardTime() { return config.getInt("Scoreboards.Mctop.Display_Time", 10); }
public boolean getInspectScoreboardEnabled() { return config.getBoolean("Scoreboards.Inspect.Use", true); }
public int getInspectScoreboardTime() { return config.getInt("Scoreboards.Inspect.Display_Time", 10); }
public boolean getSkillScoreboardEnabled() { return config.getBoolean("Scoreboards.Skillname.Use", true); }
public int getSkillScoreboardTime() { return config.getInt("Scoreboards.Skillname.Display_Time", 10); }
/* Database Purging */ /* Database Purging */
public int getPurgeInterval() { return config.getInt("Database_Purging.Purge_Interval", -1); } public int getPurgeInterval() { return config.getInt("Database_Purging.Purge_Interval", -1); }
public int getOldUsersCutoff() { return config.getInt("Database_Purging.Old_User_Cutoff", 6); } public int getOldUsersCutoff() { return config.getInt("Database_Purging.Old_User_Cutoff", 6); }

View File

@ -131,30 +131,11 @@ public final class FlatfileDatabaseManager {
* @param pageNumber Which page in the leaderboards to retrieve * @param pageNumber Which page in the leaderboards to retrieve
* @return the requested leaderboard information * @return the requested leaderboard information
*/ */
public static String[] retrieveInfo(String skillType, int pageNumber) { public static List<PlayerStat> retrieveInfo(String skillType, int pageNumber, int statsPerPage) {
String[] info = new String[10]; List<PlayerStat> statsList = skillType.equalsIgnoreCase("all") ? powerLevels : playerStatHash.get(SkillType.getSkill(skillType));
List<PlayerStat> statsList; int fromIndex = (Math.max(pageNumber, 1) - 1) * statsPerPage;
if (skillType.equalsIgnoreCase("all")) { return statsList.subList(Math.min(fromIndex, statsList.size()), Math.min(fromIndex + statsPerPage, statsList.size()));
statsList = powerLevels;
}
else {
statsList = playerStatHash.get(SkillType.getSkill(skillType));
}
if (pageNumber < 1) {
pageNumber = 1;
}
int destination = (pageNumber - 1) * 10;
for (int i = 0; i < 10; i++) {
if (destination + i < statsList.size()) {
PlayerStat ps = statsList.get(destination + i);
info[i] = ps.name + ":" + ps.statVal;
}
}
return info;
} }
public static boolean removeFlatFileUser(String playerName) { public static boolean removeFlatFileUser(String playerName) {
@ -326,6 +307,10 @@ public final class FlatfileDatabaseManager {
return skills; return skills;
} }
public static List<PlayerStat> getPlayerStats(String skillName) {
return (skillName.equalsIgnoreCase("all")) ? powerLevels : playerStatHash.get(SkillType.getSkill(skillName));
}
private static int loadStat(List<PlayerStat> statList, String playerName, String[] data, int dataIndex) { private static int loadStat(List<PlayerStat> statList, String playerName, String[] data, int dataIndex) {
if (data.length > dataIndex) { if (data.length > dataIndex) {
int statValue = Integer.parseInt(data[dataIndex]); int statValue = Integer.parseInt(data[dataIndex]);

View File

@ -9,6 +9,8 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.bukkit.scoreboard.Scoreboard;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.spout.SpoutConfig; import com.gmail.nossr50.config.spout.SpoutConfig;
@ -30,6 +32,7 @@ public class PlayerProfile {
private HudType hudType; private HudType hudType;
private MobHealthbarType mobHealthbarType; private MobHealthbarType mobHealthbarType;
private McMMOHud spoutHud; private McMMOHud spoutHud;
private Scoreboard playerStatsScoreboard;
/* Skill Data */ /* Skill Data */
private final Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>(); // Skill & Level private final Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>(); // Skill & Level
@ -70,6 +73,10 @@ public class PlayerProfile {
} }
} }
public String getPlayerName() {
return playerName;
}
public boolean isLoaded() { public boolean isLoaded() {
return loaded; return loaded;
} }
@ -106,6 +113,18 @@ public class PlayerProfile {
this.mobHealthbarType = mobHealthbarType; this.mobHealthbarType = mobHealthbarType;
} }
/*
* Scoreboards
*/
public Scoreboard getPlayerStatsScoreboard() {
return playerStatsScoreboard;
}
public void setPlayerStatsScoreboard(Scoreboard statsScoreboard) {
this.playerStatsScoreboard = statsScoreboard;
}
/* /*
* Cooldowns * Cooldowns
*/ */

View File

@ -32,7 +32,7 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName)); sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
for (SkillType skill : SkillType.values()) { for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || !Permissions.skillEnabled(player, skill)) { if (skill.isChildSkill() || (player != null && !Permissions.skillEnabled(player, skill))) {
continue; continue;
} }

View File

@ -1,7 +1,7 @@
package com.gmail.nossr50.runnables.commands; package com.gmail.nossr50.runnables.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.Collection;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@ -11,7 +11,6 @@ import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.SQLDatabaseManager; import com.gmail.nossr50.database.SQLDatabaseManager;
public class MctopCommandAsyncTask extends BukkitRunnable { public class MctopCommandAsyncTask extends BukkitRunnable {
private CommandSender sender; private CommandSender sender;
private String query; private String query;
private int page; private int page;
@ -25,8 +24,8 @@ public class MctopCommandAsyncTask extends BukkitRunnable {
@Override @Override
public void run() { public void run() {
String tablePrefix = Config.getInstance().getMySQLTablePrefix(); String tablePrefix = Config.getInstance().getMySQLTablePrefix();
final HashMap<Integer, ArrayList<String>> userslist = SQLDatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((page * 10) - 10) + ",10"); final Collection<ArrayList<String>> userStats = SQLDatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((page * 10) - 10) + ",10").values();
new MctopCommandDisplayTask(userslist, page, tablePrefix, sender).runTaskLater(mcMMO.p, 1); new MctopCommandDisplayTask(userStats, page, tablePrefix, sender).runTaskLater(mcMMO.p, 1);
} }
} }

View File

@ -1,7 +1,7 @@
package com.gmail.nossr50.runnables.commands; package com.gmail.nossr50.runnables.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.Collection;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -11,13 +11,13 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.StringUtils;
public class MctopCommandDisplayTask extends BukkitRunnable { public class MctopCommandDisplayTask extends BukkitRunnable {
private HashMap<Integer, ArrayList<String>> userslist; private Collection<ArrayList<String>> userStats;
private CommandSender sender; private CommandSender sender;
private String query; private String query;
private int page; private int page;
public MctopCommandDisplayTask(HashMap<Integer, ArrayList<String>> userslist, int page, String query, CommandSender sender) { public MctopCommandDisplayTask(Collection<ArrayList<String>> userStats, int page, String query, CommandSender sender) {
this.userslist = userslist; this.userStats = userStats;
this.page = page; this.page = page;
this.query = query; this.query = query;
this.sender = sender; this.sender = sender;
@ -33,13 +33,12 @@ public class MctopCommandDisplayTask extends BukkitRunnable {
} }
int place = (page * 10) - 9; int place = (page * 10) - 9;
for (int i = 1; i <= 10; i++) {
if (userslist.get(i) == null) { for (ArrayList<String> stat : userStats) {
break; String digit = (place < 10) ? "0" : "" + String.valueOf(place);
}
// Format: 1. Playername - skill value // Format: 1. Playername - skill value
sender.sendMessage(place + ". " + ChatColor.GREEN + userslist.get(i).get(1) + " - " + ChatColor.WHITE + userslist.get(i).get(0)); sender.sendMessage(digit + ". " + ChatColor.GREEN + stat.get(1) + " - " + ChatColor.WHITE + stat.get(0));
place++; place++;
} }

View File

@ -0,0 +1,23 @@
package com.gmail.nossr50.runnables.scoreboards;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Scoreboard;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
public class ScoreboardChangeTask extends BukkitRunnable {
private Player player;
private Scoreboard oldScoreboard;
public ScoreboardChangeTask(Player player, Scoreboard oldScoreboard) {
this.player = player;
this.oldScoreboard = oldScoreboard;
}
@Override
public void run() {
player.setScoreboard(oldScoreboard);
ScoreboardManager.clearPendingTask(player.getName());
}
}

View File

@ -0,0 +1,312 @@
package com.gmail.nossr50.util.scoreboards;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.database.FlatfileDatabaseManager;
import com.gmail.nossr50.database.SQLDatabaseManager;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.SkillType;
import com.gmail.nossr50.runnables.scoreboards.ScoreboardChangeTask;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillUtils;
public class ScoreboardManager {
private static final Map<String, Scoreboard> PLAYER_SCOREBOARDS = new HashMap<String, Scoreboard>();
private static final Scoreboard GLOBAL_STATS_SCOREBOARD = mcMMO.p.getServer().getScoreboardManager().getNewScoreboard();
private final static String PLAYER_STATS_HEADER = "mcMMO Stats";
private final static String PLAYER_RANK_HEADER = "mcMMO Rankings";
private final static String PLAYER_INSPECT_HEADER = "mcMMO Stats: ";
private final static List<String> SCOREBOARD_TASKS = new ArrayList<String>();
public static void setupPlayerScoreboard(String playerName) {
if (PLAYER_SCOREBOARDS.containsKey(playerName)) {
return;
}
PLAYER_SCOREBOARDS.put(playerName, mcMMO.p.getServer().getScoreboardManager().getNewScoreboard());
}
public static void enablePlayerSkillScoreboard(McMMOPlayer mcMMOPlayer, SkillType skill) {
Player player = mcMMOPlayer.getPlayer();
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(SkillUtils.getSkillName(skill));
if (objective == null) {
objective = newScoreboard.registerNewObjective(SkillUtils.getSkillName(skill), "dummy");
}
updatePlayerSkillScores(mcMMOPlayer.getProfile(), skill, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getSkillScoreboardTime());
}
public static void enablePlayerStatsScoreboard(McMMOPlayer mcMMOPlayer) {
Player player = mcMMOPlayer.getPlayer();
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_STATS_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_STATS_HEADER, "dummy");
}
updatePlayerStatsScores(mcMMOPlayer, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getMcstatsScoreboardTime());
}
public static void enablePlayerRankScoreboard(Player player) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_RANK_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_RANK_HEADER, "dummy");
}
updatePlayerRankScores(player, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getMcrankScoreboardTime());
}
public static void enablePlayerRankScoreboardOthers(Player player, String targetName) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_RANK_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_RANK_HEADER, "dummy");
}
updatePlayerRankOthersScores(targetName, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getMcrankScoreboardTime());
}
public static void enablePlayerInspectScoreboardOnline(Player player, McMMOPlayer mcMMOTarget) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_INSPECT_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_INSPECT_HEADER, "dummy");
}
updatePlayerInspectOnlineScores(mcMMOTarget, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getInspectScoreboardTime());
}
public static void enablePlayerInspectScoreboardOffline(Player player, PlayerProfile targetProfile) {
Scoreboard oldScoreboard = player.getScoreboard();
Scoreboard newScoreboard = PLAYER_SCOREBOARDS.get(player.getName());
Objective objective = newScoreboard.getObjective(PLAYER_INSPECT_HEADER);
if (objective == null) {
objective = newScoreboard.registerNewObjective(PLAYER_INSPECT_HEADER, "dummy");
}
updatePlayerInspectOfflineScores(targetProfile, objective);
changeScoreboard(player, oldScoreboard, newScoreboard, Config.getInstance().getInspectScoreboardTime());
}
public static void enableGlobalStatsScoreboard(Player player, String skillName, int pageNumber) {
Objective oldObjective = GLOBAL_STATS_SCOREBOARD.getObjective(skillName);
Scoreboard oldScoreboard = player.getScoreboard();
if (oldObjective != null) {
oldObjective.unregister();
}
Objective newObjective = GLOBAL_STATS_SCOREBOARD.registerNewObjective(skillName, "dummy");
newObjective.setDisplayName(ChatColor.GOLD + (skillName.equalsIgnoreCase("all") ? "Power Level" : SkillUtils.getSkillName(SkillType.getSkill(skillName))));
updateGlobalStatsScores(player, newObjective, skillName, pageNumber);
changeScoreboard(player, oldScoreboard, GLOBAL_STATS_SCOREBOARD, Config.getInstance().getMctopScoreboardTime());
}
private static void updatePlayerSkillScores(PlayerProfile profile, SkillType skill, Objective objective) {
Server server = mcMMO.p.getServer();
objective.getScore(server.getOfflinePlayer("Level")).setScore(profile.getSkillLevel(skill));
objective.getScore(server.getOfflinePlayer("Current XP")).setScore(profile.getSkillXpLevel(skill));
objective.getScore(server.getOfflinePlayer("Remaining XP")).setScore(profile.getXpToLevel(skill));
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerStatsScores(McMMOPlayer mcMMOPlayer, Objective objective) {
Player player = mcMMOPlayer.getPlayer();
PlayerProfile profile = mcMMOPlayer.getProfile();
Server server = mcMMO.p.getServer();
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || !Permissions.skillEnabled(player, skill)) {
continue;
}
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(profile.getSkillLevel(skill));
}
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Power Level")).setScore(mcMMOPlayer.getPowerLevel());
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerRankScores(Player player, Objective objective) {
String playerName = player.getName();
Server server = mcMMO.p.getServer();
Integer rank;
Map<String, Integer> skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(playerName) : FlatfileDatabaseManager.getPlayerRanks(playerName);
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || !Permissions.skillEnabled(player, skill)) {
continue;
}
rank = skills.get(skill.name());
if (rank != null) {
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(rank);
}
}
rank = skills.get("ALL");
if (rank != null) {
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Overall")).setScore(rank);
}
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerRankOthersScores(String targetName, Objective objective) {
Server server = mcMMO.p.getServer();
Integer rank;
Map<String, Integer> skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(targetName) : FlatfileDatabaseManager.getPlayerRanks(targetName);
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill()) {
continue;
}
rank = skills.get(skill.name());
if (rank != null) {
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(rank);
}
}
rank = skills.get("ALL");
if (rank != null) {
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Overall")).setScore(rank);
}
objective.setDisplayName(PLAYER_RANK_HEADER + ": " + targetName);
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerInspectOnlineScores(McMMOPlayer mcMMOTarget, Objective objective) {
Player target = mcMMOTarget.getPlayer();
PlayerProfile profile = mcMMOTarget.getProfile();
Server server = mcMMO.p.getServer();
int powerLevel = 0;
int skillLevel;
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill() || !Permissions.skillEnabled(target, skill)) {
continue;
}
skillLevel = profile.getSkillLevel(skill);
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(skillLevel);
powerLevel += skillLevel;
}
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Power Level")).setScore(powerLevel);
objective.setDisplayName(PLAYER_INSPECT_HEADER + target.getName());
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void updatePlayerInspectOfflineScores(PlayerProfile targetProfile, Objective objective) {
Server server = mcMMO.p.getServer();
int powerLevel = 0;
int skillLevel;
for (SkillType skill : SkillType.values()) {
if (skill.isChildSkill()) {
continue;
}
skillLevel = targetProfile.getSkillLevel(skill);
objective.getScore(server.getOfflinePlayer(SkillUtils.getSkillName(skill))).setScore(skillLevel);
powerLevel += skillLevel;
}
objective.getScore(server.getOfflinePlayer(ChatColor.GOLD + "Power Level")).setScore(powerLevel);
objective.setDisplayName(PLAYER_INSPECT_HEADER + targetProfile.getPlayerName());
}
private static void updateGlobalStatsScores(Player player, Objective objective, String skillName, int pageNumber) {
int position = (pageNumber * 15) - 14;
String startPosition = ((position < 10) ? "0" : "") + String.valueOf(position);
String endPosition = String.valueOf(position + 14);
Server server = mcMMO.p.getServer();
if (Config.getInstance().getUseMySQL()) {
String tablePrefix = Config.getInstance().getMySQLTablePrefix();
String query = (skillName.equalsIgnoreCase("all") ? "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing" : skillName);
final Collection<ArrayList<String>> userStats = SQLDatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((pageNumber * 15) - 15) + ",15").values();
for (ArrayList<String> stat : userStats) {
String playerName = stat.get(1);
playerName = (playerName.equals(player.getName()) ? ChatColor.GOLD : "") + playerName;
objective.getScore(server.getOfflinePlayer(playerName)).setScore(Integer.valueOf(stat.get(0)));
}
}
else {
for (PlayerStat stat : FlatfileDatabaseManager.retrieveInfo(skillName, pageNumber, 15)) {
String playerName = stat.name;
playerName = (playerName.equals(player.getName()) ? ChatColor.GOLD : "") + playerName;
objective.getScore(server.getOfflinePlayer(playerName)).setScore(stat.statVal);
}
}
objective.setDisplayName(objective.getDisplayName() + " (" + startPosition + " - " + endPosition + ")");
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
}
private static void changeScoreboard(Player player, Scoreboard oldScoreboard, Scoreboard newScoreboard, int displayTime) {
if (oldScoreboard != newScoreboard) {
String playerName = player.getName();
player.setScoreboard(newScoreboard);
if (displayTime != -1 && !SCOREBOARD_TASKS.contains(playerName)) {
new ScoreboardChangeTask(player, oldScoreboard).runTaskLater(mcMMO.p, displayTime * 20);
SCOREBOARD_TASKS.add(playerName);
}
}
}
public static void clearPendingTask(String playerName) {
SCOREBOARD_TASKS.remove(playerName);
}
}

View File

@ -27,6 +27,34 @@ General:
# Should mcMMO over-write configs to update, or make new ones ending in .new? # Should mcMMO over-write configs to update, or make new ones ending in .new?
Config_Update_Overwrite: true Config_Update_Overwrite: true
Scoreboards:
Inspect:
# Should mcMMO use scoreboards for /inspect?
Use: true
# Amount of time (in seconds) to display. To display permanently, set to -1
Display_Time: 10
Mcrank:
# Should mcMMO use scoreboards for /mcrank?
Use: true
# Amount of time (in seconds) to display. To display permanently, set to -1
Display_Time: 10
Mcstats:
# Should mcMMO use scoreboards for /mcstats?
Use: true
# Amount of time (in seconds) to display. To display permanently, set to -1
Display_Time: 10
Mctop:
# Should mcMMO use scoreboards for /mctop?
Use: true
# Amount of time (in seconds) to display. To display permanently, set to -1
Display_Time: 10
Skillname:
# Should mcMMO use scoreboards for /skillname (/mining, /fishing, etc.)?
Use: true
# Amount of time (in seconds) to display. To display permanently, set to -1
Display_Time: 10
Mob_Healthbar: Mob_Healthbar:
# Default display for mob health bars - HEARTS, BAR, or DISABLED # Default display for mob health bars - HEARTS, BAR, or DISABLED
Display_Type: HEARTS Display_Type: HEARTS