fix: rozpierdalał sie przy dodawaniu do kolejki kiedy coś grało

This commit is contained in:
Patryk Koreń
2026-04-06 22:36:56 +02:00
parent 20a36703e6
commit 4fc00493af
8 changed files with 89 additions and 86 deletions

1
history/06-04-2026.json Normal file
View File

@@ -0,0 +1 @@
{"timestamp":1775508648856,"url":"https://www.youtube.com/watch?v=xTemcPZw8Eo","user":"kapitan.papryk"}

1
history/26-02-2026.json Normal file
View File

@@ -0,0 +1 @@
{"timestamp":1772133865649,"url":"https://www.youtube.com/watch?v=TWiOB4lUZrQ","user":"kapitan.papryk"}

View File

@@ -32,10 +32,10 @@ async function execute(interaction: ChatInputCommandInteraction<CacheType>) {
} }
await interaction.editReply(msg_downloading(url)); await interaction.editReply(msg_downloading(url));
await forceRequestSong(interaction, url) forceRequestSong(url, { user: interaction.user.username }).then(() => {
// const msg = getPlayMsg(url)
const msg = getPlayMsg(url) interaction.editReply(msg_play());
await interaction.editReply(msg_play()); })
} catch (error) { } catch (error) {
console.error(error); console.error(error);
await interaction.editReply('Coś poszło nie tak :/'); await interaction.editReply('Coś poszło nie tak :/');

View File

@@ -36,10 +36,9 @@ async function execute(interaction: ChatInputCommandInteraction<CacheType>) {
} }
await interaction.editReply(msg_downloading(url)); await interaction.editReply(msg_downloading(url));
await requestSong(interaction, url) requestSong(url, { user: interaction.user.username }).then(() => {
interaction.editReply(msg_play());
const msg = getPlayMsg(url) })
await interaction.editReply(msg_play());
} catch (error) { } catch (error) {
console.error(error); console.error(error);
await interaction.editReply('Coś poszło nie tak :/'); await interaction.editReply('Coś poszło nie tak :/');

4
src/global.d.ts vendored
View File

@@ -16,7 +16,7 @@ type Queue = {
} }
type HistoryObject = { type HistoryObject = {
interaction: ChatInputCommandInteraction<CacheType> user?: number | string,
url: string url?: string,
} }

View File

@@ -18,24 +18,25 @@ export function toggleLoop(): AudioFile | null {
} }
export async function requestSong( export async function requestSong(
interaction: ChatInputCommandInteraction<CacheType>,
url: string, url: string,
user?: any data: Partial<HistoryObject>
) { ) {
getAudioFile(url).then((path) => {
const path = await getAudioFile(url) queue.songList.push({ path, url })
queue.songList.push({ path, url }) add_to_history({ url, user: data.user })
add_to_history({ interaction, url }) updatePlayer()
updatePlayer() })
} }
export async function forceRequestSong( export async function forceRequestSong(
interaction: ChatInputCommandInteraction<CacheType>, url: string,
url: string) { data: Partial<HistoryObject>
) {
const path = await getAudioFile(url) const path = await getAudioFile(url)
const audio = { path, url } const audio = { path, url }
queue.songList.push(audio) queue.songList.push(audio)
add_to_history({ url, user: data.user })
queue.current = audio queue.current = audio
playSong(player, path); playSong(player, path);
} }

View File

@@ -14,17 +14,17 @@ import { player } from '../main.js';
export async function connectToChannelByInteraction(interaction: ChatInputCommandInteraction<CacheType>): Promise<void> { export async function connectToChannelByInteraction(interaction: ChatInputCommandInteraction<CacheType>): Promise<void> {
const member = await interaction.guild?.members.fetch(interaction.user.id); const member = await interaction.guild?.members.fetch(interaction.user.id);
if (!member) throw new Error("ale chuj") if (!member) throw new Error("ale chuj")
const voiceChannel = member.voice.channel; const voiceChannel = member.voice.channel;
if (!voiceChannel) throw new Error("ale chuj 2") if (!voiceChannel) throw new Error("ale chuj 2")
const connection = await connectToChannel(voiceChannel); const connection = await connectToChannel(voiceChannel);
connection.subscribe(player); connection.subscribe(player);
} }
export async function connectToChannel(channel: VoiceBasedChannel) { export async function connectToChannel(channel: VoiceBasedChannel) {
/** /**
* Here, we try to establish a connection to a voice channel. If we're already connected * Here, we try to establish a connection to a voice channel. If we're already connected
* to this voice channel, \@discordjs/voice will just return the existing connection for us! * to this voice channel, \@discordjs/voice will just return the existing connection for us!
*/ */
const connection = joinVoiceChannel({ const connection = joinVoiceChannel({
channelId: channel.id, channelId: channel.id,
guildId: channel.guild.id, guildId: channel.guild.id,
@@ -32,28 +32,28 @@ export async function connectToChannel(channel: VoiceBasedChannel) {
}); });
/** /**
* If we're dealing with a connection that isn't yet Ready, we can set a reasonable * If we're dealing with a connection that isn't yet Ready, we can set a reasonable
* time limit before giving up. In this example, we give the voice connection 30 seconds * time limit before giving up. In this example, we give the voice connection 30 seconds
* to enter the ready state before giving up. * to enter the ready state before giving up.
*/ */
try { try {
/** /**
* Allow ourselves 30 seconds to join the voice channel. If we do not join within then, * Allow ourselves 30 seconds to join the voice channel. If we do not join within then,
* an error is thrown. * an error is thrown.
*/ */
await entersState(connection, VoiceConnectionStatus.Ready, 30_000); await entersState(connection, VoiceConnectionStatus.Ready, 30_000);
/** /**
* At this point, the voice connection is ready within 30 seconds! This means we can * At this point, the voice connection is ready within 30 seconds! This means we can
* start playing audio in the voice channel. We return the connection so it can be * start playing audio in the voice channel. We return the connection so it can be
* used by the caller. * used by the caller.
*/ */
return connection; return connection;
} catch (error) { } catch (error) {
/** /**
* At this point, the voice connection has not entered the Ready state. We should make * At this point, the voice connection has not entered the Ready state. We should make
* sure to destroy it, and propagate the error by throwing it, so that the calling function * sure to destroy it, and propagate the error by throwing it, so that the calling function
* is aware that we failed to connect to the channel. * is aware that we failed to connect to the channel.
*/ */
connection.destroy(); connection.destroy();
throw error; throw error;
@@ -61,27 +61,31 @@ export async function connectToChannel(channel: VoiceBasedChannel) {
} }
export async function playSong(player: AudioPlayer, songUrl: string) { export async function playSong(player: AudioPlayer, songUrl: string) {
/** try {
* Here we are creating an audio resource using a sample song freely available online /**
* (see https://www.soundhelix.com/audio-examples) * Here we are creating an audio resource using a sample song freely available online
* * (see https://www.soundhelix.com/audio-examples)
* We specify an arbitrary inputType. This means that we aren't too sure what the format of *
* the input is, and that we'd like to have this converted into a format we can use. If we * We specify an arbitrary inputType. This means that we aren't too sure what the format of
* were using an Ogg or WebM source, then we could change this value. However, for now we * the input is, and that we'd like to have this converted into a format we can use. If we
* will leave this as arbitrary. * were using an Ogg or WebM source, then we could change this value. However, for now we
*/ * will leave this as arbitrary.
const resource = createAudioResource(songUrl, { inputType: StreamType.Arbitrary }); */
const resource = createAudioResource(songUrl, { inputType: StreamType.Arbitrary });
/** /**
* We will now play this to the audio player. By default, the audio player will not play until * We will now play this to the audio player. By default, the audio player will not play until
* at least one voice connection is subscribed to it, so it is fine to attach our resource to the * at least one voice connection is subscribed to it, so it is fine to attach our resource to the
* audio player this early. * audio player this early.
*/ */
player.play(resource); player.play(resource);
/** /**
* Here we are using a helper function. It will resolve if the player enters the Playing * Here we are using a helper function. It will resolve if the player enters the Playing
* state within 5 seconds, otherwise it will reject with an error. * state within 5 seconds, otherwise it will reject with an error.
*/ */
return entersState(player, AudioPlayerStatus.Playing, 5_000); return entersState(player, AudioPlayerStatus.Playing, 5_000);
} catch (e) {
console.error(e)
}
} }

View File

@@ -2,32 +2,29 @@ import path from "node:path";
import fs from "node:fs"; import fs from "node:fs";
import { HISTORY_DIR_PATH } from "../main"; import { HISTORY_DIR_PATH } from "../main";
export async function add_to_history(history: HistoryObject) { export async function add_to_history(data: HistoryObject) {
const today = new Date();
const day = String(today.getDate()).padStart(2, '0');
const month = String(today.getMonth() + 1).padStart(2, '0');
const year = today.getFullYear();
const file_name = `${day}-${month}-${year}.json`;
const file_path = path.join(HISTORY_DIR_PATH, file_name)
if (!fs.existsSync(HISTORY_DIR_PATH)) {
fs.mkdirSync(HISTORY_DIR_PATH);
}
let data = [];
try { try {
const content = fs.readFileSync(file_path, 'utf8'); const today = new Date();
data = JSON.parse(content);
} catch (err) { const day = String(today.getDate()).padStart(2, '0');
data = []; const month = String(today.getMonth() + 1).padStart(2, '0');
const year = today.getFullYear();
const file_name = `${day}-${month}-${year}.json`;
const file_path = path.join(HISTORY_DIR_PATH, file_name)
if (!fs.existsSync(HISTORY_DIR_PATH)) {
fs.mkdirSync(HISTORY_DIR_PATH);
}
let history = {
timestamp: today.getTime(),
url: data.url,
user: data.user,
};
fs.writeFileSync(file_path, JSON.stringify(history));
} catch (error) {
console.log(error)
} }
data.push(history)
fs.writeFileSync(file_path, JSON.stringify(data, (key, value) => {
return typeof value === "bigint" ? value.toString() : value
}, 2));
} }