diff --git a/src/main/java/com/eofitg/hardcore/ConfigReader.java b/src/main/java/com/eofitg/hardcore/ConfigReader.java deleted file mode 100644 index 0eae7a7..0000000 --- a/src/main/java/com/eofitg/hardcore/ConfigReader.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.eofitg.hardcore; - -import org.bukkit.configuration.file.FileConfiguration; - -import java.util.List; - -public class ConfigReader { - private static FileConfiguration config = Hardcore.getInstance().getConfig(); - private static List playerNames = config.getStringList("playerNames"); - private static List cmdNames = config.getStringList("commandNames"); - private static boolean state = config.getBoolean("enable"); - public static List getPlayerNames() { - return playerNames; - } - public static boolean getPlayerState(String name) { - return config.getBoolean("alive." + name); - } - public static List getCmdNames() { - return cmdNames; - } - public static List getCmdList(String cmd) { - return config.getStringList("commands." + cmd); - } - public static boolean getState() { - return state; - } - public static int getPoint(String name) { - return config.getInt("point." + name); - } - public static void set(String key, Object value) { - config.set(key, value); - } - public static void setPoint(String name, int point) { - config.set("point." + name, point); - } - public static void reset(String name) { - if (playerNames.contains(name)) { - set("alive." + name, true); - set("point." + name, 0); - } - } - public static void reset() { - for (String s : playerNames) { - reset(s); - } - } -} diff --git a/src/main/java/com/eofitg/hardcore/Hardcore.java b/src/main/java/com/eofitg/hardcore/Hardcore.java index 8f8977c..a073b42 100644 --- a/src/main/java/com/eofitg/hardcore/Hardcore.java +++ b/src/main/java/com/eofitg/hardcore/Hardcore.java @@ -2,17 +2,21 @@ import com.eofitg.hardcore.cmdoperation.CommandRegister; import com.eofitg.hardcore.cmdoperation.TabCompleterRegister; +import com.eofitg.hardcore.configuration.MainConfig; +import com.eofitg.hardcore.configuration.UserDataConfig; import com.eofitg.hardcore.listener.PlayerListener; import com.eofitg.hardcore.listener.PointListener; +import com.eofitg.hardcore.util.Leaderboard; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; -import java.util.List; +import java.util.*; public final class Hardcore extends JavaPlugin { + private static Hardcore instance; private static String pluginName; public static Hardcore getInstance() { @@ -22,46 +26,76 @@ public static String getPluginName() { return pluginName; } + // Store players' leaderboards displayed on their interfaces + public static Map leaderboards = new HashMap<>(); + + @Override public void onEnable() { // Plugin startup logic instance = this; pluginName = instance.getName(); + MainConfig.saveDefault(); + // Register Listeners Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); Bukkit.getPluginManager().registerEvents(new PointListener(), this); - CommandRegister.register(ConfigReader.getCmdNames()); - TabCompleterRegister.register(ConfigReader.getCmdNames()); + // Register Commands + CommandRegister.register(MainConfig.getCmdNames()); + TabCompleterRegister.register(MainConfig.getCmdNames()); - // 扫描所有在线玩家加入到玩家列表 - if (ConfigReader.getState()) { + // Add all online players to the player list then toggle their game-mode + if (MainConfig.getState()) { for (Player player : Bukkit.getOnlinePlayers()) { - String playerName = player.getName(); - List playerNames = ConfigReader.getPlayerNames(); - if (!playerNames.contains(playerName)) { - playerNames.add(playerName); - ConfigReader.set("playerNames", playerNames); - ConfigReader.set("alive." + playerName, true); - Hardcore.getInstance().saveConfig(); + // playerId = playerUuid + '/' + playerName + List playerIdList = MainConfig.getPlayerIdList(); + List uuidList = MainConfig.getUuidList(); + String uuid = player.getUniqueId().toString(); + String playerId = uuid + "/" + player.getName(); + // Create config file for this player + UserDataConfig userDataConfig; + userDataConfig = new UserDataConfig(player, player.getUniqueId().toString(), player.getName()); + if (!uuidList.contains(uuid)) { + // new player + playerIdList.add(playerId); + uuidList.add(uuid); + MainConfig.setPlayerIdList(playerIdList); + MainConfig.setUuidList(uuidList); + MainConfig.save(); + // + userDataConfig.init(); + userDataConfig.save(); + // player.setGameMode(GameMode.SURVIVAL); player.sendTitle(ChatColor.BLUE + "WELCOME, NEW PLAYER!", ChatColor.GRAY + "You only have one life and do your best to survive!", 10, 150, 10); } else { - boolean playerState = ConfigReader.getPlayerState(playerName); + // existing player + if(!playerIdList.contains(playerId)) { + // Player name changed + for(int i = 0; i < playerIdList.size(); i ++) { + if(playerIdList.get(i).contains(uuid)) { + // Update player id (uuid + '/' + name) + playerIdList.set(i, playerId); + } + } + MainConfig.setPlayerIdList(playerIdList); + MainConfig.save(); + } + boolean playerState = userDataConfig.getState(); if (!playerState) { + // player is dead player.setGameMode(GameMode.SPECTATOR); player.sendTitle(ChatColor.RED + "YOU HAVE DIED IN THIS SEASON!", ChatColor.GRAY + "Please wait for the reset!", 10, 150, 10); } else { + // player is alive player.setGameMode(GameMode.SURVIVAL); player.sendTitle(ChatColor.GREEN + "YOU ARE ALIVE!", ChatColor.GRAY + "Survive and earn more points!", 10, 150, 10); } } - } - } else { - for (Player player : Bukkit.getOnlinePlayers()) { - String playerName = player.getName(); - List playerNames = ConfigReader.getPlayerNames(); - if (playerNames.contains(playerName)) { - player.setGameMode(GameMode.SURVIVAL); - } + + // Set the leaderboard + Leaderboard leaderboard = new Leaderboard(Hardcore.getInstance(), player, "Leaderboard"); + leaderboards.put(player, leaderboard); + leaderboard.startShowing(); } } } @@ -69,7 +103,37 @@ public void onEnable() { @Override public void onDisable() { // Plugin shutdown logic + if (!MainConfig.getState()) { + return; + } + + // Restore players' game-mode to their original state + for (Player player : Bukkit.getOnlinePlayers()) { + List playerIdList = MainConfig.getPlayerIdList(); + List uuidList = MainConfig.getUuidList(); + String uuid = player.getUniqueId().toString(); + String name = player.getName(); + String playerId = uuid + "/" + name; + if (uuidList.contains(uuid) && new UserDataConfig(player, uuid, name).exists()) { + player.setGameMode(GameMode.valueOf(new UserDataConfig(player, uuid, name).getGameMode())); + if (!playerIdList.contains(playerId)) { + // Player name changed + for (int i = 0; i < playerIdList.size(); i++) { + if (playerIdList.get(i).contains(uuid)) { + // Update player id (uuid + '/' + name) + playerIdList.set(i, playerId); + } + } + MainConfig.setPlayerIdList(playerIdList); + MainConfig.save(); + } + } + // Delete the leaderboard + leaderboards.get(player).turnOff(); + } + leaderboards.clear(); instance = null; pluginName = null; } + } diff --git a/src/main/java/com/eofitg/hardcore/cmdoperation/CommandChecker.java b/src/main/java/com/eofitg/hardcore/cmdoperation/CommandChecker.java index e6be2ea..b6b7c52 100644 --- a/src/main/java/com/eofitg/hardcore/cmdoperation/CommandChecker.java +++ b/src/main/java/com/eofitg/hardcore/cmdoperation/CommandChecker.java @@ -1,13 +1,13 @@ package com.eofitg.hardcore.cmdoperation; -import com.eofitg.hardcore.ConfigReader; import com.eofitg.hardcore.Hardcore; +import com.eofitg.hardcore.configuration.MainConfig; import java.util.List; public class CommandChecker { public static boolean conform (String requestCommand, String commandName) { - List cmdList = ConfigReader.getCmdList(commandName); + List cmdList = MainConfig.getCmdList(commandName); String pluginName = Hardcore.getPluginName().toLowerCase(); if (requestCommand.startsWith(pluginName + ":")) { requestCommand = requestCommand.substring(pluginName.length() + 1); diff --git a/src/main/java/com/eofitg/hardcore/cmdoperation/CommandHandler.java b/src/main/java/com/eofitg/hardcore/cmdoperation/CommandHandler.java index 7c23334..3876956 100644 --- a/src/main/java/com/eofitg/hardcore/cmdoperation/CommandHandler.java +++ b/src/main/java/com/eofitg/hardcore/cmdoperation/CommandHandler.java @@ -1,13 +1,16 @@ package com.eofitg.hardcore.cmdoperation; -import com.eofitg.hardcore.ConfigReader; -import com.eofitg.hardcore.Hardcore; +import com.eofitg.hardcore.configuration.MainConfig; +import com.eofitg.hardcore.configuration.UserDataConfig; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; public class CommandHandler implements CommandExecutor { + @Override public boolean onCommand(CommandSender sender, Command command, String label, String args[]) { if (CommandChecker.conform(label, "hardcore")) { @@ -15,11 +18,35 @@ public boolean onCommand(CommandSender sender, Command command, String label, St sender.sendMessage(ChatColor.RED + "No permission."); return true; } + if (args.length > 2) { + sender.sendMessage(ChatColor.RED + "Invalid command."); + return true; + } if (args.length == 0) { sender.sendMessage(ChatColor.RED + "Empty parameters."); return true; } + String childCmd = args[0].toLowerCase(); + if (args.length == 2) { + // /hardcore reset + if (childCmd.equals("reset")) { + String name = args[1]; + for (Player player : Bukkit.getOnlinePlayers()) { + String playerName = player.getName(); + if (name.equalsIgnoreCase(playerName)) { + UserDataConfig userDataConfig = new UserDataConfig(player, player.getUniqueId().toString(), playerName); + userDataConfig.reset(); + userDataConfig.save(); + } + } + sender.sendMessage(ChatColor.BLUE + "Player " + args[1] + "'s state has reset."); + } else { + sender.sendMessage(ChatColor.RED + "Invalid command."); + } + return true; + } + switch (childCmd) { case "help" : { sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&7- &a/hardcore help &f- &7Get Help")); @@ -29,20 +56,19 @@ public boolean onCommand(CommandSender sender, Command command, String label, St break; } case "on" : { - ConfigReader.set("enable", true); - Hardcore.getInstance().saveConfig(); - sender.sendMessage("Hardcore mode is on."); + MainConfig.setState(true); + MainConfig.save(); + sender.sendMessage(ChatColor.BLUE + "Hardcore mode is on."); break; } case "off" : { - ConfigReader.set("enable", false); - Hardcore.getInstance().saveConfig(); - sender.sendMessage("Hardcore mode is off."); + MainConfig.setState(false); + MainConfig.save(); + sender.sendMessage(ChatColor.BLUE + "Hardcore mode is off."); break; } case "reset" : { - ConfigReader.reset(); - Hardcore.getInstance().saveConfig(); + UserDataConfig.reset_all(); sender.sendMessage(ChatColor.BLUE + "Player state has reset."); break; } @@ -51,4 +77,5 @@ public boolean onCommand(CommandSender sender, Command command, String label, St } return false; } + } diff --git a/src/main/java/com/eofitg/hardcore/configuration/MainConfig.java b/src/main/java/com/eofitg/hardcore/configuration/MainConfig.java new file mode 100644 index 0000000..cdc3d46 --- /dev/null +++ b/src/main/java/com/eofitg/hardcore/configuration/MainConfig.java @@ -0,0 +1,52 @@ +package com.eofitg.hardcore.configuration; + +import com.eofitg.hardcore.Hardcore; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.List; + +public class MainConfig { + + private static final FileConfiguration config = Hardcore.getInstance().getConfig(); + private static final List playerIdList = config.getStringList("playerIdList"); + private static final List uuidList = config.getStringList("uuidList"); + private static final List cmdNames = config.getStringList("commandNames"); + private static final boolean state = config.getBoolean("enable"); + + public static List getPlayerIdList() { + return playerIdList; + } + public static List getUuidList() { + return uuidList; + } + public static List getCmdNames() { + return cmdNames; + } + public static List getCmdList(String cmd) { + return config.getStringList("commands." + cmd); + } + public static boolean getState() { + return state; + } + + public static void set(String key, Object value) { + config.set(key, value); + } + public static void setPlayerIdList(List playerIdList) { + set("playerIdList", playerIdList); + } + public static void setUuidList(List uuidList) { + set("uuidList", uuidList); + } + public static void setState(boolean state) { + set("enable", state); + } + + public static void save() { + Hardcore.getInstance().saveConfig(); + } + public static void saveDefault() { + Hardcore.getInstance().saveDefaultConfig(); + } + +} diff --git a/src/main/java/com/eofitg/hardcore/configuration/UserDataConfig.java b/src/main/java/com/eofitg/hardcore/configuration/UserDataConfig.java new file mode 100644 index 0000000..ff4eb57 --- /dev/null +++ b/src/main/java/com/eofitg/hardcore/configuration/UserDataConfig.java @@ -0,0 +1,119 @@ +package com.eofitg.hardcore.configuration; + +import com.eofitg.hardcore.Hardcore; +import org.bukkit.Bukkit; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +public class UserDataConfig { + + private final File configFile; + private final FileConfiguration config; + private final Player player; + private final String uuid; + private final String name; + private final String playerId; + private final boolean exists; + private static final List playerIdList = MainConfig.getPlayerIdList(); + private static final List uuidList = MainConfig.getUuidList(); + + public UserDataConfig(Player player, String uuid, String name) { + this.configFile = new File(Hardcore.getInstance().getDataFolder() + "\\userdata", uuid + ".yml"); + this.config = new YamlConfiguration(); + this.player = player; + this.uuid = uuid; + this.name = name; + this.playerId = uuid + "/" + name; + this.exists = configFile.exists(); + if(!exists) { + this.configFile.getParentFile().mkdirs(); + try { + this.configFile.createNewFile(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + try { + this.config.load(configFile); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + } + } + + public void init() { + setName(name); + setUuid(uuid); + setState(true); + setPoint(0); + setGameMode(player.getGameMode().toString()); + } + public boolean exists() { + return exists; + } + + public boolean getState() { + return config.getBoolean("alive"); + } + public double getPoint() { + return config.getDouble("point"); + } + public String getGameMode() { + return config.getString("game-mode"); + } + public void set(String key, Object value) { + config.set(key, value); + } + public void setName(String name) { + set("name", name); + } + public void setUuid(String uuid) { + set("uuid", uuid); + } + public void setState(boolean state) { + set("alive", state); + } + public void setPoint(double point) { + set("point", point); + } + public void setGameMode(String gamemode) { + set("game-mode", gamemode); + } + + public void reset() { // Reset this.state + if(exists) { + setState(true); + setPoint(0); + } + } + public static void reset(String playerId) { // Try to reset a designated player's state + String uuid = playerId.split("/")[0]; + String name = playerId.split("/")[1]; + if (uuidList.contains(uuid)) { + UserDataConfig userDataConfig = new UserDataConfig(Bukkit.getOfflinePlayer(uuid).getPlayer(), uuid, name); + if (userDataConfig.exists()) { + userDataConfig.setState(true); + userDataConfig.setPoint(0); + userDataConfig.save(); + } + } + } + public static void reset_all() { // Reset all players' state + for (String s : playerIdList) { + reset(s); + } + } + public void save(){ + try { + config.save(configFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/com/eofitg/hardcore/listener/AbstractListener.java b/src/main/java/com/eofitg/hardcore/listener/AbstractListener.java new file mode 100644 index 0000000..ce0d26f --- /dev/null +++ b/src/main/java/com/eofitg/hardcore/listener/AbstractListener.java @@ -0,0 +1,12 @@ +package com.eofitg.hardcore.listener; + +import com.eofitg.hardcore.configuration.MainConfig; + +public class AbstractListener { + protected static boolean state = MainConfig.getState(); + + protected static void reload() { + state = MainConfig.getState(); + } + +} diff --git a/src/main/java/com/eofitg/hardcore/listener/PlayerListener.java b/src/main/java/com/eofitg/hardcore/listener/PlayerListener.java index 42d8657..2b213d9 100644 --- a/src/main/java/com/eofitg/hardcore/listener/PlayerListener.java +++ b/src/main/java/com/eofitg/hardcore/listener/PlayerListener.java @@ -1,7 +1,9 @@ package com.eofitg.hardcore.listener; -import com.eofitg.hardcore.ConfigReader; import com.eofitg.hardcore.Hardcore; +import com.eofitg.hardcore.configuration.MainConfig; +import com.eofitg.hardcore.configuration.UserDataConfig; +import com.eofitg.hardcore.util.Leaderboard; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; @@ -10,50 +12,112 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import java.util.List; -public class PlayerListener implements Listener { - boolean state = ConfigReader.getState(); +import static com.eofitg.hardcore.Hardcore.leaderboards; + +public class PlayerListener extends AbstractListener implements Listener { + @EventHandler public void onJoin(PlayerJoinEvent e) { + Player player = e.getPlayer(); + List playerIdList = MainConfig.getPlayerIdList(); + List uuidList = MainConfig.getUuidList(); + String uuid = player.getUniqueId().toString(); + String name = player.getName(); + String playerId = uuid + "/" + name; if (!state) { + if (uuidList.contains(uuid) && new UserDataConfig(player, uuid, name).exists()) { + player.setGameMode(GameMode.valueOf(new UserDataConfig(player, uuid, name).getGameMode())); + if(!playerIdList.contains(playerId)) { + // Player name changed + for(int i = 0; i < playerIdList.size(); i ++) { + if(playerIdList.get(i).contains(uuid)) { + // Update player id (uuid + '/' + name) + playerIdList.set(i, playerId); + } + } + MainConfig.setPlayerIdList(playerIdList); + MainConfig.save(); + } + } return; } - // 新玩家加入时为该玩家申请存储空间 - Player player = e.getPlayer(); - String playerName = e.getPlayer().getName(); - List playerNames = ConfigReader.getPlayerNames(); - if (!playerNames.contains(playerName)) { - playerNames.add(playerName); - ConfigReader.set("playerNames", playerNames); - ConfigReader.set("alive." + playerName, true); - ConfigReader.set("point." + playerName, 0); - Hardcore.getInstance().saveConfig(); + + if (!uuidList.contains(uuid)) { + // New player + playerIdList.add(playerId); + uuidList.add(uuid); + MainConfig.setPlayerIdList(playerIdList); + MainConfig.setUuidList(uuidList); + MainConfig.save(); + // Create user data config for the new player + UserDataConfig userDataConfig = new UserDataConfig(player, uuid, name); + userDataConfig.init(); + userDataConfig.save(); + // Change his/her game-mode and start player.setGameMode(GameMode.SURVIVAL); player.sendTitle(ChatColor.BLUE + "WELCOME, NEW PLAYER!", ChatColor.GRAY + "You only have one life and do your best to survive!", 10, 150, 10); } else { - boolean playerState = ConfigReader.getPlayerState(playerName); + // Existing player + if(!playerIdList.contains(playerId)) { + // Player name changed + for(int i = 0; i < playerIdList.size(); i ++) { + if(playerIdList.get(i).contains(uuid)) { + // Update player id (uuid + '/' + name) + playerIdList.set(i, playerId); + } + } + MainConfig.setPlayerIdList(playerIdList); + MainConfig.save(); + } + boolean playerState = new UserDataConfig(player, uuid, name).getState(); if (!playerState) { + // player is dead player.setGameMode(GameMode.SPECTATOR); - player.sendTitle(ChatColor.RED + "YOU HAVE DIED IN THIS SEASON!", ChatColor.GRAY + "Please wait for the reset!", 10, 150, 10); + player.sendTitle(ChatColor.RED + "YOU ARE DIED!", ChatColor.GRAY + "Please wait for the reset!", 10, 150, 10); } else { + // player is alive player.setGameMode(GameMode.SURVIVAL); player.sendTitle(ChatColor.GREEN + "YOU ARE ALIVE!", ChatColor.GRAY + "Survive and earn more points!", 10, 150, 10); } } + + // Set leaderboard for this player + if (leaderboards.containsKey(player)) { + leaderboards.get(player).startShowing(); + } else { + Leaderboard leaderboard = new Leaderboard(Hardcore.getInstance(), player, "Leaderboard"); + leaderboards.put(player, leaderboard); + leaderboard.startShowing(); + } + + } + + @EventHandler + public void onQuit(PlayerQuitEvent e) { + Player player = e.getPlayer(); + if (leaderboards.containsKey(player)) { + leaderboards.get(player).turnOff(); + leaderboards.remove(player); + } } + @EventHandler public void onDeath(PlayerDeathEvent e) { if (!state) { return; } - // 玩家死亡时触发极限模式机制 - String playerName = e.getEntity().getPlayer().getName(); - ConfigReader.set("alive." + playerName, false); - Hardcore.getInstance().saveConfig(); + // Write config + UserDataConfig userDataConfig = new UserDataConfig(e.getEntity(), e.getEntity().getUniqueId().toString(), e.getEntity().getName()); + userDataConfig.setState(false); + userDataConfig.save(); + + // Send player's location when dead Location location = e.getEntity().getLocation(); String world = e.getEntity().getWorld().getName(); String x = location.getBlockX() + ", "; @@ -62,14 +126,14 @@ public void onDeath(PlayerDeathEvent e) { String location_ = ChatColor.GRAY + "[" + ChatColor.AQUA + x + y + z + ChatColor.GRAY + "] "; e.setDeathMessage(e.getDeathMessage() + " @" + location_ + ChatColor.WHITE + "in " + ChatColor.GREEN + world + ChatColor.RED + " RIP D: "); } + @EventHandler public void onRespawn(PlayerRespawnEvent e) { if (!state) { return; } Player player = e.getPlayer(); - String playerName = e.getPlayer().getName(); - boolean playerState = ConfigReader.getPlayerState(playerName); + boolean playerState = new UserDataConfig(player, player.getUniqueId().toString(), player.getName()).getState(); if (!playerState) { player.setGameMode(GameMode.SPECTATOR); player.sendTitle(ChatColor.RED + "YOU HAVE DIED IN THIS SEASON!", ChatColor.GRAY + "Please wait for the reset!", 10, 150, 10); @@ -78,4 +142,5 @@ public void onRespawn(PlayerRespawnEvent e) { player.sendTitle(ChatColor.GREEN + "YOU ARE ALIVE!", ChatColor.GRAY + "Survive and earn more points!", 10, 150, 10); } } + } diff --git a/src/main/java/com/eofitg/hardcore/listener/PointListener.java b/src/main/java/com/eofitg/hardcore/listener/PointListener.java index 208cfea..81264ec 100644 --- a/src/main/java/com/eofitg/hardcore/listener/PointListener.java +++ b/src/main/java/com/eofitg/hardcore/listener/PointListener.java @@ -1,22 +1,55 @@ package com.eofitg.hardcore.listener; -import com.eofitg.hardcore.ConfigReader; -import com.eofitg.hardcore.Hardcore; +import com.eofitg.hardcore.configuration.UserDataConfig; +import com.eofitg.hardcore.util.MathUtil; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; -public class PointListener implements Listener { +public class PointListener extends AbstractListener implements Listener { + @EventHandler public void getDamage(EntityDamageEvent e) { + if(!state) { // Plugin is off + return; + } if (e.getEntity() instanceof Player) { - String name = e.getEntity().getName(); - int damage = (int) e.getDamage(); - //e.getEntity().sendMessage(name + " " + e.getCause() + " " + e.getDamage()); - int point = ConfigReader.getPoint(name) - damage; - ConfigReader.setPoint(name, point); - Hardcore.getInstance().saveConfig(); + UserDataConfig userDataConfig = new UserDataConfig(((Player) e.getEntity()).getPlayer(), e.getEntity().getUniqueId().toString(), e.getEntity().getName()); + if(!userDataConfig.getState()) return; + + double heart = Math.round(((LivingEntity) e.getEntity()).getHealth() * 2) / 20.0; + double damage = Math.min(heart, Math.round(e.getFinalDamage() * 2) / 20.0); + double point = MathUtil.round_half_up(userDataConfig.getPoint() - damage, 2); + userDataConfig.setPoint(point); + userDataConfig.save(); + + } + } + + @EventHandler + public void causeDamage(EntityDamageByEntityEvent e) { + if(!state) { // Plugin is off + return; + } + if (e.getDamager() instanceof Player) { + if (e.getEntity() instanceof LivingEntity) { + // Why Mojang made ARMOR_STAND a damageable entity??? + if (e.getEntityType() == EntityType.ARMOR_STAND) return; + + UserDataConfig userDataConfig = new UserDataConfig(((Player) e.getDamager()).getPlayer(), e.getDamager().getUniqueId().toString(), e.getDamager().getName()); + if(!userDataConfig.getState()) return; + + double heart = Math.round(((LivingEntity) e.getEntity()).getHealth() * 2) / 20.0; + double damage = Math.min(heart, Math.round(e.getFinalDamage() * 2) / 20.0); + double point = MathUtil.round_half_up(userDataConfig.getPoint() + damage, 2); + userDataConfig.setPoint(point); + userDataConfig.save(); + } } } + } diff --git a/src/main/java/com/eofitg/hardcore/util/Leaderboard.java b/src/main/java/com/eofitg/hardcore/util/Leaderboard.java new file mode 100644 index 0000000..1167041 --- /dev/null +++ b/src/main/java/com/eofitg/hardcore/util/Leaderboard.java @@ -0,0 +1,127 @@ +package com.eofitg.hardcore.util; + +import com.eofitg.hardcore.configuration.MainConfig; +import com.eofitg.hardcore.configuration.UserDataConfig; +import com.google.common.collect.Lists; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import java.text.SimpleDateFormat; +import java.util.*; + +public class Leaderboard { + + private final Plugin plugin; + private String title; + private final Scoreboard scoreboard; + private final Objective objective; + private final Player player; + private boolean isRun; + private final SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd"); + private final SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss"); + private final List text; // All text in the leaderboard + private BukkitTask task; + + public Leaderboard(Plugin plugin, Player player, String title) { + this.plugin = plugin; + this.title = title; + this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + this.objective = scoreboard.registerNewObjective("LEADERBOARD", "dummy", ChatColor.DARK_BLUE + this.title); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + + this.player = player; + this.isRun = false; + text = Lists.newArrayList(); + } + + public void startShowing() { + // Check out if this leaderboard is running + if (isRun) { + return; + } + // Make sure this player's scoreboard is valid + if (player == null || !player.isOnline()) { + return; + } + isRun = true; + player.setScoreboard(scoreboard); + + int N = 7; // The number of players displayed on the leaderboard + List tempList = Lists.newArrayList(); + for (int i = 0; i <= N; i++) { + tempList.add("§" + ChatColor.values()[i].getChar()); + } + + for (int i = 0; i <= N; i++) { + Team row = scoreboard.registerNewTeam("" + i); + row.addEntry(tempList.get(i)); + objective.getScore(tempList.get(i)).setScore(N-i); + text.add(row); + } + + task = Bukkit.getScheduler().runTaskTimer(plugin, () -> { + if (!isRun) { + return; + } + + Map playerState = new HashMap<>(); + Map playerPoint = new HashMap<>(); + List playerIdList = MainConfig.getPlayerIdList(); + for (int i = 0; i < playerIdList.size() && i < N; i++) { + String uuid = playerIdList.get(i).split("/")[0]; + String name = playerIdList.get(i).split("/")[1]; + UserDataConfig userDataConfig = new UserDataConfig(Bukkit.getOfflinePlayer(name).getPlayer(), uuid, name); + playerState.put(name, userDataConfig.getState()); + playerPoint.put(name, userDataConfig.getPoint()); + } + // sort playerPoint by point + List> pointRanking = new LinkedList<>(playerPoint.entrySet()); + // Collections.sort(pointRanking, Map.Entry.comparingByValue()); + Collections.sort(pointRanking, (o1, o2) -> o2.getValue().compareTo(o1.getValue())); + + for (int i = 0, j = 0; i < text.size(); i++) { + Team row = text.get(i); // Get every Team + if (i == 0) { + // Date & Time HUD + Date date = new Date(); + row.setPrefix(ChatColor.GRAY + format.format(date)); + row.setSuffix(ChatColor.GRAY + " " + format2.format(date)); + continue; + } + if (j < pointRanking.size()) { + // Fill in the players' data on the leaderboard + String name = pointRanking.get(j).getKey(); + double points = pointRanking.get(j).getValue(); + String suffix = ChatColor.GOLD + name + ChatColor.WHITE + " - " + ChatColor.GOLD + points; + if (playerState.get(name)) { + suffix = suffix + ChatColor.GREEN + " √"; + } else { + suffix = suffix + ChatColor.RED + " ×"; + } + row.setPrefix(ChatColor.GREEN + "#" + i + ": "); + row.setSuffix(suffix); + j++; + continue; + } + // i < text.size() && j < pointRanking.size() -> pointRanking.size() < i < text.size() , mean last rows have no last players to fill + row.setPrefix(ChatColor.GREEN + "#" + i + ": "); + row.setSuffix(ChatColor.DARK_GRAY + "****" + ChatColor.WHITE + " - " + ChatColor.DARK_GRAY + "****"); + } + + }, 0L, 20L); + } + + public void turnOff() { + isRun = false; + task.cancel(); + player.setScoreboard(Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard()); + } + +} diff --git a/src/main/java/com/eofitg/hardcore/util/MathUtil.java b/src/main/java/com/eofitg/hardcore/util/MathUtil.java new file mode 100644 index 0000000..0f55361 --- /dev/null +++ b/src/main/java/com/eofitg/hardcore/util/MathUtil.java @@ -0,0 +1,11 @@ +package com.eofitg.hardcore.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class MathUtil { + public static double round_half_up(double number, int scale) { + BigDecimal bd = new BigDecimal(number); + return bd.setScale(scale, RoundingMode.HALF_UP).doubleValue(); + } +} diff --git a/src/main/java/com/eofitg/hardcore/util/TestScordboard.java b/src/main/java/com/eofitg/hardcore/util/TestScordboard.java new file mode 100644 index 0000000..87a968c --- /dev/null +++ b/src/main/java/com/eofitg/hardcore/util/TestScordboard.java @@ -0,0 +1,99 @@ +package com.eofitg.hardcore.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import com.google.common.collect.Lists; + +public class TestScordboard { + + private Scoreboard scoreboard; + private Objective objective; + private String title; + private Player player; + private boolean isRun; + private SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd"); + private SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss"); + // 用作runnable的主类实例 + private Plugin plugin; + /** + * 用于保存所有的Team + */ + private List timers; + private BukkitTask task; + + public TestScordboard(Plugin plugin, Player player, String title) { + this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + this.title = title; + this.objective = scoreboard.registerNewObjective(player.getName(), "dummy", this.title.replace("&", "§")); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + + this.player = player; + this.isRun = false; + this.plugin = plugin; + timers = Lists.newArrayList(); + } + + public void startShowing() { + // 判断是否已经在运行 + if (isRun) { + return; + } + if (player == null || !player.isOnline()) { + return; + } + isRun = true; + player.setScoreboard(scoreboard); + + // 用于保存前15位的内容 + List tempList = Lists.newArrayList(); + for (int i = 0; i <= 10; i++) { + tempList.add("§" + ChatColor.values()[i].getChar()); + } + + for (int i = 0; i <= 10; i++) { + // 注册Team时使用 数字的形式就行 + Team timer = scoreboard.registerNewTeam("" + i); + // addEntry只是作为一个标识符, 用于getScore时的识别 + timer.addEntry(tempList.get(i)); + // getScore 刚才的标识符 + objective.getScore(tempList.get(i)).setScore(i); + + timers.add(timer); + } + + task = Bukkit.getScheduler().runTaskTimer(plugin, () -> { + if (!isRun) { + return; + } + + for (int i = 0; i < timers.size(); i++) { + Team timer = timers.get(i); // 获取每个Team + Date date = new Date(); + // 设置前缀 + timer.setPrefix(tempList.get(i) + format.format(date)); + // 设置后缀 + timer.setSuffix(tempList.get(i) + " " + format2.format(date)); + } + + }, 0L, 20L); + } + + public void turnOff() { + isRun = false; + task.cancel(); + player.setScoreboard(Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard()); + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 6e839a5..72b87c7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,4 @@ -playerNames: -alive: -point: commandNames: [ hardcore ] commands: hardcore: [ hardcore, hardcoremode ] -enable: false \ No newline at end of file +enable: true \ No newline at end of file