mirror of
https://github.com/SimplexDevelopment/FreedomNetworkSuite.git
synced 2024-11-22 08:54:59 +00:00
Bot Command Implementation
# Changes: - Added /ban <player> <reason> [duration] command. Bans a user on the server for the specified reason and duration (in minutes). If no duration is specified, the default is 5 minutes. - Added /kick <player> <reason> command. Kicks a player on the server for the specified reason. - Added /whisper <player> <message> command. Send a private message to a player on the server.
This commit is contained in:
parent
4681fc9596
commit
85cc1f7ae0
@ -37,14 +37,14 @@ public class MiniMessageWrapper
|
|||||||
private static final MiniMessage unsafe = MiniMessage.miniMessage();
|
private static final MiniMessage unsafe = MiniMessage.miniMessage();
|
||||||
private static final MiniMessage safe = MiniMessage.builder()
|
private static final MiniMessage safe = MiniMessage.builder()
|
||||||
.tags(TagResolver.resolver(
|
.tags(TagResolver.resolver(
|
||||||
StandardTags.color(),
|
StandardTags.color(),
|
||||||
StandardTags.rainbow(),
|
StandardTags.rainbow(),
|
||||||
StandardTags.gradient(),
|
StandardTags.gradient(),
|
||||||
StandardTags.newline(),
|
StandardTags.newline(),
|
||||||
StandardTags.decorations(TextDecoration.ITALIC),
|
StandardTags.decorations(TextDecoration.ITALIC),
|
||||||
StandardTags.decorations(TextDecoration.BOLD),
|
StandardTags.decorations(TextDecoration.BOLD),
|
||||||
StandardTags.decorations(TextDecoration.STRIKETHROUGH),
|
StandardTags.decorations(TextDecoration.STRIKETHROUGH),
|
||||||
StandardTags.decorations(TextDecoration.UNDERLINED)
|
StandardTags.decorations(TextDecoration.UNDERLINED)
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -34,6 +34,13 @@ import org.bukkit.Bukkit;
|
|||||||
public class Aggregate
|
public class Aggregate
|
||||||
{
|
{
|
||||||
private static final FNS4J logger = FNS4J.getLogger("Veritas");
|
private static final FNS4J logger = FNS4J.getLogger("Veritas");
|
||||||
|
private static final String FAILED_PACKET = """
|
||||||
|
Failed to process inbound chat packet.
|
||||||
|
An offending element was found transmitted through the stream.
|
||||||
|
The element has been dropped, and ignored.
|
||||||
|
Offending element: %s
|
||||||
|
Caused by: %s
|
||||||
|
Stack Trace: %s""";
|
||||||
private final BotClient bot;
|
private final BotClient bot;
|
||||||
private final Veritas plugin;
|
private final Veritas plugin;
|
||||||
private final BukkitNative bukkitNativeListener;
|
private final BukkitNative bukkitNativeListener;
|
||||||
@ -62,8 +69,17 @@ public class Aggregate
|
|||||||
this.bukkitNativeListener = new BukkitNative(plugin);
|
this.bukkitNativeListener = new BukkitNative(plugin);
|
||||||
this.serverListener = new ServerListener(plugin);
|
this.serverListener = new ServerListener(plugin);
|
||||||
|
|
||||||
Bukkit.getServer().getPluginManager().registerEvents(this.getBukkitNativeListener(), plugin);
|
Bukkit.getServer()
|
||||||
this.getServerListener().minecraftChatBound().subscribe();
|
.getPluginManager()
|
||||||
|
.registerEvents(this.getBukkitNativeListener(), plugin);
|
||||||
|
this.getServerListener()
|
||||||
|
.minecraftChatBound()
|
||||||
|
.onErrorContinue((th, v) -> Aggregate.getLogger()
|
||||||
|
.error(FAILED_PACKET.formatted(
|
||||||
|
v.getClass().getName(),
|
||||||
|
th.getCause(),
|
||||||
|
th.getMessage())))
|
||||||
|
.subscribe();
|
||||||
this.bot = bot1;
|
this.bot = bot1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +103,11 @@ public class Aggregate
|
|||||||
return bot;
|
return bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BotConfig getBotConfig()
|
||||||
|
{
|
||||||
|
return bot.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
public Veritas getPlugin()
|
public Veritas getPlugin()
|
||||||
{
|
{
|
||||||
return plugin;
|
return plugin;
|
||||||
|
@ -54,20 +54,20 @@ public class ServerListener
|
|||||||
public Mono<Void> minecraftChatBound()
|
public Mono<Void> minecraftChatBound()
|
||||||
{
|
{
|
||||||
return bot.getClient()
|
return bot.getClient()
|
||||||
.getEventDispatcher()
|
.getEventDispatcher()
|
||||||
.on(MessageCreateEvent.class)
|
.on(MessageCreateEvent.class)
|
||||||
.filter(m -> m.getMessage()
|
.filter(m -> m.getMessage()
|
||||||
.getChannelId()
|
.getChannelId()
|
||||||
.equals(bot.getChatChannelId()))
|
.equals(bot.getConfig().getChatChannelId()))
|
||||||
.filter(m -> m.getMember().orElse(null) != null)
|
.filter(m -> m.getMember().orElse(null) != null)
|
||||||
.filter(m -> !m.getMessage()
|
.filter(m -> !m.getMessage()
|
||||||
.getAuthor()
|
.getAuthor()
|
||||||
.orElseThrow(IllegalAccessError::new)
|
.orElseThrow(IllegalAccessError::new)
|
||||||
.getId()
|
.getId()
|
||||||
.equals(plugin.getAggregate().getBot().getClient().getSelfId()))
|
.equals(bot.getClient().getSelfId()))
|
||||||
.doOnError(Aggregate.getLogger()::error)
|
.doOnError(Aggregate.getLogger()::error)
|
||||||
.doOnNext(this::doMessageBodyDetails)
|
.doOnNext(this::doMessageBodyDetails)
|
||||||
.then();
|
.then();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doMessageBodyDetails(MessageCreateEvent m)
|
private void doMessageBodyDetails(MessageCreateEvent m)
|
||||||
@ -81,7 +81,7 @@ public class ServerListener
|
|||||||
.hoverEvent(HoverEvent.showText(
|
.hoverEvent(HoverEvent.showText(
|
||||||
Component.text("Click to join our Discord server!")))
|
Component.text("Click to join our Discord server!")))
|
||||||
.clickEvent(ClickEvent.openUrl(
|
.clickEvent(ClickEvent.openUrl(
|
||||||
plugin.getAggregate().getBot().getInviteLink())))
|
plugin.getAggregate().getBotConfig().getInviteLink())))
|
||||||
.append(Component.text("] ", NamedTextColor.DARK_GRAY));
|
.append(Component.text("] ", NamedTextColor.DARK_GRAY));
|
||||||
TextComponent user = Component.empty();
|
TextComponent user = Component.empty();
|
||||||
|
|
||||||
|
@ -23,16 +23,20 @@
|
|||||||
|
|
||||||
package fns.veritas.client;
|
package fns.veritas.client;
|
||||||
|
|
||||||
import discord4j.common.util.Snowflake;
|
|
||||||
import discord4j.core.DiscordClientBuilder;
|
import discord4j.core.DiscordClientBuilder;
|
||||||
import discord4j.core.GatewayDiscordClient;
|
import discord4j.core.GatewayDiscordClient;
|
||||||
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
||||||
import discord4j.core.object.entity.Guild;
|
import discord4j.core.object.entity.Guild;
|
||||||
import discord4j.core.object.entity.Message;
|
import discord4j.core.object.entity.Message;
|
||||||
|
import discord4j.core.object.entity.PartialMember;
|
||||||
|
import discord4j.core.object.entity.Role;
|
||||||
|
import discord4j.core.object.entity.User;
|
||||||
|
import discord4j.core.object.entity.channel.Channel;
|
||||||
import discord4j.core.object.entity.channel.TextChannel;
|
import discord4j.core.object.entity.channel.TextChannel;
|
||||||
import discord4j.core.spec.MessageCreateSpec;
|
import discord4j.core.spec.MessageCreateSpec;
|
||||||
import fns.veritas.cmd.base.BotCommandHandler;
|
import fns.veritas.cmd.base.BotCommandHandler;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
public class BotClient
|
public class BotClient
|
||||||
@ -58,37 +62,11 @@ public class BotClient
|
|||||||
|
|
||||||
client.on(ChatInputInteractionEvent.class, handler::handle);
|
client.on(ChatInputInteractionEvent.class, handler::handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBotId()
|
|
||||||
{
|
|
||||||
return client.getSelfId().asString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mono<Guild> getServerGuildId()
|
|
||||||
{
|
|
||||||
return client.getGuildById(config.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public GatewayDiscordClient getClient()
|
public GatewayDiscordClient getClient()
|
||||||
{
|
{
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Snowflake getChatChannelId()
|
|
||||||
{
|
|
||||||
return config.getChatChannelId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Snowflake getLogChannelId()
|
|
||||||
{
|
|
||||||
return config.getLogChannelId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInviteLink()
|
|
||||||
{
|
|
||||||
return config.getInviteLink();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void messageChatChannel(String message, boolean system)
|
public void messageChatChannel(String message, boolean system)
|
||||||
{
|
{
|
||||||
String channelID = config.getChatChannelId().asString();
|
String channelID = config.getChatChannelId().asString();
|
||||||
@ -119,7 +97,6 @@ public class BotClient
|
|||||||
|
|
||||||
if (message.contains("@"))
|
if (message.contains("@"))
|
||||||
{
|
{
|
||||||
// \u200B is Zero Width Space, invisible on Discord
|
|
||||||
newMessage = message.replace("@", "@\u200B");
|
newMessage = message.replace("@", "@\u200B");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +121,33 @@ public class BotClient
|
|||||||
return deformat(newMessage);
|
return deformat(newMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Mono<Boolean> isAdmin(final User user)
|
||||||
|
{
|
||||||
|
return getGuild().flatMap(guild -> guild.getMemberById(user.getId()))
|
||||||
|
.flatMapMany(PartialMember::getRoles)
|
||||||
|
.filter(role -> getConfig().getAdminRoleId().asLong() == role.getId().asLong())
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.next()
|
||||||
|
.hasElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Channel> getLogsChannel() {
|
||||||
|
return getGuild().flatMap(guild -> guild.getChannelById(getConfig().getLogChannelId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Channel> getChatChannel() {
|
||||||
|
return getGuild().flatMap(guild -> guild.getChannelById(getConfig().getChatChannelId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Guild> getGuild() {
|
||||||
|
return getClient().getGuildById(getConfig().getGuildId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BotConfig getConfig()
|
||||||
|
{
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
public String deformat(String input)
|
public String deformat(String input)
|
||||||
{
|
{
|
||||||
return input.replaceAll("([_\\\\`*>|])", "\\\\$1");
|
return input.replaceAll("([_\\\\`*>|])", "\\\\$1");
|
||||||
|
@ -39,9 +39,17 @@ import org.jetbrains.annotations.NonNls;
|
|||||||
public class BotConfig
|
public class BotConfig
|
||||||
{
|
{
|
||||||
@NonNls
|
@NonNls
|
||||||
public static final String GUILD_ID = "guild_id";
|
private static final String GUILD_ID = "bot_settings.guild_id";
|
||||||
@NonNls
|
@NonNls
|
||||||
private static final String BOT_TOKEN = "bot_token";
|
private static final String BOT_TOKEN = "bot_settings.bot_token";
|
||||||
|
@NonNls
|
||||||
|
private static final String MC_CHANNEL_ID = "bot_settings.mc_channel_id";
|
||||||
|
@NonNls
|
||||||
|
private static final String LOG_CHANNEL_ID = "bot_settings.log_channel_id";
|
||||||
|
@NonNls
|
||||||
|
private static final String INVITE_LINK = "bot_settings.invite_link";
|
||||||
|
|
||||||
|
|
||||||
private final GenericConfig config;
|
private final GenericConfig config;
|
||||||
|
|
||||||
public BotConfig(final Veritas plugin) throws IOException
|
public BotConfig(final Veritas plugin) throws IOException
|
||||||
@ -54,29 +62,29 @@ public class BotConfig
|
|||||||
return config.getString(BOT_TOKEN);
|
return config.getString(BOT_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPrefix()
|
public Snowflake getGuildId()
|
||||||
{
|
{
|
||||||
return config.getString("bot_prefix");
|
return Snowflake.of(config.getLong(GUILD_ID));
|
||||||
}
|
|
||||||
|
|
||||||
public Snowflake getId()
|
|
||||||
{
|
|
||||||
return Snowflake.of(config.getString(GUILD_ID));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Snowflake getChatChannelId()
|
public Snowflake getChatChannelId()
|
||||||
{
|
{
|
||||||
return Snowflake.of(config.getString("channel_id"));
|
return Snowflake.of(config.getLong(MC_CHANNEL_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Snowflake getLogChannelId()
|
public Snowflake getLogChannelId()
|
||||||
{
|
{
|
||||||
return Snowflake.of(config.getString("log_channel_id"));
|
return Snowflake.of(config.getLong(LOG_CHANNEL_ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Snowflake getAdminRoleId()
|
||||||
|
{
|
||||||
|
return Snowflake.of(config.getLong("admin_settings.admin_role_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInviteLink()
|
public String getInviteLink()
|
||||||
{
|
{
|
||||||
return config.getString("invite_link");
|
return config.getString(INVITE_LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Function<File, FileConfiguration> f0(final Veritas plugin)
|
private Function<File, FileConfiguration> f0(final Veritas plugin)
|
||||||
@ -94,11 +102,10 @@ public class BotConfig
|
|||||||
catch (IOException | InvalidConfigurationException ex)
|
catch (IOException | InvalidConfigurationException ex)
|
||||||
{
|
{
|
||||||
fc.addDefault(BOT_TOKEN, "token");
|
fc.addDefault(BOT_TOKEN, "token");
|
||||||
fc.addDefault("bot_prefix", "!");
|
fc.addDefault(GUILD_ID, 0);
|
||||||
fc.addDefault(GUILD_ID, GUILD_ID);
|
fc.addDefault(MC_CHANNEL_ID, 0);
|
||||||
fc.addDefault("channel_id", "nil");
|
fc.addDefault(LOG_CHANNEL_ID, 0);
|
||||||
fc.addDefault("log_channel_id", "nil");
|
fc.addDefault(INVITE_LINK, "https://discord.gg/invite");
|
||||||
fc.addDefault("invite_link", "https://discord.gg/invite");
|
|
||||||
|
|
||||||
fc.options().copyDefaults(true);
|
fc.options().copyDefaults(true);
|
||||||
|
|
||||||
|
98
Veritas/src/main/java/fns/veritas/cmd/BanCommand.java
Normal file
98
Veritas/src/main/java/fns/veritas/cmd/BanCommand.java
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of FreedomNetworkSuite - https://github.com/SimplexDevelopment/FreedomNetworkSuite
|
||||||
|
* Copyright (C) 2023 Simplex Development and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fns.veritas.cmd;
|
||||||
|
|
||||||
|
|
||||||
|
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
||||||
|
import discord4j.core.object.command.ApplicationCommandInteractionOption;
|
||||||
|
import discord4j.core.object.command.ApplicationCommandInteractionOptionValue;
|
||||||
|
import discord4j.core.object.entity.User;
|
||||||
|
import fns.patchwork.base.Shortcuts;
|
||||||
|
import fns.veritas.Veritas;
|
||||||
|
import fns.veritas.cmd.base.BotCommand;
|
||||||
|
import java.time.Duration;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
public class BanCommand implements BotCommand
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return "ban";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> handle(ChatInputInteractionEvent event)
|
||||||
|
{
|
||||||
|
final String playerName = event.getOption("player")
|
||||||
|
.flatMap(ApplicationCommandInteractionOption::getValue)
|
||||||
|
.map(ApplicationCommandInteractionOptionValue::asString)
|
||||||
|
.orElseThrow();
|
||||||
|
final String reason = event.getOption("reason")
|
||||||
|
.flatMap(ApplicationCommandInteractionOption::getValue)
|
||||||
|
.map(ApplicationCommandInteractionOptionValue::asString)
|
||||||
|
.orElseThrow();
|
||||||
|
final Duration duration = event.getOption("duration")
|
||||||
|
.flatMap(ApplicationCommandInteractionOption::getValue)
|
||||||
|
.map(ApplicationCommandInteractionOptionValue::asLong)
|
||||||
|
.map(Duration::ofMinutes)
|
||||||
|
.orElse(Duration.ofMinutes(5));
|
||||||
|
|
||||||
|
final User user = event.getInteraction().getUser();
|
||||||
|
return Shortcuts.provideModule(Veritas.class)
|
||||||
|
.getAggregate()
|
||||||
|
.getBot()
|
||||||
|
.isAdmin(user)
|
||||||
|
.doOnSuccess(b ->
|
||||||
|
{
|
||||||
|
if (Boolean.FALSE.equals(b))
|
||||||
|
return;
|
||||||
|
|
||||||
|
final Player player = Bukkit.getPlayer(playerName);
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
event.reply()
|
||||||
|
.withEphemeral(true)
|
||||||
|
.withContent("Player not found")
|
||||||
|
.block();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.ban(reason, duration, user.getUsername());
|
||||||
|
event.reply()
|
||||||
|
.withContent("Kicked " + playerName)
|
||||||
|
.withEphemeral(true)
|
||||||
|
.block();
|
||||||
|
|
||||||
|
event.getInteractionResponse()
|
||||||
|
.createFollowupMessage(user.getUsername() + ": Kicked " + playerName)
|
||||||
|
.then();
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
}
|
90
Veritas/src/main/java/fns/veritas/cmd/KickCommand.java
Normal file
90
Veritas/src/main/java/fns/veritas/cmd/KickCommand.java
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of FreedomNetworkSuite - https://github.com/SimplexDevelopment/FreedomNetworkSuite
|
||||||
|
* Copyright (C) 2023 Simplex Development and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fns.veritas.cmd;
|
||||||
|
|
||||||
|
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
||||||
|
import discord4j.core.object.command.ApplicationCommandInteractionOption;
|
||||||
|
import discord4j.core.object.command.ApplicationCommandInteractionOptionValue;
|
||||||
|
import discord4j.core.object.entity.User;
|
||||||
|
import fns.patchwork.base.Shortcuts;
|
||||||
|
import fns.patchwork.kyori.MiniMessageWrapper;
|
||||||
|
import fns.veritas.Veritas;
|
||||||
|
import fns.veritas.cmd.base.BotCommand;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
public class KickCommand implements BotCommand
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return "kick";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> handle(ChatInputInteractionEvent event)
|
||||||
|
{
|
||||||
|
final String playerName = event.getOption("player")
|
||||||
|
.flatMap(ApplicationCommandInteractionOption::getValue)
|
||||||
|
.map(ApplicationCommandInteractionOptionValue::asString)
|
||||||
|
.orElseThrow();
|
||||||
|
final String reason = event.getOption("reason")
|
||||||
|
.flatMap(ApplicationCommandInteractionOption::getValue)
|
||||||
|
.map(ApplicationCommandInteractionOptionValue::asString)
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
|
final User user = event.getInteraction().getUser();
|
||||||
|
return Shortcuts.provideModule(Veritas.class)
|
||||||
|
.getAggregate()
|
||||||
|
.getBot()
|
||||||
|
.isAdmin(user)
|
||||||
|
.doOnSuccess(b ->
|
||||||
|
{
|
||||||
|
if (Boolean.FALSE.equals(b))
|
||||||
|
return;
|
||||||
|
|
||||||
|
final Player player = Bukkit.getPlayer(playerName);
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
event.reply()
|
||||||
|
.withEphemeral(true)
|
||||||
|
.withContent("Player not found")
|
||||||
|
.block();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.kick(MiniMessageWrapper.deserialize(true, reason));
|
||||||
|
event.reply()
|
||||||
|
.withContent("Kicked " + playerName)
|
||||||
|
.withEphemeral(true)
|
||||||
|
.block();
|
||||||
|
|
||||||
|
event.getInteractionResponse()
|
||||||
|
.createFollowupMessage(user.getUsername() + ": Kicked " + playerName)
|
||||||
|
.then();
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
}
|
75
Veritas/src/main/java/fns/veritas/cmd/WhisperCommand.java
Normal file
75
Veritas/src/main/java/fns/veritas/cmd/WhisperCommand.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of FreedomNetworkSuite - https://github.com/SimplexDevelopment/FreedomNetworkSuite
|
||||||
|
* Copyright (C) 2023 Simplex Development and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fns.veritas.cmd;
|
||||||
|
|
||||||
|
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent;
|
||||||
|
import discord4j.core.object.command.ApplicationCommandInteractionOption;
|
||||||
|
import discord4j.core.object.command.ApplicationCommandInteractionOptionValue;
|
||||||
|
import fns.patchwork.kyori.MiniMessageWrapper;
|
||||||
|
import fns.veritas.cmd.base.BotCommand;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
public class WhisperCommand implements BotCommand
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return "whisper";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> handle(ChatInputInteractionEvent event)
|
||||||
|
{
|
||||||
|
final String player = event.getOption("player")
|
||||||
|
.flatMap(ApplicationCommandInteractionOption::getValue)
|
||||||
|
.map(ApplicationCommandInteractionOptionValue::asString)
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
|
final String message = event.getOption("message")
|
||||||
|
.flatMap(ApplicationCommandInteractionOption::getValue)
|
||||||
|
.map(ApplicationCommandInteractionOptionValue::asString)
|
||||||
|
.orElseThrow();
|
||||||
|
final Component c = MiniMessageWrapper.deserialize(true,
|
||||||
|
"<gray>[<yellow>Whisper<gray>] <white>"
|
||||||
|
+ event.getInteraction().getUser().getUsername()
|
||||||
|
+ "<gray>: "
|
||||||
|
+ message);
|
||||||
|
|
||||||
|
final Player actual = Bukkit.getPlayer(player);
|
||||||
|
if (actual == null) {
|
||||||
|
return event.reply("Player not found!")
|
||||||
|
.withEphemeral(true)
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
|
||||||
|
actual.sendMessage(c);
|
||||||
|
|
||||||
|
return event.reply("Sent!")
|
||||||
|
.withEphemeral(true)
|
||||||
|
.then();
|
||||||
|
}
|
||||||
|
}
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Freedom-Network-Suite - https://github.com/AtlasMediaGroup/Freedom-Network-Suite
|
|
||||||
* Copyright (C) 2023 Total Freedom Server Network and contributors
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package fns.veritas.messaging;
|
|
||||||
|
|
||||||
import discord4j.core.object.component.LayoutComponent;
|
|
||||||
import discord4j.core.spec.MessageCreateFields;
|
|
||||||
import discord4j.core.spec.MessageCreateSpec;
|
|
||||||
import discord4j.rest.util.AllowedMentions;
|
|
||||||
|
|
||||||
public class SimpleMessageWrapper
|
|
||||||
{
|
|
||||||
private final MessageCreateSpec.Builder spec;
|
|
||||||
|
|
||||||
public SimpleMessageWrapper()
|
|
||||||
{
|
|
||||||
this.spec = MessageCreateSpec.builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContent(final String content)
|
|
||||||
{
|
|
||||||
this.spec.content(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmbeds(final EmbedWrapper embed)
|
|
||||||
{
|
|
||||||
this.spec.addAllEmbeds(embed.getEmbeds());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttachments(final MessageCreateFields.File... files)
|
|
||||||
{
|
|
||||||
this.spec.addFiles(files);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSpoilerAttachments(final MessageCreateFields.FileSpoiler... files)
|
|
||||||
{
|
|
||||||
this.spec.addFileSpoilers(files);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAllowedMentions(final AllowedMentions allowedMentions)
|
|
||||||
{
|
|
||||||
this.spec.allowedMentions(allowedMentions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLayoutComponents(final LayoutComponent... components)
|
|
||||||
{
|
|
||||||
for (final LayoutComponent component : components)
|
|
||||||
{
|
|
||||||
this.spec.addComponent(component);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
24
Veritas/src/main/resources/commands/ban.json
Normal file
24
Veritas/src/main/resources/commands/ban.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "ban",
|
||||||
|
"description": "Bans a user from the server.",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "player",
|
||||||
|
"description": "The player to ban.",
|
||||||
|
"type": 3,
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reason",
|
||||||
|
"description": "The reason for the ban.",
|
||||||
|
"type": 3,
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "duration",
|
||||||
|
"description": "The duration of the ban, in minutes. Default is 5 minutes.",
|
||||||
|
"type": 4,
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
Veritas/src/main/resources/commands/kick.json
Normal file
18
Veritas/src/main/resources/commands/kick.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "kick",
|
||||||
|
"description": "Kicks a user from the server",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "player",
|
||||||
|
"type": 3,
|
||||||
|
"description": "The player to kick",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "reason",
|
||||||
|
"type": 3,
|
||||||
|
"description": "The reason for kicking the player",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
Veritas/src/main/resources/commands/whisper.json
Normal file
18
Veritas/src/main/resources/commands/whisper.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "whisper",
|
||||||
|
"description": "Whisper to a user.",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "player",
|
||||||
|
"type": 3,
|
||||||
|
"description": "The in-game user to whisper to.",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "message",
|
||||||
|
"type": 3,
|
||||||
|
"description": "The message to send.",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
10
Veritas/src/main/resources/config.toml
Normal file
10
Veritas/src/main/resources/config.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[bot_settings]
|
||||||
|
bot_token = "xyz-123-REPLACE-ME"
|
||||||
|
invite_link = "https://discord.gg/invite"
|
||||||
|
guild_id = 0
|
||||||
|
mc_channel_id = 0
|
||||||
|
log_channel_id = 0
|
||||||
|
|
||||||
|
[admin_settings]
|
||||||
|
# This role will be able to use the /kick and /ban commands.
|
||||||
|
admin_role_id = 0
|
Loading…
Reference in New Issue
Block a user