Я работаю над многопользовательским ботом Discord для игры-викторины, и я столкнулся с проблемой синхронизации таймера обратного отсчета и обработки ответа. Проблема возникает, когда пользователь отправляет ответ, и ответ обрабатывается в течение короткого времени, когда обратный отсчет подходит к концу. Во время перехода между обработкой ответа и завершением обратного отсчета происходит ошибка, которая прерывает тест и приводит систему в сбойное состояние.
Проблема:Когда пользователь отправляет ответ, он обрабатывается, но во время обработки ответа таймер продолжает работать и может уже истечь, что приводит к ошибке.
Ошибка возникает из-за того, что обратный отсчет и обработка ответа выполняются параллельно. и не синхронизированы должным образом. Это приводит к тому, что по истечении времени таймера система оказывается в недопустимом состоянии.
Как лучше синхронизировать обработку ответов с обратным отсчетом, чтобы поток теста не прерывался?
Вот код:
`require('dotenv').config();
const { Client, GatewayIntentBits, ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, Events } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
const questions = [
{
question: "Which chapter is known for their intense rage in battle, especially when near death?",
options: ["Blood Angels", "Space Wolves", "Iron Hands"],
answer: 0,
time: 10
},
{
question: "What are the elite Imperial guards called who wear golden armor and protect the Emperor?",
options: ["Custodes", "Deathwatch", "Grey Knights"],
answer: 0,
time: 10
},
{
question: "What is the armor color of the Ultramarines?",
options: ["Blue", "Red", "Green"],
answer: 0,
time: 10
},
{
question: "Which Space Marine chapter is famously known for being cursed and suffering extreme misfortune in battle?",
options: ["Lamenters", "Blood Angels", "White Scars"],
answer: 0,
time: 10
},
{
question: "Which Space Marine Chapter is known for its focus on protecting the innocent?",
options: ["Salamanders", "Blood Angels", "Space Wolves"],
answer: 0,
time: 10
},
{
question: "Which Primarch is known for having angelic wings?",
options: ["Sanguinius", "Vulkan", "Horus"],
answer: 0,
time: 10
}
];
let leaderboard = {};
let activeQuestionIndex = 0;
let questionMessage = null;
let countdownInterval = null;
let userAnswers = {};
let messageCache = [];
let ephemeralMessages = {
savedAnswers: [],
alreadyAnswered: [],
quizRunningAlert: [] // Nachrichten, dass das Quiz bereits läuft
};
let quizActive = false; // Neue Variable, um zu prüfen, ob ein Quiz läuft
let startButtonMessage = null; // Variable, um die "Start Quiz"-Nachricht zu speichern
client.once('ready', () => {
console.log('Der Bot ist online!');
});
client.on('messageCreate', async message => {
if (message.author.bot) return;
if (message.content === '!startquiz') {
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId('start_quiz')
.setLabel('Start Quiz')
.setStyle(ButtonStyle.Primary)
.setDisabled(quizActive) // Button deaktiviert, wenn ein Quiz läuft
);
startButtonMessage = await message.channel.send({
content: 'Click the button to start the quiz!',
components: [row]
});
}
});
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isButton()) return;
if (interaction.customId === 'start_quiz') {
if (!quizActive) {
quizActive = true; // Markiere das Quiz als aktiv
await startQuiz(interaction.channel);
} else {
const alreadyStartedMessage = await interaction.reply({
content: "A quiz is already running! Please wait until it is finished.",
ephemeral: true
});
ephemeralMessages.quizRunningAlert.push(alreadyStartedMessage); // Speichern der Nachricht, dass das Quiz bereits läuft
}
} else if (interaction.customId.startsWith('answer_')) {
await handleAnswer(interaction);
}
});
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
async function startQuiz(channel) {
leaderboard = {};
activeQuestionIndex = 0;
userAnswers = {};
messageCache = [];
ephemeralMessages = { savedAnswers: [], alreadyAnswered: [], quizRunningAlert: [] };
// Auswahl von 10 zufälligen Fragen
const selectedQuestions = [...questions];
shuffle(selectedQuestions);
const randomQuestions = selectedQuestions.slice(0, 10);
// Fragenliste mit den ausgewählten Fragen ersetzen
questions.length = 0; // Original-Liste leeren
questions.push(...randomQuestions);
await askNextQuestion(channel);
}
async function askNextQuestion(channel) {
if (activeQuestionIndex >= questions.length) {
return showFinalLeaderboard(channel);
}
const question = questions[activeQuestionIndex];
await askQuestion(channel, question);
activeQuestionIndex++;
}
async function askQuestion(channel, question) {
let timeLeft = question.time;
const embed = new EmbedBuilder()
.setTitle("Question")
.setDescription(question.question)
.setFooter({ text: `Time left: ${timeLeft} Seconds` });
const shuffledOptions = [...question.options];
shuffle(shuffledOptions);
const correctAnswerIndex = shuffledOptions.indexOf(question.options[question.answer]);
const row = new ActionRowBuilder();
shuffledOptions.forEach((option, index) => {
row.addComponents(
new ButtonBuilder()
.setCustomId(`answer_${index}`)
.setLabel(option)
.setStyle(ButtonStyle.Primary)
);
});
questionMessage = await channel.send({ embeds: [embed], components: [row] });
messageCache.push(questionMessage);
countdownInterval = setInterval(async () => {
timeLeft--;
const updatedEmbed = EmbedBuilder.from(embed)
.setFooter({ text: `Time left: ${timeLeft} seconds` });
await questionMessage.edit({ embeds: [updatedEmbed] });
if (timeLeft {
updatedRow.addComponents(
new ButtonBuilder()
.setCustomId(`answer_${index}`)
.setLabel(option)
.setStyle(index === correctAnswerIndex ? ButtonStyle.Success : ButtonStyle.Danger)
.setDisabled(true)
);
});
const correctEmoji = "✅";
const wrongEmoji = "❌";
let resultMessage = "";
for (const userId in userAnswers) {
const isCorrect = userAnswers[userId] === correctAnswerIndex;
resultMessage += `: ${isCorrect ? correctEmoji + " **Right!**" : wrongEmoji + " **False!**"}\n`;
if (isCorrect) {
const points = Math.floor(Math.random() * (100 - 0 + 1)) + 0;
leaderboard[userId] = (leaderboard[userId] || 0) + points;
}
}
const embed = EmbedBuilder.from(questionMessage.embeds[0])
.setFooter({ text: "Time's up!" })
.setColor(0xFF0000)
.setDescription(`${question.question}\n\n${resultMessage}`);
await questionMessage.edit({ embeds: [embed], components: [updatedRow] });
userAnswers = {};
setTimeout(async () => {
await askNextQuestion(channel);
}, 5000);
}
async function handleAnswer(interaction) {
const [_, answerIndex] = interaction.customId.split('_');
const answer = parseInt(answerIndex);
if (userAnswers[interaction.user.id] !== undefined) {
const alreadyAnsweredMessage = await interaction.reply({
content: "You have already submitted an answer.",
ephemeral: true
});
ephemeralMessages.alreadyAnswered.push(alreadyAnsweredMessage); // Füge diese Nachricht zu den "bereits geantwortet" Nachrichten hinzu
return;
}
userAnswers[interaction.user.id] = answer;
const updatedRow = new ActionRowBuilder();
questionMessage.components[0].components.forEach((button, index) => {
updatedRow.addComponents(
ButtonBuilder.from(button)
.setStyle(ButtonStyle.Primary)
);
});
const selectedAnswer = questionMessage.components[0].components[answer].label;
const replyMessage = await interaction.reply({
content: `${selectedAnswer} was logged in`,
ephemeral: true
});
ephemeralMessages.savedAnswers.push(replyMessage);
await interaction.message.edit({ components: [updatedRow] });
}
async function showFinalLeaderboard(channel) {
const sortedPlayers = Object.entries(leaderboard).sort((a, b) => b[1] - a[1]).slice(0, 5);
const description = sortedPlayers.map(([userId, score], i) => `${i + 1}. : ${score} Punkte`).join('\n');
const embed = new EmbedBuilder()
.setTitle("🏆 Final score 🏆")
.setDescription(description || "No players.")
.setColor(0xFFD700);
const leaderboardMessage = await channel.send({ embeds: [embed] });
let countdown = 15;
countdownInterval = setInterval(async () => {
await leaderboardMessage.edit({
embeds: [EmbedBuilder.from(embed).setFooter({ text: `End in ${countdown} seconds` })]
});
countdown--;
if (countdown console.error("Fehler beim Löschen der Nachricht:", err));
}
// Lösche alle ephemeren Nachrichten, die für Benutzer sichtbar waren
for (const msg of ephemeralMessages.savedAnswers) {
await msg.delete().catch(err => console.error("Fehler beim Löschen der ephemeren Nachricht:", err));
}
// Lösche die Nachrichten, dass der Benutzer bereits geantwortet hat
for (const msg of ephemeralMessages.alreadyAnswered) {
await msg.delete().catch(err => console.error("Fehler beim Löschen der Nachricht (bereits geantwortet):", err));
}
// Lösche die Nachrichten, dass das Quiz bereits läuft
for (const msg of ephemeralMessages.quizRunningAlert) {
await msg.delete().catch(err => console.error("Fehler beim Löschen der Nachricht (Quiz läuft bereits):", err));
}
// Deaktiviere den Button
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId('start_quiz')
.setLabel('Start Quiz')
.setStyle(ButtonStyle.Primary)
.setDisabled(true)
);
// Deaktiviere den Button in der bestehenden Nachricht
if (startButtonMessage) {
await startButtonMessage.edit({
content: 'The quiz is over. Click to start a new quiz!',
components: [row]
});
}
// Zurücksetzen des Quiz-Status
quizActive = false;
}
client.login(process.env.BOT_TOKEN);`
Обработка ответа занимает больше времени, чем ожидалось, и к моменту обработки ответа пользователя обратный отсчет уже истек. Это приводит к тому, что тест переходит в недопустимое состояние, поскольку система не синхронизируется должным образом по истечении времени таймера.
Я работаю над многопользовательским ботом Discord для игры-викторины, и я столкнулся с проблемой синхронизации таймера обратного отсчета и обработки ответа. Проблема возникает, когда пользователь отправляет ответ, и ответ обрабатывается в течение короткого времени, когда обратный отсчет подходит к концу. Во время перехода между обработкой ответа и завершением обратного отсчета происходит ошибка, которая прерывает тест и приводит систему в сбойное состояние. Проблема:Когда пользователь отправляет ответ, он обрабатывается, но во время обработки ответа таймер продолжает работать и может уже истечь, что приводит к ошибке. Ошибка возникает из-за того, что обратный отсчет и обработка ответа выполняются параллельно. и не синхронизированы должным образом. Это приводит к тому, что по истечении времени таймера система оказывается в недопустимом состоянии. Как лучше синхронизировать обработку ответов с обратным отсчетом, чтобы поток теста не прерывался? Вот код: [code]`require('dotenv').config(); const { Client, GatewayIntentBits, ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, Events } = require('discord.js');
const questions = [ { question: "Which chapter is known for their intense rage in battle, especially when near death?", options: ["Blood Angels", "Space Wolves", "Iron Hands"], answer: 0, time: 10 }, { question: "What are the elite Imperial guards called who wear golden armor and protect the Emperor?", options: ["Custodes", "Deathwatch", "Grey Knights"], answer: 0, time: 10 }, { question: "What is the armor color of the Ultramarines?", options: ["Blue", "Red", "Green"], answer: 0, time: 10 }, { question: "Which Space Marine chapter is famously known for being cursed and suffering extreme misfortune in battle?", options: ["Lamenters", "Blood Angels", "White Scars"], answer: 0, time: 10 }, { question: "Which Space Marine Chapter is known for its focus on protecting the innocent?", options: ["Salamanders", "Blood Angels", "Space Wolves"], answer: 0, time: 10 }, { question: "Which Primarch is known for having angelic wings?", options: ["Sanguinius", "Vulkan", "Horus"], answer: 0, time: 10 } ];
let leaderboard = {}; let activeQuestionIndex = 0; let questionMessage = null; let countdownInterval = null; let userAnswers = {}; let messageCache = []; let ephemeralMessages = { savedAnswers: [], alreadyAnswered: [], quizRunningAlert: [] // Nachrichten, dass das Quiz bereits läuft }; let quizActive = false; // Neue Variable, um zu prüfen, ob ein Quiz läuft let startButtonMessage = null; // Variable, um die "Start Quiz"-Nachricht zu speichern
client.once('ready', () => { console.log('Der Bot ist online!'); });
client.on('messageCreate', async message => { if (message.author.bot) return;
if (message.content === '!startquiz') { const row = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('start_quiz') .setLabel('Start Quiz') .setStyle(ButtonStyle.Primary) .setDisabled(quizActive) // Button deaktiviert, wenn ein Quiz läuft );
startButtonMessage = await message.channel.send({ content: 'Click the button to start the quiz!', components: [row] }); } });
client.on(Events.InteractionCreate, async interaction => { if (!interaction.isButton()) return;
if (interaction.customId === 'start_quiz') { if (!quizActive) { quizActive = true; // Markiere das Quiz als aktiv await startQuiz(interaction.channel); } else { const alreadyStartedMessage = await interaction.reply({ content: "A quiz is already running! Please wait until it is finished.", ephemeral: true });
ephemeralMessages.quizRunningAlert.push(alreadyStartedMessage); // Speichern der Nachricht, dass das Quiz bereits läuft } } else if (interaction.customId.startsWith('answer_')) { await handleAnswer(interaction); } });
function shuffle(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } }
if (countdown console.error("Fehler beim Löschen der Nachricht:", err)); }
// Lösche alle ephemeren Nachrichten, die für Benutzer sichtbar waren for (const msg of ephemeralMessages.savedAnswers) { await msg.delete().catch(err => console.error("Fehler beim Löschen der ephemeren Nachricht:", err)); }
// Lösche die Nachrichten, dass der Benutzer bereits geantwortet hat for (const msg of ephemeralMessages.alreadyAnswered) { await msg.delete().catch(err => console.error("Fehler beim Löschen der Nachricht (bereits geantwortet):", err)); }
// Lösche die Nachrichten, dass das Quiz bereits läuft for (const msg of ephemeralMessages.quizRunningAlert) { await msg.delete().catch(err => console.error("Fehler beim Löschen der Nachricht (Quiz läuft bereits):", err)); }
// Deaktiviere den Button const row = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('start_quiz') .setLabel('Start Quiz') .setStyle(ButtonStyle.Primary) .setDisabled(true) );
// Deaktiviere den Button in der bestehenden Nachricht if (startButtonMessage) { await startButtonMessage.edit({ content: 'The quiz is over. Click to start a new quiz!', components: [row] }); }
// Zurücksetzen des Quiz-Status quizActive = false; }
client.login(process.env.BOT_TOKEN);` [/code] Обработка ответа занимает больше времени, чем ожидалось, и к моменту обработки ответа пользователя обратный отсчет уже истек. Это приводит к тому, что тест переходит в недопустимое состояние, поскольку система не синхронизируется должным образом по истечении времени таймера.
В настоящее время использую Discord 2.4.0 и Python 3.12.1
На моем портале разработки -> Rich Presence -> Rich Presence Assets я загрузил изображение jpg размером 1024x1024 и назвал его «asset_id». . Я обязательно сохранил изменения, и после...
Я строю приложение викторины. В приложении будут вопросы и ответы. User не нужно войти в систему, просто должна заполнять форму (имя, lastname и т. Д.). Пользователь увидит вопросы на слайдах, где он может получить следующую страницу AR предыдущей....
Изо всех сил пытаясь заставить моего бота discord.py работать на Python, я пытался сделать это 50 раз, но безуспешно. Я полон решимости выложить его в Интернет хотя бы один раз. Для достижения этой цели нужны рекомендации и помощь в устранении...
Alright so i have a discord ask command that's supposed to let the user ask any thing and take the input and give it to gemini through the API but it seems to keep returning 0 canidates. I included a try statement only incase the user asks something...
I have a discord ask command that's supposed to let the user ask any thing and take the input and give it to gemini through the API but it seems to keep returning 0 canidates. I included a try statement only incase the user asks something...