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
62 changes: 35 additions & 27 deletions src/main/java/pw/kaboom/extras/modules/player/PlayerConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@
import com.destroystokyo.paper.event.profile.PreLookupProfileEvent;
import com.google.common.base.Charsets;
import io.papermc.paper.event.player.AsyncPlayerSpawnLocationEvent;
import io.papermc.paper.event.connection.PlayerConnectionValidateLoginEvent;
import io.papermc.paper.event.player.PlayerServerFullCheckEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.*;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.plugin.java.JavaPlugin;
import pw.kaboom.extras.Main;
import pw.kaboom.extras.modules.server.ServerTabComplete;
import pw.kaboom.extras.modules.player.skin.SkinManager;
import pw.kaboom.extras.util.Utility;

import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

Expand Down Expand Up @@ -55,6 +56,7 @@ public final class PlayerConnection implements Listener {
"allowJoinOnFullServer");
private static final boolean OP_ON_JOIN = CONFIG.getBoolean("opOnJoin");
private static final boolean RANDOMIZE_SPAWN = CONFIG.getBoolean("randomizeSpawn");
private final Set<UUID> disallowedLogins = new HashSet<>(5);

@EventHandler
void onAsyncPlayerPreLogin(final AsyncPlayerPreLoginEvent event) {
Expand Down Expand Up @@ -83,13 +85,21 @@ void onAsyncPlayerPreLogin(final AsyncPlayerPreLoginEvent event) {
void onPlayerJoin(final PlayerJoinEvent event) {
final Player player = event.getPlayer();

if (OP_ON_JOIN && !player.isOp()) {
player.setOp(true);
}

player.showTitle(Title.title(
TITLE,
SUBTITLE,
Title.Times.times(FADE_IN, STAY, FADE_OUT)
));

ServerTabComplete.getLoginNameList().put(player.getUniqueId(), player.getName());

if (!player.getPlayerProfile().hasTextures()) {
SkinManager.applySkin(player, player.getName(), false);
}
}

@EventHandler
Expand All @@ -100,34 +110,32 @@ void onPlayerKick(final PlayerKickEvent event) {
}

@EventHandler
void onPlayerLogin(final PlayerLoginEvent event) {
// #312 - If allow join on full server is off,
// but join restrictions are disabled,
// player can still join on full server

// Full server kicks should be handled differently from other join restrictions
// since we have a separate configuration value for it

if (!ENABLE_JOIN_RESTRICTIONS && !Result.KICK_FULL.equals(event.getResult())) {
event.allow();
void onPlayerServerFullCheck(final PlayerServerFullCheckEvent event) {
if (ALLOW_JOIN_ON_FULL_SERVER) {
event.allow(true);
} else if (!event.isAllowed()) {
this.disallowedLogins.add(event.getPlayerProfile().getId());
}
}

if (Result.KICK_FULL.equals(event.getResult()) && ALLOW_JOIN_ON_FULL_SERVER) {
// Note that this event gets fired even if FullCheckEvent returns disallowed, meaning we need
// to keep track of the player's allowed state across events. Yuck.
@SuppressWarnings("UnstableApiUsage")
@EventHandler
void onPlayerConnectionValidate(final PlayerConnectionValidateLoginEvent event) {
// #312 - If allow join on full server is off, but join restrictions are disabled, player
// can still join on full server

// Full server kicks should be handled differently from other join restrictions since we
// have a separate configuration value for it
final UUID uuid = Utility.getConnectionUuid(event.getConnection());
final boolean disallowed = this.disallowedLogins.remove(uuid);

// If uuid is null, disallowedLogins will never contain it. So we always let connections
// without a UUID through if join restrictions are disabled.
if (!ENABLE_JOIN_RESTRICTIONS && !disallowed) {
event.allow();
}

final Player player = event.getPlayer();

if (OP_ON_JOIN && !player.isOp()) {
player.setOp(true);
}

final Server server = Bukkit.getServer();


if (!server.getOnlineMode()) {
SkinManager.applySkin(player, player.getName(), false);
}
}

@EventHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
Expand Down Expand Up @@ -110,7 +110,7 @@ private static void onUpdate(Player player) throws IOException {
}

@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLoginEvent(PlayerLoginEvent event) throws IOException {
public void onPlayerJoinEvent(PlayerJoinEvent event) throws IOException {
final Player player = event.getPlayer();
final boolean isOp = player.isOp();

Expand Down
23 changes: 23 additions & 0 deletions src/main/java/pw/kaboom/extras/util/Utility.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package pw.kaboom.extras.util;

import com.destroystokyo.paper.profile.PlayerProfile;
import io.papermc.paper.connection.PlayerConfigurationConnection;
import io.papermc.paper.connection.PlayerConnection;
import io.papermc.paper.connection.PlayerLoginConnection;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
Expand All @@ -13,10 +17,29 @@

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.function.Function;

public final class Utility {
@SuppressWarnings("UnstableApiUsage")
public static @Nullable UUID getConnectionUuid(final PlayerConnection connection) {
// https://discord.com/channels/289587909051416579/555462289851940864/1391545447495237637
// Thanks, Paper!
final PlayerProfile profile;
if ((connection instanceof final PlayerLoginConnection loginConnection)) {
profile = loginConnection.getAuthenticatedProfile() != null
? loginConnection.getAuthenticatedProfile()
: loginConnection.getUnsafeProfile();
} else if ((connection instanceof final PlayerConfigurationConnection configConnection)) {
profile = configConnection.getProfile();
} else {
profile = null;
}

return profile != null ? profile.getId() : null;
}

public static void teleportToSpawn(final Player player,
final PlayerTeleportEvent.TeleportCause cause) {
final World world = player.getServer().getRespawnWorld();
Expand Down