From a5a1daa80b386c6ca43b651a2c2dae2f53db6afd Mon Sep 17 00:00:00 2001 From: Xander Date: Sun, 8 Oct 2023 21:37:35 +0200 Subject: First commit --- src/main/java/org/biltopia/Main.java | 370 +++++++++++++++++++++++++++++++ src/main/java/org/biltopia/SaveTask.java | 18 ++ src/main/resources/plugin.yml | 33 +++ 3 files changed, 421 insertions(+) create mode 100644 src/main/java/org/biltopia/Main.java create mode 100644 src/main/java/org/biltopia/SaveTask.java create mode 100644 src/main/resources/plugin.yml (limited to 'src') diff --git a/src/main/java/org/biltopia/Main.java b/src/main/java/org/biltopia/Main.java new file mode 100644 index 0000000..4dff9ec --- /dev/null +++ b/src/main/java/org/biltopia/Main.java @@ -0,0 +1,370 @@ +package org.biltopia; + +import org.bukkit.*; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.*; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.ScoreboardManager; +import org.bukkit.scoreboard.Team; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.bukkit.util.io.BukkitObjectOutputStream; + +import javax.annotation.Nullable; +import java.io.*; +import java.util.*; + +record Data(Map playerGroups, Map> uuidMap) implements Serializable { +} + + +public class Main extends JavaPlugin implements Listener { + + private final Map playerGroups = new HashMap<>(); + private static final double MAX_DISTANCE_SQUARED = 200.0; + private static final String FILEPATH = "dump"; + + private final Map> uuidMap = new HashMap<>(); + private final List colors = List.of( + ChatColor.BLUE, + ChatColor.RED, + ChatColor.DARK_BLUE, + ChatColor.DARK_PURPLE, + ChatColor.DARK_AQUA, + ChatColor.DARK_GRAY, + ChatColor.DARK_GREEN, + ChatColor.WHITE, + ChatColor.AQUA, + ChatColor.BLACK, + ChatColor.GOLD, + ChatColor.YELLOW, + ChatColor.LIGHT_PURPLE + ); + + private static ScoreboardManager sm; + private static Scoreboard scoreboard; + + + @Override + public void onEnable() { + getLogger().info("onEnable is called!"); + getServer().getPluginManager().registerEvents(this, this); + Objects.requireNonNull(getCommand("groupAdd")).setExecutor(this::addToGroupCommand); + Objects.requireNonNull(getCommand("groupRemove")).setExecutor(this::removeFromGroupCommand); + Objects.requireNonNull(getCommand("groupList")).setExecutor(this::groupListCommand); + Objects.requireNonNull(getCommand("groupsSave")).setExecutor(this::groupsSaveCommand); + Objects.requireNonNull(getCommand("groupsLoad")).setExecutor(this::groupsLoadCommand); + Objects.requireNonNull(getCommand("startSaving")).setExecutor(this::startSavingCommand); + sm = Bukkit.getScoreboardManager(); + scoreboard = sm.getMainScoreboard(); + scoreboard.getTeams().forEach(Team::unregister); + loadData(); + } + + @Override + public void onDisable() { + getLogger().info("onDisable is called!"); + saveData(); + } + + public boolean saveData() { + try { + BukkitObjectOutputStream out = new BukkitObjectOutputStream(new FileOutputStream(FILEPATH)); + Data data = new Data(playerGroups, uuidMap); + out.writeObject(data); + out.close(); + getLogger().info("Saved groups!"); + return true; + } catch (IOException e) { + System.out.println(e.toString()); + return false; + } + } + + public boolean loadData() { + try { + BukkitObjectInputStream in = new BukkitObjectInputStream(new FileInputStream(FILEPATH)); + Data data = (Data) in.readObject(); + in.close(); + for (Map.Entry entry : data.playerGroups().entrySet()) { + Player player = Bukkit.getPlayer(entry.getKey()); + if (player != null) { + addPlayer(player, entry.getValue()); + } else { + OfflinePlayer offline = Bukkit.getOfflinePlayer(entry.getKey()); + addPlayer(offline,entry.getValue()); + } + } + return true; + } catch (ClassNotFoundException | IOException e) { + System.out.println(e); + return false; + } + } + + private double getDistanceSquared(Location loc, Location loc2) { + return Math.pow(loc.getX() - loc2.getX(), 2) + Math.pow(loc.getZ() - loc2.getZ(), 2); + } + + @Nullable + private Location getGroupCenter(Player player) { + if (playerGroups.containsKey(player.getUniqueId())) { + // Calculate center of locations + double x = 0.0; + double y = 0.0; + double z = 0.0; + + ArrayList list = uuidMap.get(playerGroups.get(player.getUniqueId())); + int size = 0; + for (UUID id : list) { + Player p = Bukkit.getPlayer(id); + if (p != null) { + size++; + x += p.getLocation().getX(); + y += p.getLocation().getY(); + z += p.getLocation().getZ(); + } + } + + x /= size; + y /= size; + z /= size; + + return new Location(player.getWorld(), x, y, z); + } + return null; + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + if (event.getFrom().getX() != event.getTo().getX() || event.getFrom().getZ() != event.getTo().getZ() || event.getFrom().getY() != event.getTo().getY()) { + Player player = event.getPlayer(); + Location center = getGroupCenter(player); + if (center != null) { + double distanceFrom = getDistanceSquared(event.getFrom(), center); + double distanceTo = getDistanceSquared(event.getTo(), center); + if (distanceTo > MAX_DISTANCE_SQUARED && distanceTo > distanceFrom) { + event.setCancelled(true); + player.sendMessage(ChatColor.RED + "You're too far from your group!!"); + } + } + } + } + + @EventHandler + void onRightClick(PlayerInteractEvent event) { + if ((event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) && event.getMaterial() == Material.COMPASS && playerGroups.containsKey(event.getPlayer().getUniqueId())) { + event.getPlayer().setCompassTarget(Objects.requireNonNull(getGroupCenter(event.getPlayer()))); + event.getPlayer().sendMessage(ChatColor.BLUE + "Updated compass direction to group center."); + } + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + player.setGlowing(true); + if (playerGroups.containsKey(player.getUniqueId())) { + for (UUID id : uuidMap.get(playerGroups.get(player.getUniqueId()))) { + Player p = Bukkit.getPlayer(id); + if (p != null && p.getUniqueId() != player.getUniqueId()) { + player.teleport(p); + return; + } + } + } + } + + @EventHandler + public void onPlayerTeleport(PlayerTeleportEvent event) { + UUID uuid = event.getPlayer().getUniqueId(); + if (event.getCause() != PlayerTeleportEvent.TeleportCause.PLUGIN && playerGroups.containsKey(uuid) && event.getTo() != null) { + for (UUID id : uuidMap.get(playerGroups.get(uuid))) { + Player p = Bukkit.getPlayer(id); + if (p != null && + p.getUniqueId() != uuid && + event.getTo().getWorld() != null && + (p.getWorld().getEnvironment() != event.getTo().getWorld().getEnvironment() || + getDistanceSquared(p.getLocation(), event.getTo()) > MAX_DISTANCE_SQUARED)) { + p.teleport(event.getTo()); + } + } + } + } + + @EventHandler + public void onSpawnChange(PlayerSpawnChangeEvent event) { + if (event.getCause() == PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR) { + event.getPlayer().sendMessage(ChatColor.RED + "Not supported, sorry..."); + event.setCancelled(true); + } + } + + @EventHandler + public void onSpawnBed(PlayerBedEnterEvent event) { + Player player = event.getPlayer(); + if (playerGroups.containsKey(player.getUniqueId())) { + for (UUID id : uuidMap.get(playerGroups.get(player.getUniqueId()))) { + Player p = Bukkit.getPlayer(id); + if (p != null) { + p.setBedSpawnLocation(event.getBed().getLocation()); + } + } + } + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + Player player = event.getEntity(); + EntityDamageEvent damageEvent = player.getLastDamageCause(); + if (damageEvent != null && damageEvent.getCause() == EntityDamageEvent.DamageCause.CUSTOM) { + event.setKeepInventory(true); + event.getDrops().clear(); + } else if (playerGroups.containsKey(player.getUniqueId())) { + uuidMap.get(playerGroups.get(player.getUniqueId())).forEach(uuid -> { + Player target = Bukkit.getPlayer(uuid); + if (target != null && target.getUniqueId() != player.getUniqueId()) { + target.setLastDamageCause(new EntityDamageEvent(target, EntityDamageEvent.DamageCause.CUSTOM, 0)); + target.setHealth(0); + } + }); + } + } + + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent event) { + Player player = event.getPlayer(); + if (playerGroups.containsKey(player.getUniqueId()) && !player.getInventory().contains(Material.COMPASS)) { + player.getInventory().addItem(new ItemStack(Material.COMPASS, 1)); + } + } + + private void addPlayer(OfflinePlayer player, Integer index) { + if (player.getName() == null) { + getLogger().warning("Player name not found"); + return; + }; + + ArrayList list = uuidMap.getOrDefault(index, new ArrayList<>()); + + playerGroups.put(player.getUniqueId(), index); + list.add(player.getUniqueId()); + + if (!uuidMap.containsKey(index)) { + uuidMap.put(index, list); + Team team = scoreboard.registerNewTeam(index.toString()); + if (index == 69) { + team.setColor(ChatColor.MAGIC); + } else { + team.setColor(colors.get(index % colors.size())); + } + team.setPrefix("Team " + index.toString() + " "); + team.setAllowFriendlyFire(false); + team.addEntry(player.getName()); + } else { + Team team = scoreboard.getTeam(index.toString()); + if (team != null) { + team.addEntry(player.getName()); + } + } + + + if (player instanceof Player onlinePlayer) { + onlinePlayer.sendMessage(ChatColor.GREEN + "You have been added to team " + index.toString()); + + if (!onlinePlayer.getInventory().contains(Material.COMPASS)) { + onlinePlayer.getInventory().addItem(new ItemStack(Material.COMPASS, 1)); + } + } + + } + + public boolean addToGroupCommand(CommandSender sender, Command cmd, String label, String[] args) { + try { + if (args.length == 2) { + Player player = Bukkit.getPlayerExact(args[0]); + if (player != null && !playerGroups.containsKey(player.getUniqueId())) { + Integer index = Integer.parseInt(args[1]); + addPlayer(player, index); + } else { + sender.sendMessage("Player " + args[0] + " does not exist."); + } + } else { + sender.sendMessage("groupAdd usage: /groupAdd "); + return false; + } + } catch (NumberFormatException ex) { + sender.sendMessage(ChatColor.RED + "usage: /groupAdd "); + return false; + } + + return true; + } + + public boolean removeFromGroupCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (args.length > 0) { + Player player = Bukkit.getPlayerExact(args[0]); + if (player != null) { + + if (playerGroups.containsKey(player.getUniqueId())) { + Integer index = playerGroups.get(player.getUniqueId()); + ArrayList list = uuidMap.get(index); + list.remove(player.getUniqueId()); + playerGroups.remove(player.getUniqueId()); + player.sendMessage(ChatColor.RED + "You have been removed from your team"); + Team team = scoreboard.getTeam(index.toString()); + if (team != null) { + team.removeEntry(player.getName()); + } + } else { + getLogger().warning("Player not in group!"); + } + + } else { + getLogger().warning("Player " + args[0] + " does not exist."); + } + } else { + getLogger().warning("groupAdd usage: /groupAdd "); + return false; + } + + return true; + } + + public boolean groupListCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (sender instanceof Player player) { + uuidMap.forEach((num, list) -> { + player.sendMessage(ChatColor.BLUE + "Group: " + num); + list.forEach(item -> { + OfflinePlayer p = Bukkit.getPlayer(item); + if (p == null) { + p = Bukkit.getOfflinePlayer(item); + } + player.sendMessage((p.isOnline() ? ChatColor.GREEN : ChatColor.RED) + " " + p.getName()); + }); + }); + return true; + } + return false; + } + + public boolean groupsSaveCommand(CommandSender sender, Command cmd, String label, String[] args) { + return this.saveData(); + } + + public boolean groupsLoadCommand(CommandSender sender, Command cmd, String label, String[] args) { + return this.loadData(); + } + + public boolean startSavingCommand(CommandSender sender, Command cmd, String label, String[] args) { + new SaveTask(this).runTaskTimer(this, 0, 400); + return true; + } +} diff --git a/src/main/java/org/biltopia/SaveTask.java b/src/main/java/org/biltopia/SaveTask.java new file mode 100644 index 0000000..4fff4f8 --- /dev/null +++ b/src/main/java/org/biltopia/SaveTask.java @@ -0,0 +1,18 @@ +package org.biltopia; + +import org.bukkit.scheduler.BukkitRunnable; + +public class SaveTask extends BukkitRunnable { + + private final Main owner; + + public SaveTask(Main owner) { + this.owner = owner; + } + + @Override + public void run() { + owner.saveData(); + } + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..ad0d849 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,33 @@ +name: SpeedrunPlugin +version: 1.0 +main: org.biltopia.Main +api-version: 1.20 +commands: + groupAdd: + description: Add player to group + permission: speedrun.manage + usage: / + groupRemove: + description: Remove player from group + permission: speedrun.manage + usage: / + groupList: + description: Show the groups with all it's players + permission: speedrun.manage + usage: / + groupsSave: + description: Save the current group configuration to make it persistent. + permission: speedrun.manage + usage: / + groupsLoad: + description: Load the current group configuration from persistent storage. + permission: speedrun.manage + usage: / + startSaving: + description: Begins the saving tasks that executes groupsSave repeatedly. + permission: speedrun.manage + usage: / + +permissions: + speedrun.manage: + description: Allow managing speedrun plugin commands. \ No newline at end of file -- cgit v1.2.3