mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-10-31 08:32:18 +01:00
Kick/(un)freeze player when they lose/gain additional requirements
This commit is contained in:
parent
a81e8305a0
commit
f285669990
@ -25,7 +25,6 @@ package com.discordsrv.api.module.type;
|
|||||||
|
|
||||||
import com.discordsrv.api.component.MinecraftComponent;
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
import com.discordsrv.api.module.Module;
|
import com.discordsrv.api.module.Module;
|
||||||
import com.discordsrv.api.player.DiscordSRVPlayer;
|
|
||||||
import com.discordsrv.api.punishment.Punishment;
|
import com.discordsrv.api.punishment.Punishment;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -40,7 +39,6 @@ public interface PunishmentModule extends Module {
|
|||||||
CompletableFuture<@Nullable Punishment> getBan(@NotNull UUID playerUUID);
|
CompletableFuture<@Nullable Punishment> getBan(@NotNull UUID playerUUID);
|
||||||
CompletableFuture<Void> addBan(@NotNull UUID playerUUID, @Nullable Instant until, @Nullable MinecraftComponent reason, @NotNull MinecraftComponent punisher);
|
CompletableFuture<Void> addBan(@NotNull UUID playerUUID, @Nullable Instant until, @Nullable MinecraftComponent reason, @NotNull MinecraftComponent punisher);
|
||||||
CompletableFuture<Void> removeBan(@NotNull UUID playerUUID);
|
CompletableFuture<Void> removeBan(@NotNull UUID playerUUID);
|
||||||
CompletableFuture<Void> kickPlayer(@NotNull DiscordSRVPlayer player, @NotNull MinecraftComponent message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Mutes extends PunishmentModule {
|
interface Mutes extends PunishmentModule {
|
||||||
|
@ -66,7 +66,7 @@ public class PaperComponentHandle<T> {
|
|||||||
unrelocated = handle.invoke(target);
|
unrelocated = handle.invoke(target);
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
if (unrelocated != null) {
|
if (unrelocated != null) {
|
||||||
return ComponentUtil.fromUnrelocated(unrelocated);
|
return ComponentUtil.fromUnrelocated((com.discordsrv.unrelocate.net.kyori.adventure.text.Component) unrelocated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,16 +18,23 @@
|
|||||||
|
|
||||||
package com.discordsrv.bukkit.player;
|
package com.discordsrv.bukkit.player;
|
||||||
|
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@SuppressWarnings("JavaLangInvokeHandleSignature") // Unrelocate
|
||||||
public final class PaperPlayer {
|
public final class PaperPlayer {
|
||||||
|
|
||||||
private PaperPlayer() {}
|
private PaperPlayer() {}
|
||||||
|
|
||||||
private static final boolean localeMethodExists;
|
private static final boolean LOCALE_METHOD_EXISTS;
|
||||||
private static final boolean getLocaleMethodExists;
|
private static final boolean GETLOCALE_METHOD_EXISTS;
|
||||||
|
private static final MethodHandle KICK_COMPONENT_HANDLE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Class<?> playerClass = Player.class;
|
Class<?> playerClass = Player.class;
|
||||||
@ -41,18 +48,40 @@ public final class PaperPlayer {
|
|||||||
playerClass.getMethod("getLocale");
|
playerClass.getMethod("getLocale");
|
||||||
getLocale = true;
|
getLocale = true;
|
||||||
} catch (ReflectiveOperationException ignored) {}
|
} catch (ReflectiveOperationException ignored) {}
|
||||||
localeMethodExists = locale;
|
LOCALE_METHOD_EXISTS = locale;
|
||||||
getLocaleMethodExists = getLocale;
|
GETLOCALE_METHOD_EXISTS = getLocale;
|
||||||
|
|
||||||
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||||
|
MethodHandle handle = null;
|
||||||
|
try {
|
||||||
|
handle = lookup.findVirtual(Player.class, "kick", MethodType.methodType(
|
||||||
|
void.class,
|
||||||
|
com.discordsrv.unrelocate.net.kyori.adventure.text.Component.class
|
||||||
|
));
|
||||||
|
} catch (ReflectiveOperationException ignored) {}
|
||||||
|
KICK_COMPONENT_HANDLE = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static Locale getLocale(Player player) {
|
public static Locale getLocale(Player player) {
|
||||||
if (localeMethodExists) {
|
if (LOCALE_METHOD_EXISTS) {
|
||||||
return player.locale();
|
return player.locale();
|
||||||
} else if (getLocaleMethodExists) {
|
} else if (GETLOCALE_METHOD_EXISTS) {
|
||||||
return Locale.forLanguageTag(player.getLocale());
|
return Locale.forLanguageTag(player.getLocale());
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isKickAvailable() {
|
||||||
|
return KICK_COMPONENT_HANDLE != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void kick(Player player, Component reason) {
|
||||||
|
try {
|
||||||
|
KICK_COMPONENT_HANDLE.invokeExact(player, ComponentUtil.toUnrelocated(ComponentUtil.toAPI(reason)));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException("Failed to kick player", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ import com.discordsrv.bukkit.config.manager.BukkitMessagesConfigManager;
|
|||||||
import com.discordsrv.bukkit.console.BukkitConsole;
|
import com.discordsrv.bukkit.console.BukkitConsole;
|
||||||
import com.discordsrv.bukkit.listener.BukkitConnectionListener;
|
import com.discordsrv.bukkit.listener.BukkitConnectionListener;
|
||||||
import com.discordsrv.bukkit.listener.BukkitDeathListener;
|
import com.discordsrv.bukkit.listener.BukkitDeathListener;
|
||||||
import com.discordsrv.bukkit.listener.BukkitRequiredLinkingListener;
|
|
||||||
import com.discordsrv.bukkit.listener.BukkitStatusMessageListener;
|
import com.discordsrv.bukkit.listener.BukkitStatusMessageListener;
|
||||||
import com.discordsrv.bukkit.listener.award.BukkitAwardForwarder;
|
import com.discordsrv.bukkit.listener.award.BukkitAwardForwarder;
|
||||||
import com.discordsrv.bukkit.listener.chat.BukkitChatForwarder;
|
import com.discordsrv.bukkit.listener.chat.BukkitChatForwarder;
|
||||||
@ -70,7 +69,6 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
private final BukkitPlayerProvider playerProvider;
|
private final BukkitPlayerProvider playerProvider;
|
||||||
private final BukkitPluginManager pluginManager;
|
private final BukkitPluginManager pluginManager;
|
||||||
private AbstractBukkitCommandHandler commandHandler;
|
private AbstractBukkitCommandHandler commandHandler;
|
||||||
private final BukkitRequiredLinkingListener requiredLinkingListener;
|
|
||||||
private final BukkitGameCommandExecutionHelper autoCompleteHelper;
|
private final BukkitGameCommandExecutionHelper autoCompleteHelper;
|
||||||
|
|
||||||
private final BukkitConnectionConfigManager connectionConfigManager;
|
private final BukkitConnectionConfigManager connectionConfigManager;
|
||||||
@ -101,7 +99,6 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
|
|
||||||
load();
|
load();
|
||||||
|
|
||||||
this.requiredLinkingListener = new BukkitRequiredLinkingListener(this);
|
|
||||||
this.autoCompleteHelper = new BukkitGameCommandExecutionHelper(this);
|
this.autoCompleteHelper = new BukkitGameCommandExecutionHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +235,6 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
|||||||
protected void disable() {
|
protected void disable() {
|
||||||
super.disable();
|
super.disable();
|
||||||
|
|
||||||
requiredLinkingListener.disable();
|
|
||||||
audiences.close();
|
audiences.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ package com.discordsrv.bukkit.ban;
|
|||||||
|
|
||||||
import com.discordsrv.api.component.MinecraftComponent;
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
import com.discordsrv.api.module.type.PunishmentModule;
|
import com.discordsrv.api.module.type.PunishmentModule;
|
||||||
import com.discordsrv.api.player.DiscordSRVPlayer;
|
|
||||||
import com.discordsrv.api.punishment.Punishment;
|
import com.discordsrv.api.punishment.Punishment;
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
import com.discordsrv.common.bansync.BanSyncModule;
|
import com.discordsrv.common.bansync.BanSyncModule;
|
||||||
@ -126,17 +125,4 @@ public class BukkitBanModule extends AbstractModule<BukkitDiscordSRV> implements
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Void> kickPlayer(@NotNull DiscordSRVPlayer srvPlayer, @NotNull MinecraftComponent message) {
|
|
||||||
Player player = discordSRV.server().getPlayer(srvPlayer.uniqueId());
|
|
||||||
if (player == null) {
|
|
||||||
return CompletableFuture.completedFuture(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return discordSRV.scheduler().executeOnMainThread(
|
|
||||||
player,
|
|
||||||
() -> player.kickPlayer(BukkitComponentSerializer.legacy().serialize(ComponentUtil.fromAPI(message)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,306 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
|
||||||
* Copyright (c) 2016-2024 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.discordsrv.bukkit.listener;
|
|
||||||
|
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
|
||||||
import com.discordsrv.bukkit.config.main.BukkitRequiredLinkingConfig;
|
|
||||||
import com.discordsrv.bukkit.requiredlinking.BukkitRequiredLinkingModule;
|
|
||||||
import com.discordsrv.common.DiscordSRV;
|
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
|
||||||
import com.discordsrv.common.config.main.linking.ServerRequiredLinkingConfig;
|
|
||||||
import com.discordsrv.common.linking.LinkStore;
|
|
||||||
import com.discordsrv.common.player.IPlayer;
|
|
||||||
import com.github.benmanes.caffeine.cache.Cache;
|
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.*;
|
|
||||||
import org.bukkit.event.player.*;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class BukkitRequiredLinkingListener implements Listener {
|
|
||||||
|
|
||||||
private final BukkitDiscordSRV discordSRV;
|
|
||||||
private final Cache<UUID, Boolean> linkCheckRateLimit;
|
|
||||||
|
|
||||||
public BukkitRequiredLinkingListener(BukkitDiscordSRV discordSRV) {
|
|
||||||
this.discordSRV = discordSRV;
|
|
||||||
this.linkCheckRateLimit = discordSRV.caffeineBuilder()
|
|
||||||
.expireAfterWrite(LinkStore.LINKING_CODE_RATE_LIMIT)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
register(PlayerLoginEvent.class, this::handle);
|
|
||||||
register(AsyncPlayerPreLoginEvent.class, this::handle);
|
|
||||||
discordSRV.server().getPluginManager().registerEvents(this, discordSRV.plugin());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T extends Event> void register(Class<T> eventType, BiConsumer<T, EventPriority> eventConsumer) {
|
|
||||||
for (EventPriority priority : EventPriority.values()) {
|
|
||||||
if (priority == EventPriority.MONITOR) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
discordSRV.server().getPluginManager().registerEvent(
|
|
||||||
eventType,
|
|
||||||
this,
|
|
||||||
priority,
|
|
||||||
(listener, event) -> eventConsumer.accept((T) event, priority),
|
|
||||||
discordSRV.plugin(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disable() {
|
|
||||||
HandlerList.unregisterAll(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BukkitRequiredLinkingModule getModule() {
|
|
||||||
int tries = 0;
|
|
||||||
|
|
||||||
BukkitRequiredLinkingModule module;
|
|
||||||
do {
|
|
||||||
module = discordSRV.getModule(BukkitRequiredLinkingModule.class);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
tries++;
|
|
||||||
} while (module == null || tries >= 50);
|
|
||||||
|
|
||||||
return module;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompletableFuture<Component> getBlockReason(UUID playerUUID, String playerName, boolean join) {
|
|
||||||
BukkitRequiredLinkingModule module = getModule();
|
|
||||||
if (module == null) {
|
|
||||||
Component message = ComponentUtil.fromAPI(
|
|
||||||
discordSRV.messagesConfig().minecraft.unableToLinkAtThisTime.textBuilder().build()
|
|
||||||
);
|
|
||||||
return CompletableFuture.completedFuture(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return module.getBlockReason(playerUUID, playerName, join);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Kick
|
|
||||||
//
|
|
||||||
|
|
||||||
private void handle(AsyncPlayerPreLoginEvent event, EventPriority priority) {
|
|
||||||
handle(
|
|
||||||
"AsyncPlayerPreLoginEvent",
|
|
||||||
priority,
|
|
||||||
event.getUniqueId(),
|
|
||||||
event.getName(),
|
|
||||||
() -> event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED ? event.getLoginResult().name() : null,
|
|
||||||
text -> event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, text)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handle(PlayerLoginEvent event, EventPriority priority) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
handle(
|
|
||||||
"PlayerLoginEvent",
|
|
||||||
priority,
|
|
||||||
player.getUniqueId(),
|
|
||||||
player.getName(),
|
|
||||||
() -> event.getResult() != PlayerLoginEvent.Result.ALLOWED ? event.getResult().name() : null,
|
|
||||||
text -> event.disallow(PlayerLoginEvent.Result.KICK_OTHER, text)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handle(
|
|
||||||
String eventType,
|
|
||||||
EventPriority priority,
|
|
||||||
UUID playerUUID,
|
|
||||||
String playerName,
|
|
||||||
Supplier<String> alreadyBlocked,
|
|
||||||
Consumer<String> disallow
|
|
||||||
) {
|
|
||||||
BukkitRequiredLinkingConfig config = discordSRV.config().requiredLinking;
|
|
||||||
if (!config.enabled || config.action != ServerRequiredLinkingConfig.Action.KICK
|
|
||||||
|| !eventType.equals(config.kick.event) || !priority.name().equals(config.kick.priority)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String blockType = alreadyBlocked.get();
|
|
||||||
if (blockType != null) {
|
|
||||||
discordSRV.logger().debug(playerName + " is already blocked for " + eventType + "/" + priority + " (" + blockType + ")");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component kickReason = getBlockReason(playerUUID, playerName, true).join();
|
|
||||||
if (kickReason != null) {
|
|
||||||
disallow.accept(BukkitComponentSerializer.legacy().serialize(kickReason));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Freeze
|
|
||||||
//
|
|
||||||
|
|
||||||
private final Map<UUID, Component> frozen = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private boolean isFrozen(Player player) {
|
|
||||||
return frozen.containsKey(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
|
|
||||||
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discordSRV.isShutdown()) {
|
|
||||||
return;
|
|
||||||
} else if (!discordSRV.isReady()) {
|
|
||||||
try {
|
|
||||||
discordSRV.waitForStatus(DiscordSRV.Status.CONNECTED);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BukkitRequiredLinkingConfig config = discordSRV.config().requiredLinking;
|
|
||||||
if (!config.enabled || config.action != ServerRequiredLinkingConfig.Action.FREEZE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component blockReason = getBlockReason(event.getUniqueId(), event.getName(), false).join();
|
|
||||||
if (blockReason != null) {
|
|
||||||
frozen.put(event.getUniqueId(), blockReason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onLogin(PlayerLoginEvent event) {
|
|
||||||
if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
|
||||||
frozen.remove(event.getPlayer().getUniqueId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onJoin(PlayerJoinEvent event) {
|
|
||||||
UUID uuid = event.getPlayer().getUniqueId();
|
|
||||||
Component blockReason = frozen.get(uuid);
|
|
||||||
if (blockReason == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPlayer player = discordSRV.playerProvider().player(uuid);
|
|
||||||
if (player == null) {
|
|
||||||
throw new IllegalStateException("Player not available: " + uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
player.sendMessage(blockReason);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
|
||||||
public void onPlayerMove(PlayerMoveEvent event) {
|
|
||||||
Component freezeReason = frozen.get(event.getPlayer().getUniqueId());
|
|
||||||
if (freezeReason == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Location from = event.getFrom(), to = event.getTo();
|
|
||||||
if (from.getWorld().getName().equals(to.getWorld().getName())
|
|
||||||
&& from.getBlockX() == to.getBlockX()
|
|
||||||
&& from.getBlockZ() == to.getBlockZ()
|
|
||||||
&& from.getBlockY() >= to.getBlockY()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.setTo(
|
|
||||||
new Location(
|
|
||||||
from.getWorld(),
|
|
||||||
from.getBlockX() + 0.5,
|
|
||||||
from.getBlockY(),
|
|
||||||
from.getBlockZ() + 0.5,
|
|
||||||
from.getYaw(),
|
|
||||||
from.getPitch()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
|
||||||
player.sendMessage(freezeReason);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
|
||||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
|
||||||
Component freezeReason = frozen.get(event.getPlayer().getUniqueId());
|
|
||||||
if (freezeReason == null) {
|
|
||||||
event.getRecipients().removeIf(this::isFrozen);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
|
|
||||||
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
|
||||||
player.sendMessage(freezeReason);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
|
||||||
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
|
||||||
if (!isFrozen(event.getPlayer())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
|
|
||||||
String message = event.getMessage();
|
|
||||||
if (message.startsWith("/")) message = message.substring(1);
|
|
||||||
if (message.equals("discord link") || message.equals("link")) {
|
|
||||||
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
|
||||||
|
|
||||||
if (linkCheckRateLimit.getIfPresent(player.uniqueId()) != null) {
|
|
||||||
player.sendMessage(discordSRV.messagesConfig(player).pleaseWaitBeforeRunningThatCommandAgain.asComponent());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
linkCheckRateLimit.put(player.uniqueId(), true);
|
|
||||||
|
|
||||||
player.sendMessage(Component.text("Checking..."));
|
|
||||||
|
|
||||||
UUID uuid = player.uniqueId();
|
|
||||||
getBlockReason(uuid, player.username(), false).whenComplete((reason, t) -> {
|
|
||||||
if (t != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reason == null) {
|
|
||||||
frozen.remove(uuid);
|
|
||||||
} else {
|
|
||||||
frozen.put(uuid, reason);
|
|
||||||
player.sendMessage(reason);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -26,12 +26,14 @@ import com.discordsrv.common.component.util.ComponentUtil;
|
|||||||
import com.discordsrv.common.player.IPlayer;
|
import com.discordsrv.common.player.IPlayer;
|
||||||
import com.discordsrv.common.player.provider.model.SkinInfo;
|
import com.discordsrv.common.player.provider.model.SkinInfo;
|
||||||
import net.kyori.adventure.identity.Identity;
|
import net.kyori.adventure.identity.Identity;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class BukkitPlayer extends BukkitCommandSender implements IPlayer {
|
public class BukkitPlayer extends BukkitCommandSender implements IPlayer {
|
||||||
|
|
||||||
@ -64,6 +66,17 @@ public class BukkitPlayer extends BukkitCommandSender implements IPlayer {
|
|||||||
return player.getName();
|
return player.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> kick(Component component) {
|
||||||
|
return discordSRV.scheduler().executeOnMainThread(player, () -> {
|
||||||
|
if (PaperPlayer.isKickAvailable()) {
|
||||||
|
PaperPlayer.kick(player, component);
|
||||||
|
} else {
|
||||||
|
player.kickPlayer(BukkitComponentSerializer.legacy().serialize(component));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable SkinInfo skinInfo() {
|
public @Nullable SkinInfo skinInfo() {
|
||||||
return SpigotPlayer.getSkinInfo(player);
|
return SpigotPlayer.getSkinInfo(player);
|
||||||
|
@ -20,14 +20,35 @@ package com.discordsrv.bukkit.requiredlinking;
|
|||||||
|
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
import com.discordsrv.bukkit.config.main.BukkitRequiredLinkingConfig;
|
import com.discordsrv.bukkit.config.main.BukkitRequiredLinkingConfig;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.config.main.linking.ServerRequiredLinkingConfig;
|
||||||
|
import com.discordsrv.common.linking.LinkStore;
|
||||||
import com.discordsrv.common.linking.requirelinking.ServerRequireLinkingModule;
|
import com.discordsrv.common.linking.requirelinking.ServerRequireLinkingModule;
|
||||||
import com.discordsrv.common.player.IPlayer;
|
import com.discordsrv.common.player.IPlayer;
|
||||||
import org.bukkit.event.Listener;
|
import com.github.benmanes.caffeine.cache.Cache;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.*;
|
||||||
|
import org.bukkit.event.player.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class BukkitRequiredLinkingModule extends ServerRequireLinkingModule<BukkitDiscordSRV> implements Listener {
|
public class BukkitRequiredLinkingModule extends ServerRequireLinkingModule<BukkitDiscordSRV> implements Listener {
|
||||||
|
|
||||||
|
private final Cache<UUID, Boolean> linkCheckRateLimit;
|
||||||
|
|
||||||
public BukkitRequiredLinkingModule(BukkitDiscordSRV discordSRV) {
|
public BukkitRequiredLinkingModule(BukkitDiscordSRV discordSRV) {
|
||||||
super(discordSRV);
|
super(discordSRV);
|
||||||
|
this.linkCheckRateLimit = discordSRV.caffeineBuilder()
|
||||||
|
.expireAfterWrite(LinkStore.LINKING_CODE_RATE_LIMIT)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -35,12 +56,254 @@ public class BukkitRequiredLinkingModule extends ServerRequireLinkingModule<Bukk
|
|||||||
return discordSRV.config().requiredLinking;
|
return discordSRV.config().requiredLinking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
super.enable();
|
||||||
|
|
||||||
|
register(PlayerLoginEvent.class, this::handle);
|
||||||
|
register(AsyncPlayerPreLoginEvent.class, this::handle);
|
||||||
|
discordSRV.server().getPluginManager().registerEvents(this, discordSRV.plugin());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disable() {
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T extends Event> void register(Class<T> eventType, BiConsumer<T, EventPriority> eventConsumer) {
|
||||||
|
for (EventPriority priority : EventPriority.values()) {
|
||||||
|
if (priority == EventPriority.MONITOR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
discordSRV.server().getPluginManager().registerEvent(
|
||||||
|
eventType,
|
||||||
|
this,
|
||||||
|
priority,
|
||||||
|
(listener, event) -> eventConsumer.accept((T) event, priority),
|
||||||
|
discordSRV.plugin(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recheck(IPlayer player) {
|
public void recheck(IPlayer player) {
|
||||||
getBlockReason(player.uniqueId(), player.username(), false).whenComplete((component, throwable) -> {
|
getBlockReason(player.uniqueId(), player.username(), false).whenComplete((component, throwable) -> {
|
||||||
if (component != null) {
|
if (component != null) {
|
||||||
// TODO: handle
|
switch (action()) {
|
||||||
|
case KICK:
|
||||||
|
player.kick(component);
|
||||||
|
break;
|
||||||
|
case FREEZE:
|
||||||
|
freeze(player, component);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (action() == ServerRequiredLinkingConfig.Action.FREEZE) {
|
||||||
|
frozen.remove(player.uniqueId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerRequiredLinkingConfig.Action action() {
|
||||||
|
return config().action;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Kick
|
||||||
|
//
|
||||||
|
|
||||||
|
private void handle(AsyncPlayerPreLoginEvent event, EventPriority priority) {
|
||||||
|
handle(
|
||||||
|
"AsyncPlayerPreLoginEvent",
|
||||||
|
priority,
|
||||||
|
event.getUniqueId(),
|
||||||
|
event.getName(),
|
||||||
|
() -> event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED ? event.getLoginResult().name() : null,
|
||||||
|
text -> event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, text)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(PlayerLoginEvent event, EventPriority priority) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
handle(
|
||||||
|
"PlayerLoginEvent",
|
||||||
|
priority,
|
||||||
|
player.getUniqueId(),
|
||||||
|
player.getName(),
|
||||||
|
() -> event.getResult() != PlayerLoginEvent.Result.ALLOWED ? event.getResult().name() : null,
|
||||||
|
text -> event.disallow(PlayerLoginEvent.Result.KICK_OTHER, text)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(
|
||||||
|
String eventType,
|
||||||
|
EventPriority priority,
|
||||||
|
UUID playerUUID,
|
||||||
|
String playerName,
|
||||||
|
Supplier<String> alreadyBlocked,
|
||||||
|
Consumer<String> disallow
|
||||||
|
) {
|
||||||
|
BukkitRequiredLinkingConfig config = config();
|
||||||
|
if (!config.enabled || config.action != ServerRequiredLinkingConfig.Action.KICK
|
||||||
|
|| !eventType.equals(config.kick.event) || !priority.name().equals(config.kick.priority)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String blockType = alreadyBlocked.get();
|
||||||
|
if (blockType != null) {
|
||||||
|
discordSRV.logger().debug(playerName + " is already blocked for " + eventType + "/" + priority + " (" + blockType + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component kickReason = getBlockReason(playerUUID, playerName, true).join();
|
||||||
|
if (kickReason != null) {
|
||||||
|
disallow.accept(BukkitComponentSerializer.legacy().serialize(kickReason));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Freeze
|
||||||
|
//
|
||||||
|
|
||||||
|
private final Map<UUID, Component> frozen = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private boolean isFrozen(Player player) {
|
||||||
|
return frozen.containsKey(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void freeze(IPlayer player, Component blockReason) {
|
||||||
|
frozen.put(player.uniqueId(), blockReason);
|
||||||
|
player.sendMessage(blockReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
|
||||||
|
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (discordSRV.isShutdown()) {
|
||||||
|
return;
|
||||||
|
} else if (!discordSRV.isReady()) {
|
||||||
|
try {
|
||||||
|
discordSRV.waitForStatus(DiscordSRV.Status.CONNECTED);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BukkitRequiredLinkingConfig config = config();
|
||||||
|
if (!config.enabled || config.action != ServerRequiredLinkingConfig.Action.FREEZE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component blockReason = getBlockReason(event.getUniqueId(), event.getName(), false).join();
|
||||||
|
if (blockReason != null) {
|
||||||
|
frozen.put(event.getUniqueId(), blockReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onLogin(PlayerLoginEvent event) {
|
||||||
|
if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
||||||
|
frozen.remove(event.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onJoin(PlayerJoinEvent event) {
|
||||||
|
UUID uuid = event.getPlayer().getUniqueId();
|
||||||
|
Component blockReason = frozen.get(uuid);
|
||||||
|
if (blockReason == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(uuid);
|
||||||
|
if (player == null) {
|
||||||
|
throw new IllegalStateException("Player not available: " + uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendMessage(blockReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
Component freezeReason = frozen.get(event.getPlayer().getUniqueId());
|
||||||
|
if (freezeReason == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Location from = event.getFrom(), to = event.getTo();
|
||||||
|
if (from.getWorld().getName().equals(to.getWorld().getName())
|
||||||
|
&& from.getBlockX() == to.getBlockX()
|
||||||
|
&& from.getBlockZ() == to.getBlockZ()
|
||||||
|
&& from.getBlockY() >= to.getBlockY()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setTo(
|
||||||
|
new Location(
|
||||||
|
from.getWorld(),
|
||||||
|
from.getBlockX() + 0.5,
|
||||||
|
from.getBlockY(),
|
||||||
|
from.getBlockZ() + 0.5,
|
||||||
|
from.getYaw(),
|
||||||
|
from.getPitch()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
player.sendMessage(freezeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||||
|
Component freezeReason = frozen.get(event.getPlayer().getUniqueId());
|
||||||
|
if (freezeReason == null) {
|
||||||
|
event.getRecipients().removeIf(this::isFrozen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
player.sendMessage(freezeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
||||||
|
if (!isFrozen(event.getPlayer())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
String message = event.getMessage();
|
||||||
|
if (message.startsWith("/")) message = message.substring(1);
|
||||||
|
if (message.equals("discord link") || message.equals("link")) {
|
||||||
|
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
|
||||||
|
if (linkCheckRateLimit.getIfPresent(player.uniqueId()) != null) {
|
||||||
|
player.sendMessage(discordSRV.messagesConfig(player).pleaseWaitBeforeRunningThatCommandAgain.asComponent());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
linkCheckRateLimit.put(player.uniqueId(), true);
|
||||||
|
|
||||||
|
player.sendMessage(Component.text("Checking..."));
|
||||||
|
|
||||||
|
UUID uuid = player.uniqueId();
|
||||||
|
getBlockReason(uuid, player.username(), false).whenComplete((reason, t) -> {
|
||||||
|
if (t != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reason == null) {
|
||||||
|
frozen.remove(uuid);
|
||||||
|
} else {
|
||||||
|
freeze(player, reason);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ public class BanSyncModule extends AbstractSyncModule<DiscordSRV, BanSyncConfig,
|
|||||||
.applyPlaceholderService()
|
.applyPlaceholderService()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return bans.kickPlayer(player, kickMessage);
|
return player.kick(ComponentUtil.fromAPI(kickMessage));
|
||||||
})
|
})
|
||||||
.thenApply(v -> GenericSyncResults.ADD_GAME);
|
.thenApply(v -> GenericSyncResults.ADD_GAME);
|
||||||
} else {
|
} else {
|
||||||
|
@ -90,7 +90,7 @@ public final class ComponentUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MinecraftComponent fromUnrelocated(@NotNull Object unrelocatedAdventure) {
|
public static MinecraftComponent fromUnrelocated(@NotNull com.discordsrv.unrelocate.net.kyori.adventure.text.Component unrelocatedAdventure) {
|
||||||
MinecraftComponentImpl component = MinecraftComponentImpl.empty();
|
MinecraftComponentImpl component = MinecraftComponentImpl.empty();
|
||||||
MinecraftComponent.Adapter<Object> adapter = component.unrelocatedAdapter();
|
MinecraftComponent.Adapter<Object> adapter = component.unrelocatedAdapter();
|
||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
@ -100,6 +100,14 @@ public final class ComponentUtil {
|
|||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static com.discordsrv.unrelocate.net.kyori.adventure.text.Component toUnrelocated(MinecraftComponent component) {
|
||||||
|
MinecraftComponent.Adapter<Object> adapter = component.unrelocatedAdapter();
|
||||||
|
if (adapter == null) {
|
||||||
|
throw new IllegalStateException("Could not get unrelocated adventure gson serializer");
|
||||||
|
}
|
||||||
|
return (com.discordsrv.unrelocate.net.kyori.adventure.text.Component) adapter.getComponent();
|
||||||
|
}
|
||||||
|
|
||||||
public static Component join(@NotNull Component delimiter, @NotNull Collection<? extends ComponentLike> components) {
|
public static Component join(@NotNull Component delimiter, @NotNull Collection<? extends ComponentLike> components) {
|
||||||
return join(delimiter, components.toArray(new ComponentLike[0]));
|
return join(delimiter, components.toArray(new ComponentLike[0]));
|
||||||
}
|
}
|
||||||
|
@ -154,9 +154,7 @@ public abstract class RequiredLinkingModule<T extends DiscordSRV> extends Abstra
|
|||||||
public <RT> void stateChanged(Someone someone, RequirementType<RT> requirementType, RT value, boolean newState) {
|
public <RT> void stateChanged(Someone someone, RequirementType<RT> requirementType, RT value, boolean newState) {
|
||||||
for (ParsedRequirements activeRequirement : getAllActiveRequirements()) {
|
for (ParsedRequirements activeRequirement : getAllActiveRequirements()) {
|
||||||
for (Requirement<?> requirement : activeRequirement.usedRequirements()) {
|
for (Requirement<?> requirement : activeRequirement.usedRequirements()) {
|
||||||
if (requirement.type() != requirementType
|
if (requirement.type() != requirementType || !Objects.equals(requirement.value(), value)) {
|
||||||
|| !Objects.equals(requirement.value(), value)
|
|
||||||
|| newState == requirement.negated()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +256,7 @@ public abstract class RequiredLinkingModule<T extends DiscordSRV> extends Abstra
|
|||||||
}
|
}
|
||||||
|
|
||||||
// None of the futures passed: additional requirements not met
|
// None of the futures passed: additional requirements not met
|
||||||
return Component.text("You did not pass additionalRequirements");
|
return Component.text("You did not pass requirements");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public class DiscordRoleRequirementType extends LongRequirementType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDiscordMemberRoleAdd(AbstractDiscordMemberRoleChangeEvent<?> event) {
|
public void onDiscordMemberRoleChange(AbstractDiscordMemberRoleChangeEvent<?> event) {
|
||||||
boolean add = event instanceof DiscordMemberRoleAddEvent;
|
boolean add = event instanceof DiscordMemberRoleAddEvent;
|
||||||
|
|
||||||
Someone someone = Someone.of(event.getMember().getUser().getId());
|
Someone someone = Someone.of(event.getMember().getUser().getId());
|
||||||
|
@ -34,6 +34,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@PlaceholderPrefix("player_")
|
@PlaceholderPrefix("player_")
|
||||||
public interface IPlayer extends DiscordSRVPlayer, IOfflinePlayer, ICommandSender {
|
public interface IPlayer extends DiscordSRVPlayer, IOfflinePlayer, ICommandSender {
|
||||||
@ -66,6 +67,8 @@ public interface IPlayer extends DiscordSRVPlayer, IOfflinePlayer, ICommandSende
|
|||||||
return identity().uuid();
|
return identity().uuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompletableFuture<Void> kick(Component component);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Placeholder("display_name")
|
@Placeholder("display_name")
|
||||||
Component displayName();
|
Component displayName();
|
||||||
|
@ -174,8 +174,9 @@ public abstract class SQLStorage implements Storage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the uuid for the code
|
// Get the uuid for the code
|
||||||
try (Statement statement = connection.createStatement()) {
|
try (PreparedStatement statement = connection.prepareStatement("select PLAYERUUID from " + tablePrefix() + LINKING_CODES_TABLE_NAME + " where CODE = ? LIMIT 1;")) {
|
||||||
try (ResultSet resultSet = statement.executeQuery("select PLAYERUUID from " + tablePrefix() + LINKING_CODES_TABLE_NAME + " LIMIT 1;")) {
|
statement.setString(1, code);
|
||||||
|
try (ResultSet resultSet = statement.executeQuery()) {
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
return UUID.fromString(resultSet.getString("PLAYERUUID"));
|
return UUID.fromString(resultSet.getString("PLAYERUUID"));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user