Это замкнутый цикл. Подозреваю, что проблема в команде входа в канал. Я прикреплю его ниже. Но сколько бы я ни пытался комментировать детали или вносить изменения, бот все равно продолжал замкнутый цикл. Есть еще один файл, управляющий голосовыми соединениями — DiscordManager. Я также прикреплю его ниже.
Присоединиться к каналу — https://pastebin.com/KfWC5wmH (пароль: iF3U23ukPv)\
Код: Выделить всё
package callbot.commands;
import callbot.DiscordManager;
import callbot.Logger;
import callbot.sip.Sip;
import callbot.text.Text;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
import net.dv8tion.jda.api.managers.AudioManager;
import java.util.Arrays;
import java.util.List;
public class JoinChannelCommand extends AbstractCommand {
Sip sip;
public JoinChannelCommand(Sip sipClient) {
sip = sipClient;
}
@Override
public void handle(CommandContext ctx) {
handleStatic(ctx);
}
public static void handleStatic(CommandContext ctx) {
Member member = ctx.getMember(); // Member is the context of the user for the specific guild, containing voice state and roles
GuildVoiceState voiceState = member.getVoiceState(); // Check the current voice state of the user
if (voiceState == null || voiceState.getChannel() == null) {
DiscordManager.sendMessage(Text.z.youArenotConnectedToAnyChannel, 0xFF0000);
return;
}
VoiceChannel channel = voiceState.getChannel(); // Use the channel the user is currently connected to
joinChannel(channel);
}
public static void joinChannel(VoiceChannel voiceChannel) {
if (voiceChannel == null) {
sendErrorStatic(DiscordManager.textChannel, Text.z.youArenotConnectedToAnyChannel);
return;
}
try {
Guild guild = voiceChannel.getGuild();
// Get an audio manager for this guild, this will be created upon first use for each guild
AudioManager audioManager = guild.getAudioManager();
DiscordManager.audioManager = audioManager;
// Set the sending handler to our echo system
audioManager.setSendingHandler(new DiscordManager.EchoHandler());
// Connect to the voice channel
audioManager.openAudioConnection(voiceChannel);
DiscordManager.sendMessage("```" + voiceChannel.getName() + "```"
+ Text.z.readyToCall, Text.z.connectingTo,
(String) null, 0x00FF00, null);
DiscordManager.defaultVoiceChannel = voiceChannel.getId();
DiscordManager.sip.confSession.player.play(DiscordManager.sip.confSession.player.switchChannel);
// DiscordManager.connectedToVoiceChannel = false;
DiscordManager.sip.mongo.update("voiceChannel", voiceChannel.getId());
// sip.dsManager.connectedToVoiceChannel = true;
} catch (InsufficientPermissionException e) {
sendErrorStatic(DiscordManager.textChannel, Text.z.unableToConnectTo + voiceChannel + Text.z.permissionDenied);
} catch (Exception e) {
Logger.log(e);
sendErrorStatic(DiscordManager.textChannel, Text.z.unableToConnectTo + voiceChannel + "``!");
}
}
@Override
public String getName() {
return "Switch voice channel";
}
@Override
public String getHelp() {
return Text.z.switchesChannel;
}
@Override
public List getAliases() {
return Arrays.asList("sw", "v");
}
}
Код: Выделить всё
package callbot;
import callbot.commands.*;
import callbot.sip.*;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.audio.AudioReceiveHandler;
import net.dv8tion.jda.api.audio.AudioSendHandler;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.ReadyEvent;
import net.dv8tion.jda.api.events.guild.GuildJoinEvent;
import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;
import net.dv8tion.jda.api.events.interaction.SelectionMenuEvent;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.managers.AudioManager;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.requests.restaction.MessageAction;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.awt.Color;
import java.nio.ByteBuffer;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
public class DiscordManager extends ListenerAdapter {
public static Sip sip;
public static JDA JDA;
public static AudioManager audioManager;
public static ReceiveHandler receiveHandler;
public static String defaultVoiceChannel = "";
private final CommandManager commandManager;
public static TextChannel textChannel = null;
public static String textChannelId = null;
public static User memberTalking = null;
public static int phoneBookPage = 1;
public DiscordManager(Sip sipClient) {
sip = sipClient;
sip.dsManager = this;
commandManager = new CommandManager(sip);
receiveHandler = new ReceiveHandler();
try {
String token = Config.discordToken;
EnumSet intents = EnumSet.of(
// We need messages in guilds to accept commands from users
GatewayIntent.GUILD_MESSAGES,
// We need voice states to connect to the voice channel
GatewayIntent.GUILD_VOICE_STATES,
GatewayIntent.GUILD_MESSAGE_REACTIONS,
GatewayIntent.GUILD_EMOJIS
);
// Start the JDA session with default mode (voice member cache)
JDA = JDABuilder.createDefault(token, intents) // Use provided token from command line arguments
.addEventListeners(this) // Start listening with this listener
//.enableCache(CacheFlag.VOICE_STATE) // Enable the VOICE_STATE cache to find a user's connected voice channel
.build(); // Login with these options
(new DurationThread()).start();
} catch (Exception e) {
Logger.log(e);
}
}
@Override
public void onReady(@Nonnull ReadyEvent event) {
List list = new ArrayList();
for (Guild guild : event.getJDA().getGuilds()) {
list.add(guild.getId());
}
if (list.size() > 1) {
Logger.log("You have too much servers, I'm done.");
Logger.log(event.getJDA().getGuilds());
// System.exit(1);
}
if (list.size() < 1) {
Logger.log("You have zero servers, I'm done.");
// System.exit(1);
}
String server = list.get(0);
if (!server.equals(Config.guildId)) {
Logger.log("This server is illegal, I'm done.");
Logger.log(server);
Logger.log(event.getJDA().getGuilds());
// System.exit(1);
}
for (Guild guild: event.getJDA().getGuilds()) {
if (!guild.getId().equals(Config.guildId)) {
guild.leave().queue();
}
}
if (!defaultVoiceChannel.equals("")) {
VoiceChannel channel = event.getJDA().getGuilds().get(0).getVoiceChannelById(defaultVoiceChannel);
JoinChannelCommand.joinChannel(channel);
}
if (textChannelId != null) {
textChannel = event.getJDA().getGuilds().get(0).getTextChannelById(textChannelId);
}
for (Guild guild: event.getJDA().getGuilds()) {
SlashCommand.updateCommands(guild);
}
HelloCommand.hello();
}
@Override
public void onGuildJoin(@Nonnull GuildJoinEvent event) {
if (!event.getGuild().getId().equals(Config.guildId)) {
Logger.log("left from " + event.getGuild().getId());
event.getGuild().leave().queue();
}
}
@Override
public void onButtonClick(@NotNull ButtonClickEvent event) {
Buttons.handleEvent(event);
}
@Override
public void onSelectionMenu(@Nonnull SelectionMenuEvent event) {
Menu.handleEvent(event);
}
@Override
public void onSlashCommand(SlashCommandEvent event) {
SlashCommand.handle(event);
}
@Override
public void onGuildMessageReceived(@Nonnull GuildMessageReceivedEvent event)
{
Message message = event.getMessage();
String content = message.getContentRaw();
if (event.getAuthor() == event.getJDA().getSelfUser() || event.isWebhookMessage()) {
return;
}
if (content.equals("set textchannel")) {
TextCommand.set(event.getChannel());
return;
}
if (DiscordManager.textChannel != null
&& !event.getChannel().getId().equals(DiscordManager.textChannel.getId())) {
return;
}
if (content.startsWith(Config.prefix)) {
commandManager.handle(event, Config.prefix);
}
}
public void sendResult(String author, String description, String footer, String url, String avatar, int color) {
if (textChannel == null) {
return;
}
EmbedBuilder eb = new EmbedBuilder();
eb.setAuthor(author, null, avatar);
eb.setDescription(description);
eb.setFooter(footer);
eb.setTimestamp(Instant.now());
eb.setTitle(":inbox_tray: " + "Download" + " :inbox_tray:", url);
eb.setColor(new Color(color));
// Button button = Button.of(ButtonStyle.LINK, url, "Download", Emoji.fromUnicode("U+1F4E5"));
try {
textChannel.sendMessageEmbeds(eb.build()).queue();
} catch (Exception e) {
Logger.log(e);
}
}
public static void sendMessage(String message) {
sendMessage(message, null, null, null, 0x00ff00, null);
}
public static void sendMessage(String message, int color) {
sendMessage(message, null, null, null, color, null);
}
public void sendMessage(String message, MyCall call, int color, ActionRow row) {
sendMessage(message, null, call, color, row);
}
public static void sendMessage(String message, String author, MyCall call, int color, ActionRow row) {
sendMessage(message, author, null, call, color, row);
}
public static void sendMessage(String message, String author, String description, int color, ActionRow row) {
sendMessage(message, author, description, null, color, row);
}
public static void sendMessage(String message, String author, String description, MyCall call, int color, ActionRow row) {
sendMessage(message, author, description, null, false, call, color, row);
}
public static void sendEmbedAndRow(MessageEmbed embed, ActionRow row) {
if (textChannel == null) {
return;
}
try {
MessageAction action = textChannel.sendMessageEmbeds(embed);
if (row == null) {
action.setActionRows().queue();
} else {
action.setActionRows(row).queue();
}
} catch (Exception e) {
Logger.log(e);
}
}
public void sendAvatar(String message, String author, MyCall call, int color, ActionRow row) {
sendAvatar(message, author, null, call, color, row);
}
public static void sendMessage(String message, String footer, int color) {
sendMessage(message, null, null, footer, false, null, color, null);
}
public static void sendMessage(String message, String footer, int color, MyCall call) {
sendMessage(message, null, null, footer, false, call, color, null);
}
public void sendAvatar(String message, String author, String footer, MyCall call, int color, ActionRow row) {
sendMessage(message, author, null, footer, true, call, color, row);
}
public static void sendMessage(String message, String author, String description, String footer,
boolean superAvatar, MyCall call, int color, ActionRow row) {
if (textChannel == null) {
return;
}
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle(message, null);
eb.setColor(new Color(color));
eb.setAuthor(author, null, superAvatar ? getAvatar(call) : null);
eb.setDescription(description);
eb.setFooter(footer);
try {
MessageAction action = textChannel.sendMessageEmbeds(eb.build());
action = row == null ? action.setActionRows() : action.setActionRows(row);
if (call == null) {
action.queue();
} else {
action.queue(msg -> postAction(call, msg));
}
} catch (Exception e) {
Logger.log(e);
}
}
public void sendError(String message) {
sendError(message, null);
}
public void sendError(String message, MyCall call) {
sendMessage(message, null, null, call, 0xFF0000, null);
}
public static void postAction(MyCall call, Message msg) {
try {
if (call.message != null) call.message.delete().queue();
} catch (Exception e) {
Logger.log(e);
}
call.message = msg;
// if (!sip.confSession.calls.contains(call) &&
// !msg.getEmbeds().isEmpty() &&
// msg.getEmbeds().get(0).getAuthor() != null &&
// msg.getEmbeds().get(0).getAuthor().getName() != null &&
// msg.getEmbeds().get(0).getAuthor().getName().contains("Call started")) {
// msg.delete().queue();
// }
}
public static String getName(Member member) {
return member.getNickname() == null ? member.getEffectiveName() : member.getNickname();
}
public static String getAvatar(MyCall call) {
if (DiscordManager.memberTalking != null) {
return DiscordManager.memberTalking.getEffectiveAvatarUrl();
} else if (call != null && call.callBy != null) {
return call.callBy.getUser().getEffectiveAvatarUrl();
}
return null;
}
public static MessageEmbed getEmbed(String message, int color) {
return getEmbed(message, null, null, null, null, color);
}
public static MessageEmbed getEmbed(String message, String author, String description,
String authorIcon, String footer, int color) {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle(message, null);
eb.setColor(new Color(color));
eb.setAuthor(author, null, authorIcon);
eb.setFooter(footer);
eb.setDescription(description);
return eb.build();
}
public static MessageEmbed getEmbed(String message, String author, String description, int color) {
return getEmbed(message, author, description, null, null, color);
}
public static MessageEmbed getEmbed(String message, String author, String authorIcon, String footer, int color) {
return getEmbed(message, author, null, authorIcon, footer, color);
}
public static class EchoHandler implements AudioSendHandler, AudioReceiveHandler
{
public static final Queue phoneSays = new ConcurrentLinkedQueue();
@Override
public boolean canProvide()
{
if (sip.confSession.calls.isEmpty() && !sip.confSession.player.isPlaying()) {
phoneSays.clear();
return false;
}
return !phoneSays.isEmpty();
}
@Override
public ByteBuffer provide20MsAudio()
{
// use what we have in our buffer to send audio as PCM
byte[] data = phoneSays.poll();
if (phoneSays.size() > 8) {
phoneSays.clear();
}
return data == null ? null : ByteBuffer.wrap(data); // Wrap this in a java.nio.ByteBuffer
}
@Override
public boolean isOpus()
{
// since we send audio that is received from discord we don't have opus but PCM
return false;
}
}
}
В чем может быть проблема? как исправить это неприятное явление?
Подробнее здесь: https://stackoverflow.com/questions/788 ... iscord-bot