diff --git a/API/api/src/main/java/tc/oc/api/docs/virtual/UserDoc.java b/API/api/src/main/java/tc/oc/api/docs/virtual/UserDoc.java index c3c24ab..d1bbb35 100644 --- a/API/api/src/main/java/tc/oc/api/docs/virtual/UserDoc.java +++ b/API/api/src/main/java/tc/oc/api/docs/virtual/UserDoc.java @@ -85,6 +85,7 @@ public interface UserDoc { int mutationtokens(); String mc_last_sign_in_ip(); @Nullable Date trial_expires_at(); + Map>> stats_value(); Map> mc_permissions_by_realm(); Map> mc_settings_by_profile(); Map classes(); diff --git a/API/minecraft/src/main/java/tc/oc/api/minecraft/users/LocalUserDocument.java b/API/minecraft/src/main/java/tc/oc/api/minecraft/users/LocalUserDocument.java index 47666d0..caffe51 100644 --- a/API/minecraft/src/main/java/tc/oc/api/minecraft/users/LocalUserDocument.java +++ b/API/minecraft/src/main/java/tc/oc/api/minecraft/users/LocalUserDocument.java @@ -100,6 +100,11 @@ public class LocalUserDocument extends SimplePlayerId implements User { return null; } + @Override + public Map>> stats_value() { + return Collections.emptyMap(); + } + @Override public Map> mc_permissions_by_realm() { return ImmutableMap.of( diff --git a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/CommonsBukkitManifest.java b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/CommonsBukkitManifest.java index 20ab3ec..8a27049 100644 --- a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/CommonsBukkitManifest.java +++ b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/CommonsBukkitManifest.java @@ -24,13 +24,7 @@ import tc.oc.commons.bukkit.chat.TextComponentRenderer; import tc.oc.commons.bukkit.chat.TranslatableComponentRenderer; import tc.oc.commons.bukkit.chat.UserTextComponent; import tc.oc.commons.bukkit.chat.UserTextComponentRenderer; -import tc.oc.commons.bukkit.commands.PermissionCommands; -import tc.oc.commons.bukkit.commands.ServerCommands; -import tc.oc.commons.bukkit.commands.ServerVisibilityCommands; -import tc.oc.commons.bukkit.commands.SkinCommands; -import tc.oc.commons.bukkit.commands.TraceCommands; -import tc.oc.commons.bukkit.commands.UserCommands; -import tc.oc.commons.bukkit.commands.UserFinder; +import tc.oc.commons.bukkit.commands.*; import tc.oc.commons.bukkit.debug.LeakListener; import tc.oc.commons.bukkit.event.targeted.TargetedEventManifest; import tc.oc.commons.bukkit.format.ServerFormatter; @@ -68,6 +62,8 @@ import tc.oc.commons.bukkit.respack.ResourcePackManager; import tc.oc.commons.bukkit.restart.RestartCommands; import tc.oc.commons.bukkit.sessions.SessionListener; import tc.oc.commons.bukkit.settings.SettingManifest; +import tc.oc.commons.bukkit.stats.StatsCommands; +import tc.oc.commons.bukkit.stats.StatsManifest; import tc.oc.commons.bukkit.suspend.SuspendListener; import tc.oc.commons.bukkit.tablist.PlayerTabEntry; import tc.oc.commons.bukkit.tablist.TabRender; @@ -112,6 +108,7 @@ public final class CommonsBukkitManifest extends HybridManifest { install(new NavigatorManifest()); install(new RaindropManifest()); install(new TokenManifest()); + install(new StatsManifest()); install(new PunishmentManifest()); // These are already bound as facets, so they only need to be exposed diff --git a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsCommands.java b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsCommands.java new file mode 100644 index 0000000..cefb7aa --- /dev/null +++ b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsCommands.java @@ -0,0 +1,72 @@ +package tc.oc.commons.bukkit.stats; + +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.minecraft.util.commands.CommandPermissions; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.command.CommandSender; +import tc.oc.commons.bukkit.chat.Audiences; +import tc.oc.commons.bukkit.chat.HeaderComponent; +import tc.oc.commons.bukkit.chat.PlayerComponent; +import tc.oc.commons.bukkit.commands.UserFinder; +import tc.oc.commons.bukkit.nick.IdentityProvider; +import tc.oc.commons.core.chat.Audience; +import tc.oc.commons.core.chat.Component; +import tc.oc.commons.core.commands.CommandFutureCallback; +import tc.oc.commons.core.commands.Commands; +import tc.oc.minecraft.scheduler.SyncExecutor; + +import javax.inject.Inject; +import java.util.HashMap; + +public class StatsCommands implements Commands { + + private final SyncExecutor syncExecutor; + private final UserFinder userFinder; + private final Audiences audiences; + private final IdentityProvider identityProvider; + + @Inject + StatsCommands(UserFinder userFinder, SyncExecutor executor, Audiences audiences, IdentityProvider identityProvider) { + this.userFinder = userFinder; + this.syncExecutor = executor; + this.audiences = audiences; + this.identityProvider = identityProvider; + } + + @Command( + aliases = { "stats"}, + usage = "", + desc = "Shows when a player was last seen", + min = 0, + max = 1 + ) + @CommandPermissions("projectares.stats") + public void listStats(final CommandContext args, final CommandSender sender) throws CommandException { + syncExecutor.callback( + userFinder.findUser(sender, args, 0, UserFinder.Default.SENDER), + CommandFutureCallback.onSuccess(sender, args, result -> { + HashMap stats = StatsUtil.getStats(result.user); + + Audience audience = audiences.get(sender); + + audience.sendMessage(new HeaderComponent(new Component(ChatColor.AQUA) + .translate("stats.list", new PlayerComponent(identityProvider.createIdentity(result))))); + audience.sendMessage(new Component(ChatColor.AQUA) + .translate("stats.kills", new Component(String.format("%,d", (int)(double)stats.get("kills")), ChatColor.BLUE))); + audience.sendMessage(new Component(ChatColor.AQUA) + .translate("stats.deaths", new Component(String.format("%,d", (int)(double)stats.get("deaths")), ChatColor.BLUE))); + audience.sendMessage(new Component(ChatColor.AQUA) + .translate("stats.kd", new Component(String.format("%.2f", stats.get("kd")), ChatColor.BLUE))); + audience.sendMessage(new Component(ChatColor.AQUA) + .translate("stats.wools", new Component(String.format("%,d", (int)(double)stats.get("wool_placed")), ChatColor.BLUE))); + audience.sendMessage(new Component(ChatColor.AQUA) + .translate("stats.cores", new Component(String.format("%,d", (int)(double)stats.get("cores_leaked")), ChatColor.BLUE))); + audience.sendMessage(new Component(ChatColor.AQUA) + .translate("stats.monuments", new Component(String.format("%,d", (int)(double)stats.get("destroyables_destroyed")), ChatColor.BLUE))); + }) + ); + } + +} diff --git a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsManifest.java b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsManifest.java new file mode 100644 index 0000000..deab5b8 --- /dev/null +++ b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsManifest.java @@ -0,0 +1,14 @@ +package tc.oc.commons.bukkit.stats; + +import tc.oc.commons.core.inject.HybridManifest; +import tc.oc.commons.core.plugin.PluginFacetBinder; + +public class StatsManifest extends HybridManifest { + @Override + protected void configure() { + requestStaticInjection(StatsUtil.class); + + new PluginFacetBinder(binder()) + .register(StatsCommands.class); + } +} diff --git a/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsUtil.java b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsUtil.java new file mode 100644 index 0000000..593fdbc --- /dev/null +++ b/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/stats/StatsUtil.java @@ -0,0 +1,60 @@ +package tc.oc.commons.bukkit.stats; + +import org.bukkit.entity.Player; +import tc.oc.api.bukkit.users.BukkitUserStore; +import tc.oc.api.docs.User; + +import javax.inject.Inject; +import java.util.HashMap; +import java.util.Map; + +public class StatsUtil { + + @Inject + private static BukkitUserStore userStore; + + public static HashMap getStats(Player player) { + return getStats(userStore.getUser(player)); + } + + public static HashMap getStats(User user) { + HashMap map = new HashMap<>(); + + if (user.stats_value() != null) { + Map> statsCheck = user.stats_value().get("eternity"); + if (statsCheck != null) { + Map stats = statsCheck.get("global"); + if (stats != null) { + map.put("kills", getDoubleValue(stats.get("kills"))); + map.put("deaths", getDoubleValue(stats.get("deaths"))); + map.put("kd", getDoubleValue(stats.get("kd"))); + map.put("kk", getDoubleValue(stats.get("kk"))); + map.put("wool_placed", getDoubleValue(stats.get("wool_placed"))); + map.put("cores_leaked", getDoubleValue(stats.get("cores_leaked"))); + map.put("destroyables_destroyed", getDoubleValue(stats.get("destroyables_destroyed"))); + map.put("tkrate", getDoubleValue(stats.get("tkrate"))); + + return map; + } + } + } + map.put("kills", 0.0); + map.put("deaths", 0.0); + map.put("kd", 0.0); + map.put("kk", 0.0); + map.put("wool_placed", 0.0); + map.put("cores_leaked", 0.0); + map.put("destroyables_destroyed", 0.0); + map.put("tkrate", 0.0); + + return map; + } + + private static Double getDoubleValue(Object value) { + if (value == null) { + return 0.0; + } + return (Double)value; + } + +} diff --git a/Commons/core/src/main/i18n/templates/commons/Commons.properties b/Commons/core/src/main/i18n/templates/commons/Commons.properties index e32449b..08aa6d1 100644 --- a/Commons/core/src/main/i18n/templates/commons/Commons.properties +++ b/Commons/core/src/main/i18n/templates/commons/Commons.properties @@ -203,6 +203,16 @@ mutationtokens.balance.other = {0} has {1} {2} mutationtokens.singular = Mutation Token mutationtokens.plural = Mutation Tokens +stats.list = {0}'s Stats +stats.kills = Kills: {0} +stats.deaths = Deaths: {0} +stats.kd = KD: {0} +stats.kk = KK: {0} +stats.wools = Wools Placed: {0} +stats.cores = Cores Leaked: {0} +stats.monuments = Monuments Destroyed: {0} +stats.teamkills = TK: {0} + material.Iron = Iron material.gold = Gold material.quartz = Quartz @@ -211,13 +221,21 @@ punishment.prefix = Punish punishment.lookup = {0}'s Punishments punishment.warning = WARNING -punishment.screen.warn = You were warned by a staff member {0} -punishment.screen.kick = You were kicked by a staff member {0} -punishment.screen.ban = You were banned by a staff member {0} -punishment.screen.forum_warn = You were forum warned by a staff member {0} -punishment.screen.forum_ban = You were forum banned by a staff member {0} -punishment.screen.tourney_ban = You were tournament banned by a staff member {0} -punishment.screen.suspension = You were suspended by a staff member {0} -punishment.screen.unknown = You were issued an unknown punishment by a staff member {0} +punishment.screen.WARN = You were warned by a staff member {0} +punishment.screen.KICK = You were kicked by a staff member {0} +punishment.screen.BAN = You were banned by a staff member {0} +punishment.screen.FORUM_WARN = You were forum warned by a staff member {0} +punishment.screen.FORUM_BAN = You were forum banned by a staff member {0} +punishment.screen.TOURNEY_BAN = You were tournament banned by a staff member {0} +punishment.screen.SUSPENSION = You were suspended by a staff member {0} +punishment.screen.UNKNOWN = You were issued an unknown punishment by a staff member {0} punishment.screen.rules = Read our server rules at {0} punishment.screen.appeal = or contest your punishment at {0} +punishment.action.WARN = Warned +punishment.action.KICK = Kicked +punishment.action.BAN = Banned +punishment.action.FORUM_WARN = Forum Warned +punishment.action.FORUM_BAN = Forum Baned +punishment.action.TOURNEY_BAN = Tourney Baned +punishment.action.UNKNOWN = Unknown + diff --git a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties index 52dc285..8cd057e 100644 --- a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties +++ b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties @@ -332,3 +332,14 @@ broadcast.alliancesNotAllowed = Creating alliances with other players is NOT all countdown.chestsRefill = Chests will refill in {0} countdown.glowingEffect = Glowing effect in {0} + +stats.ui.list = 's Stats +stats.ui.kills = Kills: +stats.ui.deaths = Deaths: +stats.ui.kd = KD: +stats.ui.kk = KK: +stats.ui.wools = Wools Placed: +stats.ui.cores = Cores Leaked: +stats.ui.monuments = Monuments Destroyed: +stats.ui.teamkills = TK: + diff --git a/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java b/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java index 3076d8a..71e74b1 100644 --- a/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java +++ b/PGM/src/main/java/tc/oc/pgm/commands/PollCommands.java @@ -30,6 +30,8 @@ import tc.oc.pgm.polls.PollNextMap; import javax.inject.Inject; +import java.util.List; + import static tc.oc.commons.bukkit.commands.CommandUtils.newCommandException; public class PollCommands implements Commands { @@ -126,7 +128,12 @@ public class PollCommands implements Commands { max = -1 ) @CommandPermissions("poll.next") - public static void pollNext(CommandContext args, CommandSender sender) throws CommandException { + public static List pollNext(CommandContext args, CommandSender sender) throws CommandException { + final String mapName = args.argsLength() > 0 ? args.getJoinedStrings(0) : ""; + if(args.getSuggestionContext() != null) { + return CommandUtils.completeMapName(mapName); + } + if (restartManager.isRestartRequested()) { throw newCommandException(sender, new TranslatableComponent("poll.map.restarting")); } @@ -149,6 +156,7 @@ public class PollCommands implements Commands { } startPoll(new PollNextMap(PGM.getPollManager(), Bukkit.getServer(), sender, initiator.getName(), PGM.getMatchManager(), nextMap)); + return null; } @Command( diff --git a/PGM/src/main/java/tc/oc/pgm/menu/gui/MainMenuInterface.java b/PGM/src/main/java/tc/oc/pgm/menu/gui/MainMenuInterface.java index 79afc84..f525456 100644 --- a/PGM/src/main/java/tc/oc/pgm/menu/gui/MainMenuInterface.java +++ b/PGM/src/main/java/tc/oc/pgm/menu/gui/MainMenuInterface.java @@ -3,16 +3,21 @@ package tc.oc.pgm.menu.gui; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; +import tc.oc.commons.bukkit.chat.PlayerComponent; import tc.oc.commons.bukkit.gui.buttons.Button; import tc.oc.commons.bukkit.gui.interfaces.ChestInterface; +import tc.oc.commons.bukkit.stats.StatsUtil; import tc.oc.commons.bukkit.tokens.TokenUtil; import tc.oc.commons.bukkit.util.Constants; import tc.oc.commons.bukkit.util.ItemCreator; +import tc.oc.commons.core.chat.Component; +import tc.oc.pgm.PGMTranslations; import tc.oc.pgm.tokens.gui.MainTokenButton; import tc.oc.pgm.tokens.gui.MutationTokenInterface; import tc.oc.pgm.tokens.gui.TokenPurchaseInterface; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class MainMenuInterface extends ChestInterface { @@ -40,11 +45,19 @@ public class MainMenuInterface extends ChestInterface { MainTokenButton.getInstance().setSlot(11); buttons.add(MainTokenButton.getInstance()); + HashMap stats = StatsUtil.getStats(getPlayer()); + buttons.add(new Button( - new ItemCreator(Material.SKULL_ITEM) - .setName(Constants.PREFIX + "Stats") - .setData(3) - , 13)); //TODO -- show stats in lore + new ItemCreator(Material.GOLDEN_APPLE) + .setData(1) + .setName(Constants.PREFIX + getPlayer().getDisplayName() + PGMTranslations.get().t("stats.ui.list", getPlayer())) + .addLore(ChatColor.AQUA + PGMTranslations.get().t("stats.ui.kills", getPlayer()) + ChatColor.BLUE + String.format("%,d", (int)(double)stats.get("kills"))) + .addLore(ChatColor.AQUA + PGMTranslations.get().t("stats.ui.deaths", getPlayer()) + ChatColor.BLUE + String.format("%,d", (int)(double)stats.get("deaths"))) + .addLore(ChatColor.AQUA + PGMTranslations.get().t("stats.ui.kd", getPlayer()) + ChatColor.BLUE + String.format("%.2f", stats.get("kd"))) + .addLore(ChatColor.AQUA + PGMTranslations.get().t("stats.ui.wools", getPlayer()) + ChatColor.BLUE + String.format("%,d", (int)(double)stats.get("wool_placed"))) + .addLore(ChatColor.AQUA + PGMTranslations.get().t("stats.ui.cores", getPlayer()) + ChatColor.BLUE + String.format("%,d", (int)(double)stats.get("cores_leaked"))) + .addLore(ChatColor.AQUA + PGMTranslations.get().t("stats.ui.monuments", getPlayer()) + ChatColor.BLUE + String.format("%,d", (int)(double)stats.get("destroyables_destroyed"))) + , 13)); buttons.add(new Button( new ItemCreator(Material.BOOK_AND_QUILL) diff --git a/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java b/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java index 8da9e48..2ccb405 100644 --- a/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java +++ b/PGM/src/main/java/tc/oc/pgm/tokens/gui/MainTokenMenu.java @@ -8,6 +8,7 @@ import tc.oc.commons.bukkit.util.Constants; import tc.oc.commons.bukkit.util.ItemCreator; import org.bukkit.Material; import org.bukkit.entity.Player; +import tc.oc.pgm.menu.gui.MainMenuInterface; import java.util.ArrayList; import java.util.List; @@ -18,7 +19,7 @@ public class MainTokenMenu extends ChestInterface { private Player player; public MainTokenMenu(Player player) { - super(player, new ArrayList