mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-28 12:56:17 +01:00
Continue work on storage linking
This commit is contained in:
parent
a948df6070
commit
d6c1d22b64
@ -33,6 +33,8 @@ import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public abstract class AbstractInteractionEvent<T extends GenericInteractionCreateEvent> extends AbstractDiscordEvent<T> {
|
||||
|
||||
protected final ComponentIdentifier identifier;
|
||||
@ -58,6 +60,16 @@ public abstract class AbstractInteractionEvent<T extends GenericInteractionCreat
|
||||
return this.identifier.equals(identifier);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Locale getGuildLocale() {
|
||||
return jdaEvent.getGuildLocale().toLocale();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Locale getUserLocale() {
|
||||
return jdaEvent.getUserLocale().toLocale();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DiscordUser getUser() {
|
||||
return user;
|
||||
|
@ -42,7 +42,7 @@ import com.discordsrv.bukkit.scheduler.FoliaScheduler;
|
||||
import com.discordsrv.bukkit.scheduler.IBukkitScheduler;
|
||||
import com.discordsrv.common.AbstractDiscordSRV;
|
||||
import com.discordsrv.common.abstraction.plugin.PluginManager;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.config.configurate.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MainConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MessagesConfigManager;
|
||||
|
@ -20,7 +20,7 @@ package com.discordsrv.bukkit.command.game;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.bukkit.command.PaperCommandMap;
|
||||
import com.discordsrv.common.command.game.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutionHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.bukkit.command.game.handler;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.command.game.handler.BasicCommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.BasicCommandHandler;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -20,9 +20,9 @@ package com.discordsrv.bukkit.command.game.handler;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.bukkit.command.game.sender.BukkitCommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import org.bukkit.Server;
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.bukkit.command.game.handler;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
|
@ -19,8 +19,8 @@
|
||||
package com.discordsrv.bukkit.command.game.handler;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.handler.util.BrigadierUtil;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.util.BrigadierUtil;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import me.lucko.commodore.Commodore;
|
||||
import me.lucko.commodore.CommodoreProvider;
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.bukkit.command.game.sender;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -21,7 +21,7 @@ package com.discordsrv.bukkit.console;
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.bukkit.command.game.sender.BukkitCommandSender;
|
||||
import com.discordsrv.bukkit.console.executor.BukkitCommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.discordsrv.common.core.logging.backend.LoggingBackend;
|
||||
import com.discordsrv.common.core.logging.backend.impl.JavaLoggerImpl;
|
||||
|
@ -19,8 +19,8 @@
|
||||
package com.discordsrv.bukkit.console.executor;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.util.ComponentUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Server;
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.bukkit.console.executor;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class CommandSenderExecutor implements CommandExecutor {
|
||||
|
@ -24,7 +24,7 @@ import com.discordsrv.bungee.player.BungeePlayerProvider;
|
||||
import com.discordsrv.bungee.plugin.BungeePluginManager;
|
||||
import com.discordsrv.common.AbstractDiscordSRV;
|
||||
import com.discordsrv.common.abstraction.plugin.PluginManager;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.config.configurate.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MainConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MessagesConfigManager;
|
||||
|
@ -20,9 +20,9 @@ package com.discordsrv.bungee.command.game.handler;
|
||||
|
||||
import com.discordsrv.bungee.BungeeDiscordSRV;
|
||||
import com.discordsrv.bungee.command.game.sender.BungeeCommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.handler.BasicCommandHandler;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.BasicCommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.bungee.command.game.sender;
|
||||
|
||||
import com.discordsrv.bungee.BungeeDiscordSRV;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -21,7 +21,7 @@ package com.discordsrv.bungee.console;
|
||||
import com.discordsrv.bungee.BungeeDiscordSRV;
|
||||
import com.discordsrv.bungee.command.game.sender.BungeeCommandSender;
|
||||
import com.discordsrv.bungee.console.executor.BungeeCommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.core.logging.backend.LoggingBackend;
|
||||
import com.discordsrv.common.core.logging.backend.impl.JavaLoggerImpl;
|
||||
import com.discordsrv.common.feature.console.Console;
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.bungee.console.executor;
|
||||
|
||||
import com.discordsrv.bungee.BungeeDiscordSRV;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
|
||||
|
@ -19,8 +19,8 @@
|
||||
package com.discordsrv.bungee.console.executor;
|
||||
|
||||
import com.discordsrv.bungee.BungeeDiscordSRV;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
@ -25,9 +25,9 @@ import com.discordsrv.common.abstraction.bootstrap.IBootstrap;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.abstraction.player.provider.AbstractPlayerProvider;
|
||||
import com.discordsrv.common.abstraction.plugin.PluginManager;
|
||||
import com.discordsrv.common.command.game.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.config.configurate.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MainConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MessagesConfigManager;
|
||||
|
@ -24,7 +24,7 @@ import com.discordsrv.api.placeholder.annotation.PlaceholderPrefix;
|
||||
import com.discordsrv.api.placeholder.format.FormattedText;
|
||||
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.config.main.AvatarProviderConfig;
|
||||
import com.discordsrv.common.feature.profile.Profile;
|
||||
import com.discordsrv.common.util.ComponentUtil;
|
||||
|
@ -22,10 +22,10 @@ import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.events.discord.interaction.command.DiscordChatInputInteractionEvent;
|
||||
import com.discordsrv.api.events.discord.interaction.command.DiscordCommandAutoCompleteInteractionEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -19,6 +19,7 @@
|
||||
package com.discordsrv.common.command.combined.abstraction;
|
||||
|
||||
import com.discordsrv.api.component.MinecraftComponent;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.common.config.messages.MessagesConfig;
|
||||
import com.discordsrv.common.util.ComponentUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@ -47,11 +48,11 @@ public interface CommandExecution {
|
||||
|
||||
void send(Collection<Text> texts, Collection<Text> extra);
|
||||
|
||||
default void send(MinecraftComponent minecraft, String discord) {
|
||||
default void send(MinecraftComponent minecraft, SendableDiscordMessage discord) {
|
||||
send(ComponentUtil.fromAPI(minecraft), discord);
|
||||
}
|
||||
|
||||
void send(Component minecraft, String discord);
|
||||
void send(Component minecraft, SendableDiscordMessage discord);
|
||||
|
||||
void runAsync(Runnable runnable);
|
||||
}
|
||||
|
@ -18,16 +18,19 @@
|
||||
|
||||
package com.discordsrv.common.command.combined.abstraction;
|
||||
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.api.events.discord.interaction.AbstractInteractionEvent;
|
||||
import com.discordsrv.api.events.discord.interaction.command.DiscordChatInputInteractionEvent;
|
||||
import com.discordsrv.api.events.discord.interaction.command.DiscordCommandAutoCompleteInteractionEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.config.messages.MessagesConfig;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
|
||||
import com.discordsrv.common.discord.api.entity.message.util.SendableDiscordMessageUtil;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
|
||||
import net.dv8tion.jda.api.interactions.commands.CommandInteractionPayload;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -40,8 +43,8 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class DiscordCommandExecution implements CommandExecution {
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
private final AbstractInteractionEvent<?> event;
|
||||
|
||||
private final GenericInteractionCreateEvent createEvent;
|
||||
private final CommandInteractionPayload interactionPayload;
|
||||
private final IReplyCallback replyCallback;
|
||||
|
||||
@ -50,21 +53,25 @@ public class DiscordCommandExecution implements CommandExecution {
|
||||
|
||||
public DiscordCommandExecution(DiscordSRV discordSRV, DiscordChatInputInteractionEvent event) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.createEvent = event.asJDA();
|
||||
this.event = event;
|
||||
this.interactionPayload = event.asJDA();
|
||||
this.replyCallback = event.asJDA();
|
||||
}
|
||||
|
||||
public DiscordCommandExecution(DiscordSRV discordSRV, DiscordCommandAutoCompleteInteractionEvent event) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.createEvent = event.asJDA();
|
||||
this.event = event;
|
||||
this.interactionPayload = event.asJDA();
|
||||
this.replyCallback = null;
|
||||
}
|
||||
|
||||
public DiscordUser getUser() {
|
||||
return event.getUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale locale() {
|
||||
return createEvent.getUserLocale().toLocale();
|
||||
return event.getUserLocale();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -101,25 +108,26 @@ public class DiscordCommandExecution implements CommandExecution {
|
||||
verifyStyle(builder, formats, null);
|
||||
}
|
||||
|
||||
sendResponse(builder.toString());
|
||||
sendResponse(SendableDiscordMessage.builder().setContent(builder.toString()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Component minecraft, String discord) {
|
||||
public void send(Component minecraft, SendableDiscordMessage discord) {
|
||||
sendResponse(discord);
|
||||
}
|
||||
|
||||
private void sendResponse(String content) {
|
||||
private void sendResponse(SendableDiscordMessage message) {
|
||||
if (replyCallback == null) {
|
||||
throw new IllegalStateException("May not be used on auto completions");
|
||||
}
|
||||
|
||||
InteractionHook interactionHook = hook.get();
|
||||
boolean ephemeral = isEphemeral.get();
|
||||
MessageCreateData data = SendableDiscordMessageUtil.toJDASend(message);
|
||||
if (interactionHook != null) {
|
||||
interactionHook.sendMessage(content).setEphemeral(ephemeral).queue();
|
||||
interactionHook.sendMessage(data).setEphemeral(ephemeral).queue();
|
||||
} else {
|
||||
replyCallback.reply(content).setEphemeral(ephemeral).queue();
|
||||
replyCallback.reply(data).setEphemeral(ephemeral).queue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,8 +158,4 @@ public class DiscordCommandExecution implements CommandExecution {
|
||||
discordSRV.scheduler().run(runnable);
|
||||
});
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return createEvent.getUser();
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,11 @@
|
||||
|
||||
package com.discordsrv.common.command.combined.abstraction;
|
||||
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.config.messages.MessagesConfig;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
@ -85,7 +86,7 @@ public class GameCommandExecution implements CommandExecution {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Component minecraft, String discord) {
|
||||
public void send(Component minecraft, SendableDiscordMessage discord) {
|
||||
sender.sendMessage(minecraft);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.Text;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.core.paste.Paste;
|
||||
import com.discordsrv.common.core.paste.PasteService;
|
||||
import com.discordsrv.common.core.paste.service.AESEncryptedPasteService;
|
||||
|
@ -22,52 +22,51 @@ import com.discordsrv.api.discord.entity.interaction.command.CommandOption;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.GameCommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.Text;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.config.messages.MessagesConfig;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.commands.subcommand.LinkInitGameCommand;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.discordsrv.common.feature.linking.LinkProvider;
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
import com.discordsrv.common.util.CommandUtil;
|
||||
import com.discordsrv.common.util.ComponentUtil;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class LinkInitCommand extends CombinedCommand {
|
||||
public class LinkOtherCommand extends CombinedCommand {
|
||||
|
||||
private static LinkInitCommand INSTANCE;
|
||||
private static LinkOtherCommand INSTANCE;
|
||||
private static GameCommand GAME;
|
||||
private static DiscordCommand DISCORD;
|
||||
|
||||
private static LinkInitCommand getInstance(DiscordSRV discordSRV) {
|
||||
return INSTANCE != null ? INSTANCE : (INSTANCE = new LinkInitCommand(discordSRV));
|
||||
private static LinkOtherCommand getInstance(DiscordSRV discordSRV) {
|
||||
return INSTANCE != null ? INSTANCE : (INSTANCE = new LinkOtherCommand(discordSRV));
|
||||
}
|
||||
|
||||
public static GameCommand getGame(DiscordSRV discordSRV) {
|
||||
if (GAME == null) {
|
||||
LinkInitCommand command = getInstance(discordSRV);
|
||||
GameCommandExecutor initCommand = LinkInitGameCommand.getExecutor(discordSRV);
|
||||
LinkOtherCommand otherCommand = getInstance(discordSRV);
|
||||
|
||||
GAME = GameCommand.literal("link")
|
||||
.then(
|
||||
GameCommand.stringWord("player")
|
||||
.then(
|
||||
GameCommand.stringWord("user")
|
||||
.requiredPermission(Permission.COMMAND_LINK_OTHER)
|
||||
.executor(command)
|
||||
.executor(otherCommand)
|
||||
)
|
||||
)
|
||||
.requiredPermission(Permission.COMMAND_LINK)
|
||||
.executor(command);
|
||||
.executor(initCommand);
|
||||
}
|
||||
|
||||
return GAME;
|
||||
@ -75,8 +74,10 @@ public class LinkInitCommand extends CombinedCommand {
|
||||
|
||||
public static DiscordCommand getDiscord(DiscordSRV discordSRV) {
|
||||
if (DISCORD == null) {
|
||||
LinkInitCommand command = getInstance(discordSRV);
|
||||
DISCORD = DiscordCommand.chatInput(ComponentIdentifier.of("DiscordSRV", "link"), "link", "Link players")
|
||||
LinkOtherCommand command = getInstance(discordSRV);
|
||||
ComponentIdentifier identifier = ComponentIdentifier.of("DiscordSRV", "link-other");
|
||||
|
||||
DISCORD = DiscordCommand.chatInput(identifier, "link", "Link players")
|
||||
.addOption(
|
||||
CommandOption.builder(CommandOption.Type.USER, "user", "The user to link")
|
||||
.setRequired(true)
|
||||
@ -97,45 +98,31 @@ public class LinkInitCommand extends CombinedCommand {
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
private final Logger logger;
|
||||
private final Cache<UUID, Boolean> linkCheckRateLimit;
|
||||
|
||||
public LinkInitCommand(DiscordSRV discordSRV) {
|
||||
public LinkOtherCommand(DiscordSRV discordSRV) {
|
||||
super(discordSRV);
|
||||
this.discordSRV = discordSRV;
|
||||
this.logger = new NamedLogger(discordSRV, "LINK_COMMAND");
|
||||
this.linkCheckRateLimit = discordSRV.caffeineBuilder()
|
||||
.expireAfterWrite(LinkStore.LINKING_CODE_RATE_LIMIT)
|
||||
.build();
|
||||
this.logger = new NamedLogger(discordSRV, "LINK_OTHER_COMMAND");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandExecution execution) {
|
||||
String playerArgument = execution.getArgument("player");
|
||||
String userArgument = execution.getArgument("user");
|
||||
if (execution instanceof GameCommandExecution) {
|
||||
ICommandSender sender = ((GameCommandExecution) execution).getSender();
|
||||
|
||||
if (StringUtils.isEmpty(playerArgument)) {
|
||||
if (sender instanceof IPlayer) {
|
||||
startLinking((IPlayer) sender, ((GameCommandExecution) execution).getLabel());
|
||||
} else {
|
||||
sender.sendMessage(discordSRV.messagesConfig(sender).pleaseSpecifyPlayerAndUserToLink.asComponent());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sender.hasPermission(Permission.COMMAND_LINK_OTHER)) {
|
||||
sender.sendMessage(discordSRV.messagesConfig(sender).noPermission.asComponent());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LinkProvider linkProvider = discordSRV.linkProvider();
|
||||
if (!(linkProvider instanceof LinkStore)) {
|
||||
execution.send(new Text("Cannot create links using this link provider").withGameColor(NamedTextColor.DARK_RED));
|
||||
return;
|
||||
}
|
||||
|
||||
String playerArgument = execution.getArgument("player");
|
||||
String userArgument = execution.getArgument("user");
|
||||
if (execution instanceof GameCommandExecution) {
|
||||
ICommandSender sender = ((GameCommandExecution) execution).getSender();
|
||||
if (!sender.hasPermission(Permission.COMMAND_LINK_OTHER)) {
|
||||
sender.sendMessage(discordSRV.messagesConfig(sender).noPermission.asComponent());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CompletableFuture<UUID> playerUUIDFuture = CommandUtil.lookupPlayer(discordSRV, logger, execution, false, playerArgument, null);
|
||||
CompletableFuture<Long> userIdFuture = CommandUtil.lookupUser(discordSRV, logger, execution, false, userArgument, null);
|
||||
|
||||
@ -156,7 +143,6 @@ public class LinkInitCommand extends CombinedCommand {
|
||||
return;
|
||||
}
|
||||
if (linkedUser.isPresent()) {
|
||||
execution.messages().playerAlreadyLinked3rd(execution);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -167,7 +153,6 @@ public class LinkInitCommand extends CombinedCommand {
|
||||
return;
|
||||
}
|
||||
if (linkedPlayer.isPresent()) {
|
||||
execution.messages().userAlreadyLinked3rd(execution);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -176,7 +161,7 @@ public class LinkInitCommand extends CombinedCommand {
|
||||
logger.error("Failed to create link", t3);
|
||||
execution.send(
|
||||
execution.messages().minecraft.unableToLinkAtThisTime.asComponent(),
|
||||
execution.messages().discord.unableToCheckLinkingStatus
|
||||
execution.messages().discord.unableToCheckLinkingStatus.get()
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -187,43 +172,4 @@ public class LinkInitCommand extends CombinedCommand {
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
private void startLinking(IPlayer player, String label) {
|
||||
MessagesConfig.Minecraft messages = discordSRV.messagesConfig(player);
|
||||
|
||||
LinkProvider linkProvider = discordSRV.linkProvider();
|
||||
if (linkProvider.getCachedUserId(player.uniqueId()).isPresent()) {
|
||||
player.sendMessage(messages.alreadyLinked1st.asComponent());
|
||||
return;
|
||||
}
|
||||
|
||||
if (linkCheckRateLimit.getIfPresent(player.uniqueId()) != null) {
|
||||
player.sendMessage(messages.pleaseWaitBeforeRunningThatCommandAgain.asComponent());
|
||||
return;
|
||||
}
|
||||
linkCheckRateLimit.put(player.uniqueId(), true);
|
||||
|
||||
player.sendMessage(discordSRV.messagesConfig(player).checkingLinkStatus.asComponent());
|
||||
linkProvider.queryUserId(player.uniqueId(), true).whenComplete((userId, t1) -> {
|
||||
if (t1 != null) {
|
||||
logger.error("Failed to check linking status", t1);
|
||||
player.sendMessage(messages.unableToLinkAtThisTime.asComponent());
|
||||
return;
|
||||
}
|
||||
if (userId.isPresent()) {
|
||||
player.sendMessage(messages.nowLinked1st.asComponent());
|
||||
return;
|
||||
}
|
||||
|
||||
linkProvider.getLinkingInstructions(player, label).whenComplete((comp, t2) -> {
|
||||
if (t2 != null) {
|
||||
logger.error("Failed to link account", t2);
|
||||
player.sendMessage(messages.unableToLinkAtThisTime.asComponent());
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendMessage(ComponentUtil.fromAPI(comp));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifi
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
@ -129,7 +129,7 @@ public class LinkedCommand extends CombinedCommand {
|
||||
logger.error("Failed to check linking status during linked command", t);
|
||||
execution.send(
|
||||
execution.messages().minecraft.unableToCheckLinkingStatus.asComponent(),
|
||||
execution.messages().discord.unableToCheckLinkingStatus
|
||||
execution.messages().discord.unableToCheckLinkingStatus.get()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.GameCommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.Text;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.feature.groupsync.GroupSyncModule;
|
||||
import com.discordsrv.common.helper.Someone;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
|
@ -25,7 +25,7 @@ import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.Text;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.discordsrv.common.feature.linking.LinkProvider;
|
||||
@ -157,7 +157,7 @@ public class UnlinkCommand extends CombinedCommand {
|
||||
logger.error("Failed to remove link", t2);
|
||||
execution.send(
|
||||
execution.messages().minecraft.unableToLinkAtThisTime.asComponent(),
|
||||
execution.messages().discord.unableToCheckLinkingStatus
|
||||
execution.messages().discord.unableToCheckLinkingStatus.get()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.Text;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.feature.debug.data.VersionInfo;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
@ -47,7 +47,7 @@ public class DiscordSRVDiscordCommand {
|
||||
}
|
||||
if (discordSRV.linkProvider() instanceof LinkStore) {
|
||||
builder = builder
|
||||
.addSubCommand(LinkInitCommand.getDiscord(discordSRV))
|
||||
.addSubCommand(LinkOtherCommand.getDiscord(discordSRV))
|
||||
.addSubCommand(UnlinkCommand.getDiscord(discordSRV));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.common.command.discord.commands;
|
||||
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.commands.UnlinkCommand;
|
||||
import com.discordsrv.common.command.discord.commands.subcommand.LinkInitDiscordCommand;
|
||||
import com.discordsrv.common.config.main.DiscordCommandConfig;
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
|
||||
public class MinecraftDiscordCommand {
|
||||
|
||||
private static DiscordCommand INSTANCE;
|
||||
|
||||
public static DiscordCommand get(DiscordSRV discordSRV) {
|
||||
if (INSTANCE == null) {
|
||||
DiscordCommandConfig config = discordSRV.config().discordCommand;
|
||||
|
||||
ComponentIdentifier identifier = ComponentIdentifier.of("DiscordSRV", "minecraft");
|
||||
DiscordCommand.ChatInputBuilder builder = DiscordCommand.chatInput(identifier, "minecraft", "Minecraft server commands");
|
||||
|
||||
if (discordSRV.linkProvider() instanceof LinkStore) {
|
||||
builder = builder
|
||||
.addSubCommand(LinkInitDiscordCommand.getInstance(discordSRV))
|
||||
.addSubCommand(UnlinkCommand.getDiscord(discordSRV)); // TODO: no other user unlinking option
|
||||
}
|
||||
|
||||
INSTANCE = builder
|
||||
.setGuildOnly(false)
|
||||
.build();
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.api.events.discord.interaction.command.DiscordChatInputInteractionEvent;
|
||||
import com.discordsrv.api.events.discord.interaction.command.DiscordCommandAutoCompleteInteractionEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.game.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.config.main.DiscordCommandConfig;
|
||||
import com.discordsrv.common.config.main.generic.GameCommandExecutionConditionConfig;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
|
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.common.command.discord.commands.subcommand;
|
||||
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.CommandOption;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.api.events.discord.interaction.command.DiscordChatInputInteractionEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.config.messages.MessagesConfig;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.discordsrv.common.feature.linking.LinkProvider;
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class LinkInitDiscordCommand implements Consumer<DiscordChatInputInteractionEvent> {
|
||||
|
||||
private static DiscordCommand INSTANCE;
|
||||
|
||||
public static DiscordCommand getInstance(DiscordSRV discordSRV) {
|
||||
if (INSTANCE == null) {
|
||||
LinkInitDiscordCommand command = new LinkInitDiscordCommand(discordSRV);
|
||||
ComponentIdentifier identifier = ComponentIdentifier.of("DiscordSRV", "link-init");
|
||||
|
||||
INSTANCE = DiscordCommand.chatInput(identifier, "link", "Link your Minecraft account to your Discord account")
|
||||
.addOption(
|
||||
CommandOption.builder(CommandOption.Type.STRING, "code", "The code provided by the in-game command")
|
||||
.setRequired(true)
|
||||
.build()
|
||||
)
|
||||
.setEventHandler(command)
|
||||
.build();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
private final Logger logger;
|
||||
private final Cache<Long, Boolean> linkCheckRateLimit;
|
||||
|
||||
public LinkInitDiscordCommand(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.logger = new NamedLogger(discordSRV, "LINK_INIT_COMMAND");
|
||||
this.linkCheckRateLimit = discordSRV.caffeineBuilder()
|
||||
.expireAfterWrite(LinkStore.LINKING_CODE_RATE_LIMIT)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(DiscordChatInputInteractionEvent event) {
|
||||
DiscordUser user = event.getUser();
|
||||
MessagesConfig.Discord messagesConfig = discordSRV.messagesConfig(event.getUserLocale()).discord;
|
||||
|
||||
LinkProvider linkProvider = discordSRV.linkProvider();
|
||||
if (!(linkProvider instanceof LinkStore)) {
|
||||
event.reply(SendableDiscordMessage.builder().setContent("Cannot create links using this link provider").build());
|
||||
return;
|
||||
}
|
||||
LinkStore linkStore = (LinkStore) linkProvider;
|
||||
|
||||
String code = event.getOptionAsString("code");
|
||||
if (StringUtils.isEmpty(code) || !linkStore.isValidCode(code)) {
|
||||
event.reply(messagesConfig.invalidLinkingCode.get(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (linkProvider.getCachedPlayerUUID(user.getId()).isPresent()) {
|
||||
event.reply(messagesConfig.alreadyLinked1st.get(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (linkCheckRateLimit.getIfPresent(user.getId()) != null) {
|
||||
event.reply(messagesConfig.pleaseWaitBeforeRunningThatCommandAgain.get(), true);
|
||||
return;
|
||||
}
|
||||
linkCheckRateLimit.put(user.getId(), true);
|
||||
|
||||
event.deferReply(true).whenComplete((interactionHook, t1) -> {
|
||||
if (t1 != null) {
|
||||
logger.error("Failed to defer reply", t1);
|
||||
return;
|
||||
}
|
||||
|
||||
linkProvider.queryPlayerUUID(user.getId()).whenComplete((linkedPlayer, t2) -> {
|
||||
if (t2 != null) {
|
||||
logger.error("Failed to check linking status", t2);
|
||||
interactionHook.editOriginal(messagesConfig.unableToCheckLinkingStatus.get());
|
||||
return;
|
||||
}
|
||||
if (linkedPlayer.isPresent()) {
|
||||
interactionHook.editOriginal(messagesConfig.alreadyLinked1st.get());
|
||||
return;
|
||||
}
|
||||
|
||||
linkStore.getCodeLinking(user.getId(), code)
|
||||
.thenCompose(player -> linkStore.createLink(player.getKey(), user.getId()).thenApply(__ -> player))
|
||||
.whenComplete((player, t3) -> {
|
||||
if (t3 != null) {
|
||||
logger.error("Failed to link", t3);
|
||||
interactionHook.editOriginal(messagesConfig.unableToCheckLinkingStatus.get());
|
||||
return;
|
||||
}
|
||||
|
||||
linkSuccess(interactionHook, linkStore, messagesConfig, player);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void linkSuccess(
|
||||
DiscordInteractionHook interactionHook,
|
||||
LinkStore linkStore,
|
||||
MessagesConfig.Discord messagesConfig,
|
||||
Pair<UUID, String> pair
|
||||
) {
|
||||
UUID playerUUID = pair.getKey();
|
||||
String username = pair.getValue();
|
||||
|
||||
linkStore.removeLinkingCode(playerUUID).exceptionally(t -> {
|
||||
logger.error("Failed to remove linking code from storage", t);
|
||||
return null;
|
||||
});
|
||||
|
||||
IPlayer onlinePlayer = discordSRV.playerProvider().player(playerUUID);
|
||||
(onlinePlayer != null
|
||||
? CompletableFuture.completedFuture(onlinePlayer)
|
||||
: discordSRV.playerProvider().lookupOfflinePlayer(playerUUID)
|
||||
).whenComplete((player, __) -> interactionHook
|
||||
.editOriginal(
|
||||
messagesConfig.accountLinked.format()
|
||||
.addContext(player)
|
||||
.addPlaceholder("%player_name%", username)
|
||||
.addPlaceholder("%player_uuid%", playerUUID)
|
||||
.applyPlaceholderService()
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -20,10 +20,10 @@ package com.discordsrv.common.command.game;
|
||||
|
||||
import com.discordsrv.api.DiscordSRVApi;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.commands.LinkInitCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.combined.commands.LinkOtherCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.commands.DiscordSRVGameCommand;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.config.main.GameCommandConfig;
|
||||
import com.discordsrv.common.core.module.type.AbstractModule;
|
||||
|
||||
@ -57,7 +57,7 @@ public class GameCommandModule extends AbstractModule<DiscordSRV> {
|
||||
registerCommand(DiscordSRVGameCommand.get(discordSRV, "discord"));
|
||||
}
|
||||
if (config.useLinkAlias) {
|
||||
registerCommand(LinkInitCommand.getGame(discordSRV));
|
||||
registerCommand(LinkOtherCommand.getGame(discordSRV));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game;
|
||||
package com.discordsrv.common.command.game.abstraction;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
@ -16,9 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.abstraction;
|
||||
package com.discordsrv.common.command.game.abstraction.command;
|
||||
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
import com.discordsrv.common.util.function.CheckedFunction;
|
||||
import net.kyori.adventure.text.Component;
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.abstraction;
|
||||
package com.discordsrv.common.command.game.abstraction.command;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface GameCommandArguments {
|
@ -16,9 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.abstraction;
|
||||
package com.discordsrv.common.command.game.abstraction.command;
|
||||
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface GameCommandExecutor {
|
@ -16,9 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.abstraction;
|
||||
package com.discordsrv.common.command.game.abstraction.command;
|
||||
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.executor;
|
||||
package com.discordsrv.common.command.game.abstraction.executor;
|
||||
|
||||
import dev.vankka.dynamicproxy.processor.Original;
|
||||
import dev.vankka.dynamicproxy.processor.Proxy;
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.executor;
|
||||
package com.discordsrv.common.command.game.abstraction.executor;
|
||||
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.common.DiscordSRV;
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.executor;
|
||||
package com.discordsrv.common.command.game.abstraction.executor;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
@ -16,11 +16,11 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.handler;
|
||||
package com.discordsrv.common.command.game.abstraction.handler;
|
||||
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
@ -16,9 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.handler;
|
||||
package com.discordsrv.common.command.game.abstraction.handler;
|
||||
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
|
||||
public interface ICommandHandler {
|
||||
|
@ -16,12 +16,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.handler.util;
|
||||
package com.discordsrv.common.command.game.abstraction.handler.util;
|
||||
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.arguments.*;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
@ -16,9 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.command.game.sender;
|
||||
package com.discordsrv.common.command.game.abstraction.sender;
|
||||
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutor;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
import net.kyori.adventure.audience.ForwardingAudience;
|
||||
|
@ -21,12 +21,12 @@ package com.discordsrv.common.command.game.commands;
|
||||
import com.discordsrv.api.component.MinecraftComponent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.commands.*;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.commands.subcommand.BroadcastCommand;
|
||||
import com.discordsrv.common.command.game.commands.subcommand.reload.ReloadCommand;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
import com.discordsrv.common.util.ComponentUtil;
|
||||
@ -51,7 +51,7 @@ public class DiscordSRVGameCommand implements GameCommandExecutor {
|
||||
.then(BroadcastCommand.minecraft(discordSRV))
|
||||
.then(BroadcastCommand.json(discordSRV))
|
||||
.then(DebugCommand.getGame(discordSRV))
|
||||
.then(LinkInitCommand.getGame(discordSRV))
|
||||
.then(LinkOtherCommand.getGame(discordSRV))
|
||||
.then(LinkedCommand.getGame(discordSRV))
|
||||
.then(ReloadCommand.get(discordSRV))
|
||||
.then(ResyncCommand.getGame(discordSRV))
|
||||
|
@ -23,11 +23,11 @@ import com.discordsrv.api.discord.entity.channel.DiscordGuildMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.common.command.game.commands.subcommand;
|
||||
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.config.messages.MessagesConfig;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.discordsrv.common.feature.linking.LinkProvider;
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
import com.discordsrv.common.util.ComponentUtil;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class LinkInitGameCommand implements GameCommandExecutor {
|
||||
|
||||
private static GameCommandExecutor INSTANCE;
|
||||
|
||||
public static GameCommandExecutor getExecutor(DiscordSRV discordSRV) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new LinkInitGameCommand(discordSRV);
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
private final Logger logger;
|
||||
private final Cache<UUID, Boolean> linkCheckRateLimit;
|
||||
|
||||
private LinkInitGameCommand(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.logger = new NamedLogger(discordSRV, "LINK_INIT_COMMAND");
|
||||
this.linkCheckRateLimit = discordSRV.caffeineBuilder()
|
||||
.expireAfterWrite(LinkStore.LINKING_CODE_RATE_LIMIT)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ICommandSender sender, GameCommandArguments arguments, String label) {
|
||||
if (!(sender instanceof IPlayer)) {
|
||||
sender.sendMessage(discordSRV.messagesConfig(sender).pleaseSpecifyPlayerAndUserToLink.asComponent());
|
||||
return;
|
||||
}
|
||||
|
||||
IPlayer player = (IPlayer) sender;
|
||||
MessagesConfig.Minecraft messages = discordSRV.messagesConfig(player);
|
||||
|
||||
LinkProvider linkProvider = discordSRV.linkProvider();
|
||||
if (linkProvider.getCachedUserId(player.uniqueId()).isPresent()) {
|
||||
// Check cache first
|
||||
player.sendMessage(messages.alreadyLinked1st.asComponent());
|
||||
return;
|
||||
}
|
||||
|
||||
if (linkCheckRateLimit.getIfPresent(player.uniqueId()) != null) {
|
||||
player.sendMessage(messages.pleaseWaitBeforeRunningThatCommandAgain.asComponent());
|
||||
return;
|
||||
}
|
||||
linkCheckRateLimit.put(player.uniqueId(), true);
|
||||
|
||||
player.sendMessage(discordSRV.messagesConfig(player).checkingLinkStatus.asComponent());
|
||||
linkProvider.queryUserId(player.uniqueId(), true).whenComplete((userId, t1) -> {
|
||||
if (t1 != null) {
|
||||
logger.error("Failed to check linking status", t1);
|
||||
player.sendMessage(messages.unableToLinkAtThisTime.asComponent());
|
||||
return;
|
||||
}
|
||||
if (userId.isPresent()) {
|
||||
player.sendMessage(messages.nowLinked1st.asComponent());
|
||||
return;
|
||||
}
|
||||
|
||||
linkProvider.getLinkingInstructions(player, label).whenComplete((comp, t2) -> {
|
||||
if (t2 != null) {
|
||||
logger.error("Failed to link account", t2);
|
||||
player.sendMessage(messages.unableToLinkAtThisTime.asComponent());
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendMessage(ComponentUtil.fromAPI(comp));
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
@ -21,11 +21,11 @@ package com.discordsrv.common.command.game.commands.subcommand.reload;
|
||||
import com.discordsrv.api.DiscordSRVApi;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandArguments;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommandSuggester;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
|
@ -29,6 +29,9 @@ import com.discordsrv.common.config.configurate.fielddiscoverer.FieldValueDiscov
|
||||
import com.discordsrv.common.config.configurate.fielddiscoverer.OrderedFieldDiscovererProxy;
|
||||
import com.discordsrv.common.config.configurate.manager.loader.ConfigLoaderProvider;
|
||||
import com.discordsrv.common.config.configurate.serializer.*;
|
||||
import com.discordsrv.common.config.configurate.serializer.helper.DiscordMessageSerializer;
|
||||
import com.discordsrv.common.config.configurate.serializer.helper.MinecraftMessageSerializer;
|
||||
import com.discordsrv.common.config.helper.DiscordMessage;
|
||||
import com.discordsrv.common.config.helper.MinecraftMessage;
|
||||
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||
import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||
@ -207,8 +210,9 @@ public abstract class ConfigurateConfigManager<T, LT extends AbstractConfigurati
|
||||
builder.register(Pattern.class, new PatternSerializer());
|
||||
builder.register(DiscordMessageEmbed.Builder.class, new DiscordMessageEmbedSerializer(NAMING_SCHEME));
|
||||
builder.register(DiscordMessageEmbed.Field.class, new DiscordMessageEmbedSerializer.FieldSerializer(NAMING_SCHEME));
|
||||
builder.register(SendableDiscordMessage.Builder.class, new SendableDiscordMessageSerializer(NAMING_SCHEME));
|
||||
builder.register(SendableDiscordMessage.Builder.class, new SendableDiscordMessageSerializer(NAMING_SCHEME, false));
|
||||
builder.register(MinecraftMessage.class, new MinecraftMessageSerializer());
|
||||
builder.register(DiscordMessage.class, new DiscordMessageSerializer(NAMING_SCHEME));
|
||||
|
||||
// give Configurate' serializers the ObjectMapper mapper
|
||||
builder.register(type -> {
|
||||
|
@ -35,9 +35,11 @@ import java.util.List;
|
||||
public class SendableDiscordMessageSerializer implements TypeSerializer<SendableDiscordMessage.Builder> {
|
||||
|
||||
private final NamingScheme namingScheme;
|
||||
private final boolean preferContentOnly;
|
||||
|
||||
public SendableDiscordMessageSerializer(NamingScheme namingScheme) {
|
||||
public SendableDiscordMessageSerializer(NamingScheme namingScheme, boolean preferContentOnly) {
|
||||
this.namingScheme = namingScheme;
|
||||
this.preferContentOnly = preferContentOnly;
|
||||
}
|
||||
|
||||
private String map(String option) {
|
||||
@ -96,6 +98,11 @@ public class SendableDiscordMessageSerializer implements TypeSerializer<Sendable
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj.getWebhookUsername() == null && obj.getEmbeds().isEmpty() && preferContentOnly) {
|
||||
node.set(obj.getContent());
|
||||
return;
|
||||
}
|
||||
|
||||
String webhookUsername = obj.getWebhookUsername();
|
||||
if (webhookUsername != null) {
|
||||
ConfigurationNode webhook = node.node(map("Webhook"));
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.common.config.configurate.serializer.helper;
|
||||
|
||||
import com.discordsrv.common.config.configurate.serializer.SendableDiscordMessageSerializer;
|
||||
import com.discordsrv.common.config.helper.DiscordMessage;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
import org.spongepowered.configurate.util.NamingScheme;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class DiscordMessageSerializer implements TypeSerializer<DiscordMessage> {
|
||||
|
||||
private final SendableDiscordMessageSerializer serializer;
|
||||
|
||||
public DiscordMessageSerializer(NamingScheme namingScheme) {
|
||||
this.serializer = new SendableDiscordMessageSerializer(namingScheme, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscordMessage deserialize(Type type, ConfigurationNode node) throws SerializationException {
|
||||
return new DiscordMessage(serializer.deserialize(type, node));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Type type, @Nullable DiscordMessage obj, ConfigurationNode node) throws SerializationException {
|
||||
serializer.serialize(type, obj != null ? obj.builder() : null, node);
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.common.config.configurate.serializer;
|
||||
package com.discordsrv.common.config.configurate.serializer.helper;
|
||||
|
||||
import com.discordsrv.common.config.helper.MinecraftMessage;
|
||||
import org.jetbrains.annotations.Nullable;
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.common.config.helper;
|
||||
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
|
||||
public class DiscordMessage {
|
||||
|
||||
private final SendableDiscordMessage.Builder builder;
|
||||
|
||||
public DiscordMessage(SendableDiscordMessage.Builder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public SendableDiscordMessage get() {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public SendableDiscordMessage.Builder builder() {
|
||||
return builder.clone();
|
||||
}
|
||||
|
||||
public SendableDiscordMessage.Formatter format() {
|
||||
return builder.toFormatter();
|
||||
}
|
||||
}
|
@ -67,8 +67,8 @@ public class PresenceUpdaterConfig {
|
||||
@Constants.Comment({"online, idle, do_not_disturb, invisible"})
|
||||
public OnlineStatus status = OnlineStatus.ONLINE;
|
||||
|
||||
@Comment("This may be prefixed by one of the following to specify the activity type: %1\n"
|
||||
+ "You can prefix the value with %2 and a YouTube or Twitch link to use the Streaming activity type")
|
||||
@Comment("This may be prefixed by one of the following and a space to specify the activity type: %1\n"
|
||||
+ "You can use streaming by setting the value to: %2, a YouTube or Twitch link and the text all seperated by a space")
|
||||
@Constants.Comment({
|
||||
"\"playing\", \"listening\", \"watching\", \"competing in\"",
|
||||
"\"streaming\""
|
||||
|
@ -21,7 +21,7 @@ package com.discordsrv.common.config.main.generic;
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordRole;
|
||||
import com.discordsrv.common.command.game.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutionHelper;
|
||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||
|
||||
|
@ -19,13 +19,14 @@
|
||||
package com.discordsrv.common.config.messages;
|
||||
|
||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.placeholder.provider.SinglePlaceholder;
|
||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.abstraction.player.IOfflinePlayer;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.config.Config;
|
||||
import com.discordsrv.common.config.configurate.annotation.Constants;
|
||||
import com.discordsrv.common.config.configurate.annotation.Untranslated;
|
||||
import com.discordsrv.common.config.helper.DiscordMessage;
|
||||
import com.discordsrv.common.config.helper.MinecraftMessage;
|
||||
import com.discordsrv.common.util.CompletableFutureUtil;
|
||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
@ -94,35 +95,35 @@ public class MessagesConfig implements Config {
|
||||
public void playerNotFound(CommandExecution execution) {
|
||||
execution.send(
|
||||
minecraft.playerNotFound.asComponent(),
|
||||
discord.playerNotFound
|
||||
discord.playerNotFound.get()
|
||||
);
|
||||
}
|
||||
|
||||
public void userNotFound(CommandExecution execution) {
|
||||
execution.send(
|
||||
minecraft.userNotFound.asComponent(),
|
||||
discord.userNotFound
|
||||
discord.userNotFound.get()
|
||||
);
|
||||
}
|
||||
|
||||
public void unableToCheckLinkingStatus(CommandExecution execution) {
|
||||
execution.send(
|
||||
minecraft.unableToCheckLinkingStatus.asComponent(),
|
||||
discord.unableToCheckLinkingStatus
|
||||
discord.unableToCheckLinkingStatus.get()
|
||||
);
|
||||
}
|
||||
|
||||
public void playerAlreadyLinked3rd(CommandExecution execution) {
|
||||
execution.send(
|
||||
minecraft.playerAlreadyLinked3rd.asComponent(),
|
||||
discord.playerAlreadyLinked3rd
|
||||
discord.playerAlreadyLinked3rd.get()
|
||||
);
|
||||
}
|
||||
|
||||
public void userAlreadyLinked3rd(CommandExecution execution) {
|
||||
execution.send(
|
||||
minecraft.userAlreadyLinked3rd.asComponent(),
|
||||
discord.userAlreadyLinked3rd
|
||||
discord.userAlreadyLinked3rd.get()
|
||||
);
|
||||
}
|
||||
|
||||
@ -134,13 +135,12 @@ public class MessagesConfig implements Config {
|
||||
.addPlaceholder("user_id", userId)
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.build(),
|
||||
discordSRV.placeholderService().replacePlaceholders(
|
||||
execution.messages().discord.nowLinked3rd,
|
||||
user,
|
||||
player,
|
||||
new SinglePlaceholder("user_id", userId),
|
||||
new SinglePlaceholder("player_uuid", playerUUID)
|
||||
)
|
||||
execution.messages().discord.nowLinked3rd.format()
|
||||
.addContext(user, player)
|
||||
.addPlaceholder("user_id", userId)
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.applyPlaceholderService()
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
@ -158,13 +158,12 @@ public class MessagesConfig implements Config {
|
||||
.addPlaceholder("user_id", userId)
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.build(),
|
||||
discordSRV.placeholderService().replacePlaceholders(
|
||||
discord.discordUserLinkedTo,
|
||||
user,
|
||||
player,
|
||||
new SinglePlaceholder("user_id", userId),
|
||||
new SinglePlaceholder("player_uuid", playerUUID)
|
||||
)
|
||||
discord.discordUserLinkedTo.format()
|
||||
.addContext(user, player)
|
||||
.addPlaceholder("user_id", userId)
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.applyPlaceholderService()
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
@ -180,11 +179,11 @@ public class MessagesConfig implements Config {
|
||||
.addContext(user)
|
||||
.addPlaceholder("user_id", userId)
|
||||
.build(),
|
||||
discordSRV.placeholderService().replacePlaceholders(
|
||||
discord.discordUserUnlinked,
|
||||
user,
|
||||
new SinglePlaceholder("user_id", userId)
|
||||
)
|
||||
discord.discordUserUnlinked.format()
|
||||
.addContext(user)
|
||||
.addPlaceholder("user_id", userId)
|
||||
.applyPlaceholderService()
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
@ -202,13 +201,12 @@ public class MessagesConfig implements Config {
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.addPlaceholder("user_id", userId)
|
||||
.build(),
|
||||
discordSRV.placeholderService().replacePlaceholders(
|
||||
discord.minecraftPlayerLinkedTo,
|
||||
player,
|
||||
user,
|
||||
new SinglePlaceholder("player_uuid", playerUUID),
|
||||
new SinglePlaceholder("user_id", userId)
|
||||
)
|
||||
discord.minecraftPlayerLinkedTo.format()
|
||||
.addContext(player, user)
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.addPlaceholder("user_id", userId)
|
||||
.applyPlaceholderService()
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
@ -224,18 +222,17 @@ public class MessagesConfig implements Config {
|
||||
.addContext(player)
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.build(),
|
||||
discordSRV.placeholderService().replacePlaceholders(
|
||||
discord.minecraftPlayerUnlinked,
|
||||
player,
|
||||
new SinglePlaceholder("player_uuid", playerUUID)
|
||||
)
|
||||
discord.minecraftPlayerUnlinked.format()
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.applyPlaceholderService()
|
||||
.build()
|
||||
));
|
||||
}
|
||||
|
||||
public void unlinked(CommandExecution execution) {
|
||||
execution.send(
|
||||
minecraft.unlinked.asComponent(),
|
||||
discord.unlinked
|
||||
discord.unlinked.get()
|
||||
);
|
||||
}
|
||||
|
||||
@ -246,6 +243,7 @@ public class MessagesConfig implements Config {
|
||||
private static final String ERROR_COLOR = "&c";
|
||||
private static final String SUCCESS_COLOR = "&a";
|
||||
private static final String NEUTRAL_COLOR = "&b";
|
||||
private static final String BLURPLE_COLOR = "ᛩF2";
|
||||
|
||||
private MinecraftMessage make(String rawFormat) {
|
||||
return new MinecraftMessage(rawFormat);
|
||||
@ -326,6 +324,12 @@ public class MessagesConfig implements Config {
|
||||
"&fMinecraftAuth"
|
||||
})
|
||||
public MinecraftMessage minecraftAuthLinking = make("%1Please visit %2 to link your account through %3");
|
||||
@Constants({NEUTRAL_COLOR, BLURPLE_COLOR})
|
||||
public MinecraftMessage storageLinking = make(
|
||||
"%1Join our %2Discord %1server at "
|
||||
+ "[click:open_url:%discord_invite%]%discord_invite_simple%[click]"
|
||||
+ " and link your account by running the "
|
||||
+ "&r[click:copy_to_clipboard:/<todo> link %code%][hover:show_text:Click to copy]/<todo> link %code%"); // TODO
|
||||
|
||||
@Untranslated(Untranslated.Type.COMMENT)
|
||||
@Comment("/discord unlink")
|
||||
@ -343,63 +347,75 @@ public class MessagesConfig implements Config {
|
||||
private static final String INPUT_ERROR_PREFIX = "\uD83D\uDDD2️ ";
|
||||
private static final String ERROR_PREFIX = "❌ ";
|
||||
|
||||
private DiscordMessage make(String rawFormat) {
|
||||
return new DiscordMessage(SendableDiscordMessage.builder().setContent(rawFormat));
|
||||
}
|
||||
|
||||
@Comment("Generic")
|
||||
@Constants(INPUT_ERROR_PREFIX)
|
||||
public String pleaseSpecifyPlayer = "%1Please specify the Minecraft player";
|
||||
public DiscordMessage pleaseSpecifyPlayer = make("%1Please specify the Minecraft player");
|
||||
@Constants(INPUT_ERROR_PREFIX)
|
||||
public String pleaseSpecifyUser = "%1Please specify the Discord user";
|
||||
public DiscordMessage pleaseSpecifyUser = make("%1Please specify the Discord user");
|
||||
@Constants(INPUT_ERROR_PREFIX)
|
||||
public String pleaseSpecifyPlayerOrUser = "%1Please specify the Minecraft player or Discord user";
|
||||
public DiscordMessage pleaseSpecifyPlayerOrUser = make("%1Please specify the Minecraft player or Discord user");
|
||||
@Constants(ERROR_PREFIX)
|
||||
public String playerNotFound = "%1Minecraft player not found";
|
||||
public DiscordMessage playerNotFound = make("%1Minecraft player not found");
|
||||
@Constants(ERROR_PREFIX)
|
||||
public String userNotFound = "%1Discord user not found";
|
||||
public DiscordMessage userNotFound = make("%1Discord user not found");
|
||||
@Constants(ERROR_PREFIX)
|
||||
public String unableToCheckLinkingStatus = "%1Unable to check linking status, please try again later";
|
||||
public DiscordMessage unableToCheckLinkingStatus = make("%1Unable to check linking status, please try again later");
|
||||
|
||||
@Constants({
|
||||
SUCCESS_PREFIX,
|
||||
"**%user_name%** (<@%user_id%>)",
|
||||
"**%player_name%** (%player_uuid%)"
|
||||
})
|
||||
public String discordUserLinkedTo = "%1%2 is linked to %3";
|
||||
public DiscordMessage discordUserLinkedTo = make("%1%2 is linked to %3");
|
||||
|
||||
@Constants({
|
||||
ERROR_PREFIX,
|
||||
"**%user_name%** (<@%user_id%>)"
|
||||
})
|
||||
public String discordUserUnlinked = "%1%2 is __unlinked__";
|
||||
public DiscordMessage discordUserUnlinked = make("%1%2 is __unlinked__");
|
||||
|
||||
@Constants({
|
||||
SUCCESS_PREFIX,
|
||||
"**%player_name%** (%player_uuid%)",
|
||||
"**%user_name%** (<@%user_id%>)"
|
||||
})
|
||||
public String minecraftPlayerLinkedTo = "%1%2 is linked to %3";
|
||||
public DiscordMessage minecraftPlayerLinkedTo = make("%1%2 is linked to %3");
|
||||
|
||||
@Constants({
|
||||
ERROR_PREFIX,
|
||||
"**%player_name%** (%player_uuid%)"
|
||||
})
|
||||
public String minecraftPlayerUnlinked = "%1%2 is __unlinked__";
|
||||
public DiscordMessage minecraftPlayerUnlinked = make("%1%2 is __unlinked__");
|
||||
|
||||
@Untranslated(Untranslated.Type.COMMENT)
|
||||
@Comment("/discord link")
|
||||
@Constants(ERROR_PREFIX)
|
||||
public String playerAlreadyLinked3rd = "%1That Minecraft player is already linked";
|
||||
public DiscordMessage playerAlreadyLinked3rd = make("%1That Minecraft player is already linked");
|
||||
@Constants(ERROR_PREFIX)
|
||||
public String userAlreadyLinked3rd = "%1That Discord user is already linked";
|
||||
public DiscordMessage userAlreadyLinked3rd = make("%1That Discord user is already linked");
|
||||
@Constants(ERROR_PREFIX)
|
||||
public DiscordMessage alreadyLinked1st = make("%1You are already linked");
|
||||
@Constants({
|
||||
SUCCESS_PREFIX,
|
||||
"**%player_name%** (%player_uuid%)",
|
||||
"**%user_name%** (<@%user_id%>)"
|
||||
})
|
||||
public String nowLinked3rd = "%1Link created successfully\n%2 and %3";
|
||||
public DiscordMessage nowLinked3rd = make("%1Link created successfully\n%2 and %3");
|
||||
@Constants(ERROR_PREFIX)
|
||||
public DiscordMessage pleaseWaitBeforeRunningThatCommandAgain = make("%1Please wait before running that command again");
|
||||
@Constants(ERROR_PREFIX)
|
||||
public DiscordMessage invalidLinkingCode = make("%1Invalid linking code");
|
||||
@Constants({SUCCESS_PREFIX, "**%player_name%**"})
|
||||
public DiscordMessage accountLinked = make("%1Account linked to %2 successfully");
|
||||
|
||||
@Untranslated(Untranslated.Type.COMMENT)
|
||||
@Comment("/discord unlink")
|
||||
@Constants({SUCCESS_PREFIX})
|
||||
public String unlinked = "%1Accounts unlinked";
|
||||
public DiscordMessage unlinked = make("%1Accounts unlinked");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
package com.discordsrv.common.core.storage;
|
||||
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.Blocking;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -43,8 +44,8 @@ public interface Storage {
|
||||
/**
|
||||
* Inserts the given code for the given player, removing any existing code if any, with a {@link LinkStore#LINKING_CODE_EXPIRY_TIME} expiry.
|
||||
*/
|
||||
void storeLinkingCode(@NotNull UUID player, String code);
|
||||
UUID getLinkingCode(String code);
|
||||
void storeLinkingCode(@NotNull UUID player, String username, String code);
|
||||
Pair<UUID, String> getLinkingCode(String code);
|
||||
void removeLinkingCode(@NotNull UUID player);
|
||||
|
||||
int getLinkedAccountCount();
|
||||
|
@ -21,17 +21,20 @@ package com.discordsrv.common.core.storage.impl;
|
||||
import com.discordsrv.common.core.storage.Storage;
|
||||
import org.apache.commons.collections4.BidiMap;
|
||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MemoryStorage implements Storage {
|
||||
|
||||
public static String IDENTIFIER = UUID.randomUUID().toString();
|
||||
|
||||
private final BidiMap<UUID, Long> linkedAccounts = new DualHashBidiMap<>();
|
||||
private final BidiMap<UUID, String> linkingCodes = new DualHashBidiMap<>();
|
||||
private final Map<String, Pair<UUID, String>> linkingCodes = new ConcurrentHashMap<>();
|
||||
|
||||
public MemoryStorage() {}
|
||||
|
||||
@ -64,22 +67,23 @@ public class MemoryStorage implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeLinkingCode(@NotNull UUID player, String code) {
|
||||
linkingCodes.put(player, code);
|
||||
public void storeLinkingCode(@NotNull UUID player, @NotNull String username, String code) {
|
||||
linkingCodes.put(code, Pair.of(player, username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getLinkingCode(String code) {
|
||||
return linkingCodes.getKey(code);
|
||||
public Pair<UUID, String> getLinkingCode(String code) {
|
||||
return linkingCodes.get(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLinkingCode(@NotNull UUID player) {
|
||||
linkingCodes.remove(player);
|
||||
linkingCodes.values().removeIf(code -> code.getKey() == player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLinkedAccountCount() {
|
||||
return linkedAccounts.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.discordsrv.common.exception.StorageException;
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
import com.discordsrv.common.util.function.CheckedConsumer;
|
||||
import com.discordsrv.common.util.function.CheckedFunction;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -165,20 +166,16 @@ public abstract class SQLStorage implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getLinkingCode(String code) {
|
||||
public Pair<UUID, String> getLinkingCode(String code) {
|
||||
return useConnection(connection -> {
|
||||
// Clean expired codes
|
||||
try (PreparedStatement statement = connection.prepareStatement("delete from " + tablePrefix() + LINKING_CODES_TABLE_NAME + " where EXPIRY < ?;")) {
|
||||
statement.setLong(1, getTimeMS());
|
||||
statement.executeUpdate();
|
||||
}
|
||||
|
||||
// Get the uuid for the code
|
||||
try (PreparedStatement statement = connection.prepareStatement("select PLAYERUUID from " + tablePrefix() + LINKING_CODES_TABLE_NAME + " where CODE = ? LIMIT 1;")) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("select PLAYERUUID, PLAYERUSERNAME from " + tablePrefix() + LINKING_CODES_TABLE_NAME + " where CODE = ? LIMIT 1;")) {
|
||||
statement.setString(1, code);
|
||||
try (ResultSet resultSet = statement.executeQuery()) {
|
||||
if (resultSet.next()) {
|
||||
return UUID.fromString(resultSet.getString("PLAYERUUID"));
|
||||
UUID uuid = UUID.fromString(resultSet.getString("PLAYERUUID"));
|
||||
String username = resultSet.getString("PLAYERUSERNAME");
|
||||
return Pair.of(uuid, username);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -197,7 +194,7 @@ public abstract class SQLStorage implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeLinkingCode(@NotNull UUID player, String code) {
|
||||
public void storeLinkingCode(@NotNull UUID player, @NotNull String username, String code) {
|
||||
useConnection(connection -> {
|
||||
// Remove existing code
|
||||
try (PreparedStatement statement = connection.prepareStatement("delete from " + tablePrefix() + LINKING_CODES_TABLE_NAME + " where PLAYERUUID = ?;")) {
|
||||
@ -206,10 +203,11 @@ public abstract class SQLStorage implements Storage {
|
||||
}
|
||||
|
||||
// Insert new code
|
||||
try (PreparedStatement statement = connection.prepareStatement("insert into " + tablePrefix() + LINKING_CODES_TABLE_NAME + " (PLAYERUUID, CODE, EXPIRY) VALUES (?, ?, ?);")) {
|
||||
try (PreparedStatement statement = connection.prepareStatement("insert into " + tablePrefix() + LINKING_CODES_TABLE_NAME + " (PLAYERUUID, PLAYERUSERNAME, CODE, EXPIRY) VALUES (?, ?, ?, ?);")) {
|
||||
statement.setString(1, player.toString());
|
||||
statement.setString(2, code);
|
||||
statement.setLong(3, getTimeMS() + LinkStore.LINKING_CODE_EXPIRY_TIME.toMillis());
|
||||
statement.setString(2, username);
|
||||
statement.setString(3, code);
|
||||
statement.setLong(4, getTimeMS() + LinkStore.LINKING_CODE_EXPIRY_TIME.toMillis());
|
||||
exceptEffectedRows(statement.executeUpdate(), 1);
|
||||
}
|
||||
});
|
||||
|
@ -102,21 +102,27 @@ public class H2Storage extends SQLStorage {
|
||||
public void createTables(Connection connection, String tablePrefix) throws SQLException {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(
|
||||
"create table if not exists " + tablePrefix + LINKED_ACCOUNTS_TABLE_NAME + " "
|
||||
+ "(ID int not null auto_increment, "
|
||||
+ "PLAYER_UUID varchar(36), "
|
||||
+ "USER_ID bigint, "
|
||||
+ "constraint LINKED_ACCOUNTS_PK primary key (ID)"
|
||||
+ ")");
|
||||
"create table if not exists " + tablePrefix + LINKED_ACCOUNTS_TABLE_NAME + " ("
|
||||
+ "ID int not null auto_increment,"
|
||||
+ "PLAYER_UUID varchar(36),"
|
||||
+ "USER_ID bigint,"
|
||||
+ "constraint LINKED_ACCOUNTS_PK primary key (ID),"
|
||||
+ "constraint LINKED_ACCOUNTS_UQ unique (PLAYER_UUID, USER_ID)"
|
||||
+ ");");
|
||||
}
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(
|
||||
"create table if not exists " + tablePrefix + LINKING_CODES_TABLE_NAME + " "
|
||||
+ "(PLAYERUUID varchar(36), "
|
||||
+ "CODE varchar(8), "
|
||||
+ "EXPIRY bigint, "
|
||||
+ "constraint LINKING_CODES_PK primary key (PLAYERUUID)"
|
||||
+ ")");
|
||||
"create table if not exists " + tablePrefix + LINKING_CODES_TABLE_NAME + " ("
|
||||
+ "PLAYERUUID varchar(36),"
|
||||
+ "PLAYERUSERNAME varchar(32),"
|
||||
+ "CODE varchar(8),"
|
||||
+ "EXPIRY bigint,"
|
||||
+ "constraint LINKING_CODES_PK primary key (PLAYERUUID),"
|
||||
+ "constraint LINKING_CODES_UQ unique (CODE)"
|
||||
+ ");");
|
||||
}
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute("alter table " + tablePrefix + LINKING_CODES_TABLE_NAME + " add column if not exists PLAYERUSERNAME varchar(32);");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,17 +57,23 @@ public class MySQLStorage extends HikariStorage {
|
||||
+ "(ID int not null auto_increment, "
|
||||
+ "PLAYER_UUID varchar(36), "
|
||||
+ "USER_ID bigint, "
|
||||
+ "constraint LINKED_ACCOUNTS_PK primary key (ID)"
|
||||
+ ")");
|
||||
+ "constraint LINKED_ACCOUNTS_PK primary key (ID),"
|
||||
+ "constraint LINKED_ACCOUNTS_UQ unique (PLAYER_UUID, USER_ID)"
|
||||
+ ");");
|
||||
}
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute(
|
||||
"create table if not exists " + tablePrefix + LINKING_CODES_TABLE_NAME + " "
|
||||
+ "(PLAYERUUID varchar(36),"
|
||||
"create table if not exists " + tablePrefix + LINKING_CODES_TABLE_NAME + " ("
|
||||
+ "PLAYERUUID varchar(36),"
|
||||
+ "PLAYERUSERNAME varchar(32),"
|
||||
+ "CODE varchar(8),"
|
||||
+ "EXPIRY bigint,"
|
||||
+ "constraint LINKING_CODES_PK primary key (PLAYERUUID)"
|
||||
+ ")");
|
||||
+ "constraint LINKING_CODES_PK primary key (PLAYERUUID),"
|
||||
+ "constraint LINKING_CODES_UQ unique (CODE)"
|
||||
+ ");");
|
||||
}
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.execute("alter table " + tablePrefix + LINKING_CODES_TABLE_NAME + " add column if not exists PLAYERUSERNAME varchar(32);");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,4 +199,9 @@ public class DiscordInviteModule extends AbstractModule<DiscordSRV> {
|
||||
public CharSequence getInvite() {
|
||||
return FormattedText.of(invite != null ? invite : UNKNOWN_INVITE);
|
||||
}
|
||||
|
||||
@Placeholder("discord_invite_simple")
|
||||
public CharSequence getInviteSimple() {
|
||||
return FormattedText.of(invite != null ? invite.replace("https://", "") : UNKNOWN_INVITE);
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
package com.discordsrv.common.feature.console;
|
||||
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.core.logging.backend.LoggingBackend;
|
||||
|
||||
public interface Console extends ICommandSender {
|
||||
|
@ -31,7 +31,7 @@ import com.discordsrv.api.events.discord.message.DiscordMessageReceiveEvent;
|
||||
import com.discordsrv.api.placeholder.format.PlainPlaceholderFormat;
|
||||
import com.discordsrv.api.placeholder.provider.SinglePlaceholder;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.game.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.config.main.ConsoleConfig;
|
||||
import com.discordsrv.common.config.main.generic.DestinationConfig;
|
||||
import com.discordsrv.common.config.main.generic.GameCommandExecutionConditionConfig;
|
||||
|
@ -74,6 +74,8 @@ public interface LinkProvider {
|
||||
String username,
|
||||
UUID playerUUID,
|
||||
@Nullable Locale locale,
|
||||
@Nullable String requestReason
|
||||
@Nullable String requestReason,
|
||||
Object... additionalContext
|
||||
);
|
||||
boolean isValidCode(@NotNull String code);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.discordsrv.common.feature.linking;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
@ -32,8 +33,13 @@ public interface LinkStore extends LinkProvider {
|
||||
CompletableFuture<Void> createLink(@NotNull UUID playerUUID, long userId);
|
||||
CompletableFuture<Void> removeLink(@NotNull UUID playerUUID, long userId);
|
||||
|
||||
CompletableFuture<UUID> getCodeLinking(long userId, @NotNull String code);
|
||||
CompletableFuture<Void> removeLinkingCode(@NotNull String code);
|
||||
/**
|
||||
* Gets the linking code information for the given code.
|
||||
* @param userId the Discord user id this request is for
|
||||
* @param code the code
|
||||
* @return a part with the Player's {@link UUID} and username
|
||||
*/
|
||||
CompletableFuture<Pair<UUID, String>> getCodeLinking(long userId, @NotNull String code);
|
||||
CompletableFuture<Void> removeLinkingCode(@NotNull UUID playerUUID);
|
||||
|
||||
CompletableFuture<Integer> getLinkedAccountCount();
|
||||
|
@ -20,7 +20,6 @@ package com.discordsrv.common.feature.linking.impl;
|
||||
|
||||
import com.discordsrv.api.component.MinecraftComponent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.core.logging.NamedLogger;
|
||||
import com.discordsrv.common.feature.linking.LinkStore;
|
||||
@ -89,16 +88,28 @@ public class MinecraftAuthenticationLinker extends CachedLinkProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<MinecraftComponent> getLinkingInstructions(@NotNull IPlayer player, @Nullable String requestReason) {
|
||||
return getInstructions(player, requestReason);
|
||||
public CompletableFuture<MinecraftComponent> getLinkingInstructions(
|
||||
String username,
|
||||
UUID playerUUID,
|
||||
Locale locale,
|
||||
@Nullable String requestReason,
|
||||
Object... additionalContext
|
||||
) {
|
||||
return getInstructions(username, playerUUID, locale, requestReason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<MinecraftComponent> getLinkingInstructions(String username, UUID playerUUID, Locale locale, @Nullable String requestReason) {
|
||||
return getInstructions(null, requestReason);
|
||||
public boolean isValidCode(@NotNull String code) {
|
||||
throw new IllegalStateException("Does not offer codes");
|
||||
}
|
||||
|
||||
private CompletableFuture<MinecraftComponent> getInstructions(@Nullable IPlayer player, @Nullable String requestReason) {
|
||||
private CompletableFuture<MinecraftComponent> getInstructions(
|
||||
String playerName,
|
||||
UUID playerUUID,
|
||||
@Nullable Locale locale,
|
||||
@Nullable String requestReason,
|
||||
Object... additionalContext
|
||||
) {
|
||||
String method = null;
|
||||
if (requestReason != null) {
|
||||
requestReason = requestReason.toLowerCase(Locale.ROOT);
|
||||
@ -121,10 +132,12 @@ public class MinecraftAuthenticationLinker extends CachedLinkProvider {
|
||||
|
||||
String url = BASE_LINK_URL + (additionalParam.length() > 0 ? "/" + additionalParam : "");
|
||||
String simple = url.substring(url.indexOf("://") + 3); // Remove protocol & don't include method query parameter
|
||||
MinecraftComponent component = discordSRV.messagesConfig(player).minecraftAuthLinking.textBuilder()
|
||||
.addContext(player)
|
||||
MinecraftComponent component = discordSRV.messagesConfig(locale).minecraft.minecraftAuthLinking.textBuilder()
|
||||
.addContext(additionalContext)
|
||||
.addPlaceholder("minecraftauth_link", url + (method != null ? "?command=" + method : null))
|
||||
.addPlaceholder("minecraftauth_link_simple", simple)
|
||||
.addPlaceholder("player_name", playerName)
|
||||
.addPlaceholder("player_uuid", playerUUID)
|
||||
.applyPlaceholderService()
|
||||
.build();
|
||||
return CompletableFuture.completedFuture(component);
|
||||
|
@ -20,8 +20,7 @@ package com.discordsrv.common.feature.linking.impl;
|
||||
|
||||
import com.discordsrv.api.component.MinecraftComponent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.util.ComponentUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -64,18 +63,10 @@ public class StorageLinker extends CachedLinkProvider.Store {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<UUID> getCodeLinking(long userId, @NotNull String code) {
|
||||
public CompletableFuture<Pair<UUID, String>> getCodeLinking(long userId, @NotNull String code) {
|
||||
return discordSRV.scheduler().supply(() -> discordSRV.storage().getLinkingCode(code));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeLinkingCode(@NotNull String code) {
|
||||
return discordSRV.scheduler().execute(() -> {
|
||||
UUID player = discordSRV.storage().getLinkingCode(code);
|
||||
discordSRV.storage().removeLinkingCode(player);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeLinkingCode(@NotNull UUID playerUUID) {
|
||||
return discordSRV.scheduler().execute(() -> discordSRV.storage().removeLinkingCode(playerUUID));
|
||||
@ -89,7 +80,13 @@ public class StorageLinker extends CachedLinkProvider.Store {
|
||||
private final SecureRandom secureRandom = new SecureRandom();
|
||||
|
||||
@Override
|
||||
public CompletableFuture<MinecraftComponent> getLinkingInstructions(String username, UUID playerUUID, @Nullable Locale locale, @Nullable String requestReason) {
|
||||
public CompletableFuture<MinecraftComponent> getLinkingInstructions(
|
||||
String username,
|
||||
UUID playerUUID,
|
||||
@Nullable Locale locale,
|
||||
@Nullable String requestReason,
|
||||
Object... additionalContext
|
||||
) {
|
||||
return discordSRV.scheduler().supply(() -> {
|
||||
String code = null;
|
||||
while (code == null || discordSRV.storage().getLinkingCode(code) != null) {
|
||||
@ -99,8 +96,19 @@ public class StorageLinker extends CachedLinkProvider.Store {
|
||||
}
|
||||
}
|
||||
|
||||
discordSRV.storage().storeLinkingCode(playerUUID, code);
|
||||
return ComponentUtil.toAPI(Component.text(code));
|
||||
discordSRV.storage().storeLinkingCode(playerUUID, username, code);
|
||||
return discordSRV.messagesConfig(locale).minecraft.storageLinking.textBuilder()
|
||||
.addContext(additionalContext)
|
||||
.addPlaceholder("%code%", code)
|
||||
.addPlaceholder("%player_name%", username)
|
||||
.addPlaceholder("%player_uuid%", playerUUID)
|
||||
.applyPlaceholderService()
|
||||
.build();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidCode(@NotNull String code) {
|
||||
return code.matches("[0-9]{6}");
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.command.combined.abstraction.CommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.DiscordCommandExecution;
|
||||
import com.discordsrv.common.command.combined.abstraction.GameCommandExecution;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.common.config.messages.MessagesConfig;
|
||||
import com.discordsrv.common.core.logging.Logger;
|
||||
import com.discordsrv.common.permission.game.Permission;
|
||||
@ -116,11 +116,11 @@ public final class CommandUtil {
|
||||
} else if (execution instanceof DiscordCommandExecution) {
|
||||
if (target == null) {
|
||||
if (selfPermitted && lookupUser) {
|
||||
target = Long.toUnsignedString(((DiscordCommandExecution) execution).getUser().getIdLong());
|
||||
target = Long.toUnsignedString(((DiscordCommandExecution) execution).getUser().getId());
|
||||
} else {
|
||||
execution.send(
|
||||
messages.minecraft.pleaseSpecifyUser.asComponent(),
|
||||
messages.discord.pleaseSpecifyUser
|
||||
messages.discord.pleaseSpecifyUser.get()
|
||||
);
|
||||
return CompletableFuture.completedFuture(TargetLookupResult.INVALID);
|
||||
}
|
||||
@ -142,7 +142,7 @@ public final class CommandUtil {
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
execution.send(
|
||||
messages.minecraft.userNotFound.asComponent(),
|
||||
messages.discord.userNotFound
|
||||
messages.discord.userNotFound.get()
|
||||
);
|
||||
return CompletableFuture.completedFuture(TargetLookupResult.INVALID);
|
||||
}
|
||||
@ -176,7 +176,7 @@ public final class CommandUtil {
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
execution.send(
|
||||
messages.minecraft.playerNotFound.asComponent(),
|
||||
messages.discord.playerNotFound
|
||||
messages.discord.playerNotFound.get()
|
||||
);
|
||||
return CompletableFuture.completedFuture(TargetLookupResult.INVALID);
|
||||
}
|
||||
@ -205,19 +205,19 @@ public final class CommandUtil {
|
||||
if (lookupPlayer && lookupUser) {
|
||||
execution.send(
|
||||
messages.minecraft.pleaseSpecifyPlayerOrUser.asComponent(),
|
||||
messages.discord.pleaseSpecifyPlayerOrUser
|
||||
messages.discord.pleaseSpecifyPlayerOrUser.get()
|
||||
);
|
||||
return TargetLookupResult.INVALID;
|
||||
} else if (lookupPlayer) {
|
||||
execution.send(
|
||||
messages.minecraft.pleaseSpecifyPlayer.asComponent(),
|
||||
messages.discord.pleaseSpecifyPlayer
|
||||
messages.discord.pleaseSpecifyPlayer.get()
|
||||
);
|
||||
return TargetLookupResult.INVALID;
|
||||
} else if (lookupUser) {
|
||||
execution.send(
|
||||
messages.minecraft.pleaseSpecifyUser.asComponent(),
|
||||
messages.discord.pleaseSpecifyUser
|
||||
messages.discord.pleaseSpecifyUser.get()
|
||||
);
|
||||
return TargetLookupResult.INVALID;
|
||||
} else {
|
||||
|
@ -24,8 +24,8 @@ import com.discordsrv.common.abstraction.bootstrap.LifecycleManager;
|
||||
import com.discordsrv.common.abstraction.player.IPlayer;
|
||||
import com.discordsrv.common.abstraction.player.provider.AbstractPlayerProvider;
|
||||
import com.discordsrv.common.abstraction.plugin.PluginManager;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.config.configurate.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MainConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MessagesConfigManager;
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
package com.discordsrv.common.command.game;
|
||||
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommandExecutionHelper;
|
||||
import com.discordsrv.common.config.main.generic.GameCommandExecutionConditionConfig;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -20,7 +20,7 @@ package com.discordsrv.velocity;
|
||||
|
||||
import com.discordsrv.common.AbstractDiscordSRV;
|
||||
import com.discordsrv.common.abstraction.plugin.PluginManager;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.config.configurate.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MainConfigManager;
|
||||
import com.discordsrv.common.config.configurate.manager.MessagesConfigManager;
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
package com.discordsrv.velocity.command.game.handler;
|
||||
|
||||
import com.discordsrv.common.command.game.abstraction.GameCommand;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.handler.util.BrigadierUtil;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.command.GameCommand;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.ICommandHandler;
|
||||
import com.discordsrv.common.command.game.abstraction.handler.util.BrigadierUtil;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.velocity.VelocityDiscordSRV;
|
||||
import com.discordsrv.velocity.command.game.sender.VelocityCommandSender;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package com.discordsrv.velocity.command.game.sender;
|
||||
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import com.discordsrv.common.command.game.abstraction.sender.ICommandSender;
|
||||
import com.discordsrv.velocity.VelocityDiscordSRV;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package com.discordsrv.velocity.console;
|
||||
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.core.logging.backend.LoggingBackend;
|
||||
import com.discordsrv.common.core.logging.backend.impl.Log4JLoggerImpl;
|
||||
import com.discordsrv.common.feature.console.Console;
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
package com.discordsrv.velocity.console.executor;
|
||||
|
||||
import com.discordsrv.common.command.game.executor.AdventureCommandExecutorProxy;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.AdventureCommandExecutorProxy;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutor;
|
||||
import com.discordsrv.velocity.VelocityDiscordSRV;
|
||||
import com.velocitypowered.api.proxy.ConsoleCommandSource;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
package com.discordsrv.velocity.console.executor;
|
||||
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutor;
|
||||
import com.discordsrv.common.command.game.abstraction.executor.CommandExecutorProvider;
|
||||
import com.discordsrv.velocity.VelocityDiscordSRV;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user