Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions src/main/java/wolfcraft/randomspawn/PlayerListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
public class PlayerListener implements Listener {
private final RandomSpawn plugin;
private final SpawnManager spawnManager;

public PlayerListener(RandomSpawn plugin, SpawnManager spawnManager) {
this.plugin = plugin;
this.spawnManager = spawnManager;
}

@EventHandler(priority = EventPriority.HIGH)
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();

// Only teleport on first join
if (!player.hasPlayedBefore() && spawnManager.isFirstJoinEnabled()) {
// Delay the teleport to ensure the player is fully loaded
Expand All @@ -35,27 +35,40 @@ public void run() {
}.runTaskLater(plugin, 5L); // 5 ticks = 0.25 seconds
}
}

@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerRespawn(PlayerRespawnEvent event) {
// Don't override if player has a bed or anchor respawn
if (!event.isBedSpawn() && !event.isAnchorSpawn() && spawnManager.isRespawnOnDeathEnabled()) {
Player player = event.getPlayer();

// Only apply to worlds that are enabled
if (spawnManager.isWorldEnabled(player.getWorld().getName())) {
Location randomLocation = spawnManager.getRandomSpawnLocation(player);

if (randomLocation != null) {
event.setRespawnLocation(randomLocation);

// If configured, transfer the player to another server after respawn
if (spawnManager.getTransferServerName() != null && !spawnManager.getTransferServerName().isEmpty()) {
// Delay the transfer to ensure the player is fully respawned
new BukkitRunnable() {
@Override
public void run() {
if (player.isOnline()) {
plugin.transferPlayerToServer(player, spawnManager.getTransferServerName());
}
}
}.runTaskLater(plugin, 5L); // 5 ticks = 0.25 seconds
}
}
}
}
}

private void teleportToRandomSpawn(Player player) {
Location randomLocation = spawnManager.getRandomSpawnLocation(player);

if (randomLocation != null) {
player.teleport(randomLocation);
}
Expand Down
42 changes: 30 additions & 12 deletions src/main/java/wolfcraft/randomspawn/RandomSpawn.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,37 @@

import java.util.Arrays;
import java.util.List;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;

public class RandomSpawn extends JavaPlugin {
private FileConfiguration config;
private SpawnManager spawnManager;
private final String PREFIX = ChatColor.GOLD + "[RandomSpawn] " + ChatColor.RESET;

@Override
public void onEnable() {
// Save default config if it doesn't exist
saveDefaultConfig();
config = getConfig();

// Initialize spawn manager
spawnManager = new SpawnManager(this);

// Register event listeners
getServer().getPluginManager().registerEvents(new PlayerListener(this, spawnManager), this);


// Register BungeeCord channel
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");

getLogger().info("RandomSpawn has been enabled!");
}

@Override
public void onDisable() {
getLogger().info("RandomSpawn has been disabled!");
}

@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
// Handle both command aliases: /rd and /random
Expand All @@ -44,39 +49,52 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String
showHelp(sender);
return true;
}

if (args[0].equalsIgnoreCase("reload")) {
// Check permission
if (!sender.hasPermission("randomspawn.reload")) {
sender.sendMessage(PREFIX + ChatColor.RED + "You don't have permission to use this command!");
return true;
}

// Reload config
reloadConfig();
config = getConfig();
spawnManager.reloadConfig();
sender.sendMessage(PREFIX + ChatColor.GREEN + "Configuration reloaded successfully!");
return true;
}

// Unknown argument, show help
showHelp(sender);
return true;
}

return false;
}

private void showHelp(CommandSender sender) {
sender.sendMessage(ChatColor.YELLOW + "=== RandomSpawn Help ===");
sender.sendMessage(ChatColor.GOLD + "/rd reload " + ChatColor.WHITE + "- Reload the configuration");
sender.sendMessage(ChatColor.GOLD + "/random reload " + ChatColor.WHITE + "- Reload the configuration");
}

public void reloadPluginConfig() {
reloadConfig();
config = getConfig();
spawnManager.reloadConfig();
}

public void transferPlayerToServer(Player player, String serverName) {
if (player == null || serverName == null || serverName.isEmpty()) return;

try {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF(serverName);
player.sendPluginMessage(this, "BungeeCord", out.toByteArray());
} catch (NoClassDefFoundError | Exception e) {
getLogger().warning("Failed to send player to server '" + serverName + "': " + e.getMessage());
}
}
}
14 changes: 10 additions & 4 deletions src/main/java/wolfcraft/randomspawn/SpawnManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class SpawnManager {
private boolean enableFirstJoinSpawn;
private boolean enableRespawnOnDeath;
private int maxTries;
private String transferServerName;
private Set<String> enabledWorlds;
private Set<String> fatalBlocks;

Expand All @@ -51,6 +52,7 @@ public void reloadConfig() {
forceGroundSpawn = config.getBoolean("spawn.force-ground-spawn", true);
enableFirstJoinSpawn = config.getBoolean("events.first-join", true);
enableRespawnOnDeath = config.getBoolean("events.respawn-on-death", true);
transferServerName = config.getString("spawn.transfer-to-server", "");
maxTries = config.getInt("spawn.max-tries", 50);
fatalBlocks = new HashSet<>();
for (String block : config.getStringList("fatal-blocks")) {
Expand All @@ -77,6 +79,10 @@ public boolean isWorldEnabled(String worldName) {
return enabledWorlds.contains(worldName);
}

public String getTransferServerName() {
return transferServerName;
}

public Location getRandomSpawnLocation(Player player) {
World world = player.getWorld();

Expand Down Expand Up @@ -134,8 +140,8 @@ private Location findSafeYPosition(Location location) {
Block blockAbove = world.getBlockAt(x, y + 1, z);
Block blockTwoAbove = world.getBlockAt(x, y + 2, z);

if (!block.getType().isAir() &&
blockAbove.getType().isAir() &&
if (!block.getType().isAir() &&
blockAbove.getType().isAir() &&
blockTwoAbove.getType().isAir() &&
!block.isLiquid() &&
!isFatalBlock(block.getType().toString())) {
Expand All @@ -157,7 +163,7 @@ private boolean isSafeLocation(Location location) {
Block blockAbove = location.clone().add(0, 1, 0).getBlock();

if (!forceGroundSpawn) {
return block.getType().isAir() &&
return block.getType().isAir() &&
blockAbove.getType().isAir() &&
!blockBelow.getType().isAir() &&
!blockBelow.isLiquid() &&
Expand Down Expand Up @@ -188,7 +194,7 @@ private void cacheLocation(String worldName, Location location) {
locations.remove(locArray[random.nextInt(locArray.length)]);
}
}

private int randomBetween(int min, int max) {
if (min > max) {
int temp = min;
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ spawn:
# If true, players will always spawn on the surface
# This will disable the Y coordinate range setting above
force-ground-spawn: true

# If set, players will be transferred to the specified server after spawning (supports BungeeCord/Waterfall/Velocity)
transfer-to-server: ''

# Maximum number of attempts to find a safe spawn location
max-tries: 50
Expand Down Expand Up @@ -56,4 +59,3 @@ messages:
prefix: "&6[RandomSpawn] &r"
reload: "&aConfiguration reloaded successfully!"
no-permission: "&cYou don't have permission to use this command!"