From 72e88ce491dca43c4095a61021ffa31bffd2690d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Sat, 21 Jun 2025 18:51:37 +0200 Subject: [PATCH] added spawnpoint for varo --- .../spawnpoint/SetSpawnpointCommand.java | 27 +++++ .../spawnpoint/SpawnAtSpawnpointListener.java | 20 ++++ .../tooling/spawnpoint/Spawnpoint.java | 105 ++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SetSpawnpointCommand.java create mode 100644 varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SpawnAtSpawnpointListener.java create mode 100644 varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/Spawnpoint.java diff --git a/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SetSpawnpointCommand.java b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SetSpawnpointCommand.java new file mode 100644 index 0000000..52c0b71 --- /dev/null +++ b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SetSpawnpointCommand.java @@ -0,0 +1,27 @@ +package eu.mhsl.craftattack.spawn.varo.appliances.tooling.spawnpoint; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +class SetSpawnpointCommand extends ApplianceCommand.PlayerChecked { + public SetSpawnpointCommand() { + super("setSpawnpoint"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if(args.length < 1) throw new Error("Specify playername for the Spawnpoint"); + var location = this.getPlayer().getLocation() + .toBlockLocation() + .add(0.5, 0.5, 0.5); + location.setYaw(0); + location.setPitch(0); + + this.getAppliance().setSpawnpoint(location, args[0]); + sender.sendMessage(Component.text("Spawnpoint updated!", NamedTextColor.GREEN)); + } +} diff --git a/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SpawnAtSpawnpointListener.java b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SpawnAtSpawnpointListener.java new file mode 100644 index 0000000..3f8475f --- /dev/null +++ b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/SpawnAtSpawnpointListener.java @@ -0,0 +1,20 @@ +package eu.mhsl.craftattack.spawn.varo.appliances.tooling.spawnpoint; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerRespawnEvent; + +class SpawnAtSpawnpointListener extends ApplianceListener { + @EventHandler + public void onJoin(PlayerJoinEvent event) { + this.getAppliance().handlePlayerLogin(event.getPlayer()); + } + + @EventHandler + public void onRespawn(PlayerRespawnEvent event) { + if(event.isBedSpawn()) return; + if(event.isAnchorSpawn()) return; + event.setRespawnLocation(this.getAppliance().getSpawnPoint(event.getPlayer())); + } +} diff --git a/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/Spawnpoint.java b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/Spawnpoint.java new file mode 100644 index 0000000..8974355 --- /dev/null +++ b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/tooling/spawnpoint/Spawnpoint.java @@ -0,0 +1,105 @@ +package eu.mhsl.craftattack.spawn.varo.appliances.tooling.spawnpoint; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import eu.mhsl.craftattack.spawn.core.Main; +import eu.mhsl.craftattack.spawn.core.appliance.Appliance; +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; + +public class Spawnpoint extends Appliance { + private static final String namespace = Spawnpoint.class.getSimpleName().toLowerCase(Locale.ROOT); + public static NamespacedKey alreadySpawned = new NamespacedKey(namespace, "alreadySpawned".toLowerCase()); + + private final Path saveFile = Paths.get(Main.instance().getDataFolder().getAbsolutePath() + "/spawnpoints.json"); + + private final Map spawnPoints = new HashMap<>(); + + public Spawnpoint() { + super("spawnpoint"); + this.load(); + } + + private record LocationDto(String world, double x, double y, double z, float yaw, float pitch) { + static LocationDto from(Location loc) { + return new LocationDto(loc.getWorld().getName(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); + } + + Location toLocation() { + return new Location(Bukkit.getWorld(this.world), this.x, this.y, this.z, this.yaw, this.pitch); + } + } + + private void load() { + if (!Files.exists(this.saveFile)) return; + try (Reader reader = Files.newBufferedReader(this.saveFile)) { + Type type = new TypeToken>() {}.getType(); + Map raw = new Gson().fromJson(reader, type); + for (var entry : raw.entrySet()) { + this.spawnPoints.put(UUID.fromString(entry.getKey()), entry.getValue().toLocation()); + } + } catch (IOException e) { + Main.logger().warning("Failed to load spawnpoints: " + e.getMessage()); + } + } + + private void save() { + try { + Files.createDirectories(this.saveFile.getParent()); + Map raw = new HashMap<>(); + for (var entry : this.spawnPoints.entrySet()) { + raw.put(entry.getKey().toString(), LocationDto.from(entry.getValue())); + } + try (Writer writer = Files.newBufferedWriter(this.saveFile)) { + new Gson().toJson(raw, writer); + } + } catch (IOException e) { + Main.logger().warning("Failed to save spawnpoints: " + e.getMessage()); + } + } + + public void setSpawnpoint(Location location, String playerName) { + UUID uuid = Bukkit.getOfflinePlayer(playerName).getUniqueId(); + this.spawnPoints.put(uuid, location); + this.save(); + } + + public void handlePlayerLogin(Player player) { + PersistentDataContainer dataContainer = player.getPersistentDataContainer(); + if(dataContainer.has(alreadySpawned)) return; + player.teleportAsync(this.spawnPoints.get(player.getUniqueId())); + player.setGameMode(GameMode.ADVENTURE); + dataContainer.set(alreadySpawned, PersistentDataType.BOOLEAN, true); + } + + public Location getSpawnPoint(Player player) { + return this.spawnPoints.get(player.getUniqueId()); + } + + @Override + protected @NotNull List> commands() { + return List.of(new SetSpawnpointCommand()); + } + + @Override + protected @NotNull List listeners() { + return List.of(new SpawnAtSpawnpointListener()); + } +}