summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/biltopia/Main.java370
-rw-r--r--src/main/java/org/biltopia/SaveTask.java18
-rw-r--r--src/main/resources/plugin.yml33
3 files changed, 421 insertions, 0 deletions
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<UUID, Integer> playerGroups, Map<Integer, ArrayList<UUID>> uuidMap) implements Serializable {
+}
+
+
+public class Main extends JavaPlugin implements Listener {
+
+ private final Map<UUID, Integer> playerGroups = new HashMap<>();
+ private static final double MAX_DISTANCE_SQUARED = 200.0;
+ private static final String FILEPATH = "dump";
+
+ private final Map<Integer, ArrayList<UUID>> uuidMap = new HashMap<>();
+ private final List<ChatColor> 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<UUID, Integer> 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<UUID> 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<UUID> 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 <player> <index>");
+ return false;
+ }
+ } catch (NumberFormatException ex) {
+ sender.sendMessage(ChatColor.RED + "usage: /groupAdd <player> <NUMBER>");
+ 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<UUID> 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 <player>");
+ 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: /<command> <player>
+ groupRemove:
+ description: Remove player from group
+ permission: speedrun.manage
+ usage: /<command> <player>
+ groupList:
+ description: Show the groups with all it's players
+ permission: speedrun.manage
+ usage: /<command>
+ groupsSave:
+ description: Save the current group configuration to make it persistent.
+ permission: speedrun.manage
+ usage: /<command>
+ groupsLoad:
+ description: Load the current group configuration from persistent storage.
+ permission: speedrun.manage
+ usage: /<command>
+ startSaving:
+ description: Begins the saving tasks that executes groupsSave repeatedly.
+ permission: speedrun.manage
+ usage: /<command>
+
+permissions:
+ speedrun.manage:
+ description: Allow managing speedrun plugin commands. \ No newline at end of file