Typescript Continue

This commit is contained in:
Christer Warén 2023-06-06 01:39:35 +03:00
parent 7acabe411b
commit 2d17c33d21
32 changed files with 233 additions and 149 deletions

View File

@ -6,9 +6,9 @@ import Streamer from "./client/classes/Streamer";
import Statistics from "./client/classes/Statistics"; import Statistics from "./client/classes/Statistics";
import { command } from "./client/commands"; import { command } from "./client/commands";
import config from "./config"; import config from "./config";
import messages from "./client/messages"; import { messages } from "./client/messages";
import events from "./client/events" import { events } from "./client/events"
import funcs from "./client/funcs"; import { funcs } from "./client/funcs";
const GatewayIntents = new IntentsBitField(); const GatewayIntents = new IntentsBitField();
GatewayIntents.add( GatewayIntents.add(
@ -19,8 +19,8 @@ GatewayIntents.add(
export default class RadioClient extends Client { export default class RadioClient extends Client {
readonly commands: Collection<string, command>; readonly commands: Collection<string, command>;
public events: any; readonly events = events;
public funcs: any; readonly funcs = funcs;
readonly config = config; readonly config = config;
readonly messages = messages; readonly messages = messages;
public datastore: Datastore | null; public datastore: Datastore | null;
@ -43,9 +43,6 @@ export default class RadioClient extends Client {
this.radio = null; this.radio = null;
this.messageEmojis = null; this.messageEmojis = null;
this.events = events;
this.funcs = funcs;
console.log('RadioX ' + this.config.version); console.log('RadioX ' + this.config.version);
console.log('Internet Radio to your Discord guild'); console.log('Internet Radio to your Discord guild');
console.log('(c)2020-2022 EximiaBots by Warén Group'); console.log('(c)2020-2022 EximiaBots by Warén Group');
@ -73,7 +70,7 @@ export default class RadioClient extends Client {
}); });
this.on("error", error => { this.on("error", error => {
this.funcs.logger("Discord Client / Error"); this.funcs.logger("Discord Client", "Error");
console.error(error); console.error(error);
console.log(''); console.log('');
}); });
@ -99,7 +96,7 @@ export default class RadioClient extends Client {
}); });
this.login(this.config.token).catch((err) => { this.login(this.config.token).catch((err) => {
this.funcs.logger("Discord Client / Error"); this.funcs.logger("Discord Client", "Login Error");
console.log(err); console.log(err);
console.log(''); console.log('');
}); });

View File

@ -28,7 +28,8 @@ export default class {
//console.log(""); //console.log("");
} }
checkEntry(id: string){ checkEntry(id: string | undefined){
if(!id) return;
this.loadEntry(id); this.loadEntry(id);
if(!this.map.has(id)){ if(!this.map.has(id)){
this.createEntry(id); this.createEntry(id);

View File

@ -1,5 +1,5 @@
import { getVoiceConnection, joinVoiceChannel } from "@discordjs/voice"; import { getVoiceConnection, joinVoiceChannel } from "@discordjs/voice";
import { VoiceChannel } from "discord.js"; import { Guild, GuildMember, VoiceChannel } from "discord.js";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
export default class Radio extends Map { export default class Radio extends Map {
@ -32,13 +32,13 @@ export default class Radio extends Map {
restore(client: RadioClient, guilds: any) { restore(client: RadioClient, guilds: any) {
if(!client.stations) return; if(!client.stations) return;
guilds.forEach(async (guild: { id: any; }) => { guilds.forEach(async (guild: Guild) => {
let state = client.funcs.loadState(client, guild); let state = client.funcs.loadState(client, guild);
if(!state) return; if(!state) return;
if(!state.station || !state.channels.voice || !state.channels.text) return; if(!state.station || !state.channels.voice || !state.channels.text) return;
let voiceChannel = client.channels.cache.get(state.channels.voice); let voiceChannel = client.channels.cache.get(state.channels.voice);
if(!voiceChannel) return; if(!voiceChannel || !(voiceChannel instanceof VoiceChannel)) return;
if(voiceChannel.members.filter((member: { user: { bot: any; }; }) => !member.user.bot).size === 0) return; if(voiceChannel.members.filter((member: GuildMember) => !member.user.bot).size === 0) return;
const sstation = await client.stations?.search(state.station.name, "direct"); const sstation = await client.stations?.search(state.station.name, "direct");

View File

@ -3,17 +3,23 @@ const _importDynamic = new Function('modulePath', 'return import(modulePath)');
const fetch = (...args: any) => _importDynamic('node-fetch').then(({default: fetch}) => fetch(...args)); const fetch = (...args: any) => _importDynamic('node-fetch').then(({default: fetch}) => fetch(...args));
import logger from "../funcs/logger"; import logger from "../funcs/logger";
export interface station {
name: string,
owner: string,
logo: string,
stream: []
}
export default class Stations extends Array { export default class Stations extends Array {
logger: any; logger: any;
constructor() { constructor() {
super(); super();
this.logger = logger;
} }
async fetch(options: any){ async fetch(options: any){
try { try {
this.logger('Stations', 'Started fetching list - ' + options.url); logger('Stations', 'Started fetching list - ' + options.url);
let list = await fetch(options.url) let list = await fetch(options.url)
.then(this.checkFetchStatus) .then(this.checkFetchStatus)
.then((response: { json: () => any; }) => response.json()); .then((response: { json: () => any; }) => response.json());
@ -30,7 +36,7 @@ export default class Stations extends Array {
if(options.show){ if(options.show){
list.forEach((station: { name: any; }) => { list.forEach((station: { name: any; }) => {
this.logger('Stations', station.name); logger('Stations', station.name);
}); });
} }
@ -45,9 +51,9 @@ export default class Stations extends Array {
}); });
} }
this.logger('Stations', 'Successfully fetched list'); logger('Stations', 'Successfully fetched list');
} catch (error) { } catch (error) {
this.logger('Stations', 'Fetching list failed'); logger('Stations', 'Fetching list failed');
console.error(error + "\n"); console.error(error + "\n");
if(this.length == 0) this.fetch(options); if(this.length == 0) this.fetch(options);

View File

@ -8,7 +8,8 @@ export default class Statistics {
this.map = new Map(); this.map = new Map();
} }
update(client: RadioClient, guild: Guild, radio: any) { update(client: RadioClient, guild: Guild | null, radio: any) {
if(!guild) return;
client.datastore?.checkEntry(guild.id); client.datastore?.checkEntry(guild.id);
@ -47,18 +48,18 @@ export default class Statistics {
let currentGuild = client.datastore.getEntry(calculation.value); let currentGuild = client.datastore.getEntry(calculation.value);
if(calculation.value != 'global'){ if(calculation.value != 'global'){
if(stations){ if(stations){
Object.keys(stations).forEach(function(station) { for(const station of stations) {
if(currentGuild.statistics[stations[station].name] && currentGuild.statistics[stations[station].name].time && parseInt(currentGuild.statistics[stations[station].name].time) != 0 && currentGuild.statistics[stations[station].name].used && parseInt(currentGuild.statistics[stations[station].name].used) != 0){ if(currentGuild.statistics[station.name] && currentGuild.statistics[station.name].time && parseInt(currentGuild.statistics[station.name].time) != 0 && currentGuild.statistics[station.name].used && parseInt(currentGuild.statistics[station.name].used) != 0){
if(!statistics[stations[station].name]){ if(!statistics[station.name]){
statistics[stations[station].name] = {}; statistics[station.name] = {};
statistics[stations[station].name].time = 0; statistics[station.name].time = 0;
statistics[stations[station].name].used = 0; statistics[station.name].used = 0;
} }
statistics[stations[station].name].time = parseInt(statistics[stations[station].name].time)+parseInt(currentGuild.statistics[stations[station].name].time); statistics[station.name].time = parseInt(statistics[station.name].time)+parseInt(currentGuild.statistics[station.name].time);
statistics[stations[station].name].used = parseInt(statistics[stations[station].name].used)+parseInt(currentGuild.statistics[stations[station].name].used); statistics[station.name].used = parseInt(statistics[station.name].used)+parseInt(currentGuild.statistics[station.name].used);
} }
}); }
} }
} }
calculation = guilds.next(); calculation = guilds.next();

View File

@ -10,7 +10,6 @@ export default class Streamer {
constructor() { constructor() {
this.map = new Map(); this.map = new Map();
this.mode = null; this.mode = null;
this.logger = logger;
} }
init(client: RadioClient){ init(client: RadioClient){
@ -73,25 +72,25 @@ export default class Streamer {
audioPlayer.play(resource); audioPlayer.play(resource);
audioPlayer audioPlayer
.on('playing', () => { .on('playing', () => {
this.logger('Streamer', station.name + " / " + "Playing"); logger('Streamer', station.name + " / " + "Playing");
}) })
.on('idle', () => { .on('idle', () => {
this.logger('Streamer', station.name + " / " + "Idle"); logger('Streamer', station.name + " / " + "Idle");
audioPlayer.removeAllListeners(); audioPlayer.removeAllListeners();
if(this.mode == "manual" && audioPlayer.subscribers.length == 0) return; if(this.mode == "manual" && audioPlayer.subscribers.length == 0) return;
this.play(station); this.play(station);
}) })
.on('paused', () => { .on('paused', () => {
this.logger('Streamer', station.name + " / " + "Paused"); logger('Streamer', station.name + " / " + "Paused");
}) })
.on('buffering', () => { .on('buffering', () => {
this.logger('Streamer', station.name + " / " + "Buffering"); logger('Streamer', station.name + " / " + "Buffering");
}) })
.on('autopaused', () => { .on('autopaused', () => {
this.logger('Streamer', station.name + " / " + "AutoPaused"); logger('Streamer', station.name + " / " + "AutoPaused");
}) })
.on('error', (error: string) => { .on('error', (error: string) => {
this.logger('Streamer', station.name + " / " + "Error" + "\n" + error); logger('Streamer', station.name + " / " + "Error" + "\n" + error);
}); });
return audioPlayer; return audioPlayer;
} }
@ -99,7 +98,7 @@ export default class Streamer {
stop(station: any){ stop(station: any){
let audioPlayer = this.map.get(station.name); let audioPlayer = this.map.get(station.name);
if(audioPlayer){ if(audioPlayer){
this.logger('Streamer', station.name + " / " + "Stop"); logger('Streamer', station.name + " / " + "Stop");
audioPlayer.removeAllListeners(); audioPlayer.removeAllListeners();
audioPlayer.stop(); audioPlayer.stop();
} }

View File

@ -6,6 +6,11 @@ export default {
description: 'Report a bug', description: 'Report a bug',
category: 'info', category: 'info',
async execute(interaction: ChatInputCommandInteraction, client: RadioClient) { async execute(interaction: ChatInputCommandInteraction, client: RadioClient) {
if(!client.user) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
let message : any = {}; let message : any = {};
message.bugTitle = client.messages.bugTitle.replace("%client.user.username%", client.user.username); message.bugTitle = client.messages.bugTitle.replace("%client.user.username%", client.user.username);

View File

@ -6,6 +6,12 @@ export default {
description: 'Get help using bot', description: 'Get help using bot',
category: 'info', category: 'info',
execute(interaction: ChatInputCommandInteraction, client: RadioClient) { execute(interaction: ChatInputCommandInteraction, client: RadioClient) {
if(!client.user) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
let message: any = {}; let message: any = {};
const categories : any= []; const categories : any= [];
@ -14,10 +20,10 @@ export default {
} }
let commands = ''; let commands = '';
for (let i = 0; i < categories.length; i++) { for (let i = 0; i < categories.length; i++) {
commands += `**» ${categories[i].toUpperCase()}**\n${client.commands.filter((x: { category: any; omitFromHelp: any; }) => x.category === categories[i] && !x.omitFromHelp).map((x: { name: any; }) => `\`${x.name}\``).join(', ')}\n`; commands += `**» ${categories[i].toUpperCase()}**\n${client.commands.filter(x => x.category === categories[i]).map((x: { name: any; }) => `\`${x.name}\``).join(', ')}\n`;
} }
message.helpTitle = client.messages.helpTitle.replace("%client.user.username%", client.user.username); message.helpTitle = client.messages.helpTitle.replace("%client.user.username%", client.user?.username || "-");
message.helpDescription = client.messages.helpDescription.replace("%commands%", commands); message.helpDescription = client.messages.helpDescription.replace("%commands%", commands);
const embed = new EmbedBuilder() const embed = new EmbedBuilder()

View File

@ -6,6 +6,12 @@ export default {
description: 'Invite Bot', description: 'Invite Bot',
category: 'info', category: 'info',
execute(interaction: ChatInputCommandInteraction, client: RadioClient) { execute(interaction: ChatInputCommandInteraction, client: RadioClient) {
if(!client.user) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
let message: any = {}; let message: any = {};
message.inviteTitle = client.messages.inviteTitle.replace("%client.user.username%", client.user.username); message.inviteTitle = client.messages.inviteTitle.replace("%client.user.username%", client.user.username);
const embed = new EmbedBuilder() const embed = new EmbedBuilder()

View File

@ -16,7 +16,7 @@ export default {
}); });
} }
const radio = client.radio?.get(interaction.guild.id); const radio = client.radio?.get(interaction.guild?.id);
if(radio && !client.config.maintenanceMode){ if(radio && !client.config.maintenanceMode){
client.funcs.listStations(client, interaction); client.funcs.listStations(client, interaction);

View File

@ -1,4 +1,4 @@
import { ActionRowBuilder, ButtonInteraction, ChatInputCommandInteraction, ColorResolvable, EmbedBuilder, StringSelectMenuBuilder, StringSelectMenuInteraction } from "discord.js"; import { ActionRowBuilder, AnyComponentBuilder, APIActionRowComponent, APISelectMenuOption, ButtonInteraction, ChatInputCommandInteraction, ColorResolvable, EmbedBuilder, StringSelectMenuBuilder, StringSelectMenuInteraction } from "discord.js";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
import Streamer from "../classes/Streamer"; import Streamer from "../classes/Streamer";
import commands from "../commands"; import commands from "../commands";
@ -17,62 +17,95 @@ export default {
content: client.messageEmojis["error"] + client.messages.notAllowed, content: client.messageEmojis["error"] + client.messages.notAllowed,
ephemeral: true ephemeral: true
}); });
let action = interaction.options?.getNumber("action") ?? interaction.values?.[0];
const options: any = new Array( let action : number | string | null = null;
if(interaction.isChatInputCommand()){
action = interaction.options?.getNumber("action");
}
if(interaction.isStringSelectMenu()){
action = interaction.values?.[0];
}
const options: APISelectMenuOption[] = new Array(
{ {
emoji: "🌀", emoji: {
"name": "🌀",
},
label: "Restart Bot", label: "Restart Bot",
value: "0" value: "0"
}, },
{ {
emoji: "<:RadioXStop:688541155377414168>", emoji: {
id: "688541155377414168",
name: "RadioXStop",
},
label: "Save Radios", label: "Save Radios",
value: "4" value: "4"
}, },
{ {
emoji: "<:RadioXPlay:688541155712827458>", emoji: {
id: "688541155712827458",
name: "RadioXPlay",
},
label: "Restore Radios", label: "Restore Radios",
value: "5" value: "5"
}, },
{ {
emoji: "#️⃣", emoji: {
name: "#️⃣",
},
label: "Reload Commands", label: "Reload Commands",
value: "6" value: "6"
}, },
{ {
emoji: "<:RadioXList:688541155519889482>", emoji: {
id: "688541155519889482",
name: "RadioXList",
},
label: "Reload Stations", label: "Reload Stations",
value: "7" value: "7"
}, },
{ {
emoji: "<:dnd:746069698139127831>", emoji: {
id: "746069698139127831",
name: "dnd",
},
label: "Enable Maintenance Mode", label: "Enable Maintenance Mode",
value: "8" value: "8"
}, },
{ {
emoji: "<:online:746069731836035098>", emoji: {
id: "746069731836035098",
name: "online",
},
label: "Disable Maintenance Mode", label: "Disable Maintenance Mode",
value: "9" value: "9"
}, },
{ {
emoji: "💤", emoji: {
name: "💤",
},
label: "Streamer Mode - Manual", label: "Streamer Mode - Manual",
value: "10" value: "10"
}, },
{ {
emoji: "📡", emoji: {
name: "📡",
},
label: "Streamer Mode - Auto", label: "Streamer Mode - Auto",
value: "11" value: "11"
} }
); );
const menu = new ActionRowBuilder() const menu : ActionRowBuilder<any> = new ActionRowBuilder()
.addComponents( .addComponents(
new StringSelectMenuBuilder() new StringSelectMenuBuilder()
.setCustomId('maintenance') .setCustomId('maintenance')
.setPlaceholder('Select action') .setPlaceholder('Select action')
.addOptions(options) .addOptions(options)
); );
if(!action){ if(!action){
return interaction.reply({ return interaction.reply({
@ -82,12 +115,12 @@ export default {
}); });
} }
client.funcs.logger('Maintenance', options.find((option: { value: any; }) => option.value == action).label); client.funcs.logger('Maintenance', options.find((option: APISelectMenuOption) => option.value == action)?.label);
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle(client.messages.maintenanceTitle) .setTitle(client.messages.maintenanceTitle)
.setColor(client.config.embedColor as ColorResolvable) .setColor(client.config.embedColor as ColorResolvable)
.setDescription(options.find((option: { value: any; }) => option.value == action).label) .setDescription(options.find((option: APISelectMenuOption) => option.value == action)?.label || "-")
.setFooter({ .setFooter({
text: client.messages.footerText, text: client.messages.footerText,
iconURL: "https://cdn.discordapp.com/emojis/" + client.messageEmojis["eximiabots"].replace(/[^0-9]+/g, '') iconURL: "https://cdn.discordapp.com/emojis/" + client.messageEmojis["eximiabots"].replace(/[^0-9]+/g, '')
@ -107,43 +140,43 @@ export default {
break; break;
case "4": case "4":
client.config.maintenanceMode = true; client.config.maintenanceMode = true;
client.user.setStatus('idle'); client.user?.setStatus('idle');
client.radio.save(client); client.radio?.save(client);
client.user.setStatus('online'); client.user?.setStatus('online');
client.config.maintenanceMode = false; client.config.maintenanceMode = false;
break; break;
case "5": case "5":
client.config.maintenanceMode = true; client.config.maintenanceMode = true;
client.user.setStatus('idle'); client.user?.setStatus('idle');
client.radio.restore(client, guilds); client.radio?.restore(client, guilds);
client.user.setStatus('online'); client.user?.setStatus('online');
client.config.maintenanceMode = false; client.config.maintenanceMode = false;
break; break;
case "6": case "6":
client.config.maintenanceMode = true; client.config.maintenanceMode = true;
client.user.setStatus('idle'); client.user?.setStatus('idle');
commands.execute(client); commands.execute(client);
client.user.setStatus('online'); client.user?.setStatus('online');
client.config.maintenanceMode = false; client.config.maintenanceMode = false;
break; break;
case "7": case "7":
try { try {
client.stations.fetch({ client.stations?.fetch({
url: client.config.stationslistUrl url: client.config.stationslistUrl
}); });
client.streamer.refresh(client); client.streamer?.refresh(client);
} catch (error) { } catch (error) {
} }
break; break;
case "8": case "8":
client.user.setStatus('dnd'); client.user?.setStatus('dnd');
client.funcs.logger("Maintenance Mode", "Enabled"); client.funcs.logger("Maintenance Mode", "Enabled");
client.config.maintenanceMode = true; client.config.maintenanceMode = true;
break; break;
case "9": case "9":
client.user.setStatus('online'); client.user?.setStatus('online');
client.funcs.logger("Maintenance Mode", "Disabled"); client.funcs.logger("Maintenance Mode", "Disabled");
client.config.maintenanceMode = false; client.config.maintenanceMode = false;
break; break;
@ -151,17 +184,17 @@ export default {
client.config.streamerMode = "manual"; client.config.streamerMode = "manual";
client.config.maintenanceMode = true; client.config.maintenanceMode = true;
client.user.setStatus('idle'); client.user?.setStatus('idle');
client.radio.save(client); client.radio?.save(client);
setInterval(() => { setInterval(() => {
if(client.radio.size == 0 && client.config.streamerMode == "manual" && client.config.maintenanceMode){ if(client.radio?.size == 0 && client.config.streamerMode == "manual" && client.config.maintenanceMode){
client.streamer.leave(client); client.streamer?.leave(client);
client.streamer = new Streamer(); client.streamer = new Streamer();
client.streamer.init(client); client.streamer.init(client);
client.radio.restore(client, guilds); client.radio?.restore(client, guilds);
client.user.setStatus('online'); client.user?.setStatus('online');
client.config.maintenanceMode = false; client.config.maintenanceMode = false;
} }
@ -175,17 +208,17 @@ export default {
client.config.streamerMode = "auto"; client.config.streamerMode = "auto";
client.config.maintenanceMode = true; client.config.maintenanceMode = true;
client.user.setStatus('idle'); client.user?.setStatus('idle');
client.radio.save(client); client.radio?.save(client);
setInterval(() => { setInterval(() => {
if(client.radio.size == 0 && client.config.streamerMode == "auto" && client.config.maintenanceMode){ if(client.radio?.size == 0 && client.config.streamerMode == "auto" && client.config.maintenanceMode){
client.streamer.leave(client); client.streamer?.leave(client);
client.streamer = new Streamer(); client.streamer = new Streamer();
client.streamer.init(client); client.streamer.init(client);
client.radio.restore(client, guilds); client.radio.restore(client, guilds);
client.user.setStatus('online'); client.user?.setStatus('online');
client.config.maintenanceMode = false; client.config.maintenanceMode = false;
} }

View File

@ -1,5 +1,6 @@
import { ButtonInteraction, ChatInputCommandInteraction, StringSelectMenuInteraction } from "discord.js"; import { ButtonInteraction, ChatInputCommandInteraction, StringSelectMenuInteraction } from "discord.js";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
import { station } from "../classes/Stations"
export default { export default {
name: 'next', name: 'next',
@ -7,10 +8,15 @@ export default {
category: 'radio', category: 'radio',
async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: any) { async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: any) {
if (client.funcs.check(client, interaction, command)) { if (client.funcs.check(client, interaction, command)) {
const radio = client.radio.get(interaction.guild.id); const radio = client.radio?.get(interaction.guild?.id);
let index = client.stations.findIndex((station: { name: any; }) => station.name == radio.station.name) + 1; if(!client.stations) return interaction.reply({
if(index == client.stations.length) index = 0; content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
let index: number = client.stations.findIndex((station: station) => station.name == radio.station.name) + 1;
if(index == client.stations?.length) index = 0;
let station = client.stations[index]; let station = client.stations[index];
@ -19,7 +25,7 @@ export default {
ephemeral: true ephemeral: true
}); });
client.statistics.update(client, interaction.guild, radio); client.statistics?.update(client, interaction.guild, radio);
let date = new Date(); let date = new Date();
radio.station = station; radio.station = station;

View File

@ -6,9 +6,9 @@ export default {
description: 'Current Radio Station', description: 'Current Radio Station',
category: 'radio', category: 'radio',
async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: any) { async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: any) {
if (client.funcs.check(client, interaction, command)) { if(client.funcs.check(client, interaction, command)) {
let message: any = {}; let message: any = {};
const radio = client.radio?.get(interaction.guild.id); const radio = client.radio?.get(interaction.guild?.id);
let date = new Date(); let date = new Date();
radio.currentTime = date.getTime(); radio.currentTime = date.getTime();

View File

@ -1,4 +1,4 @@
import { ApplicationCommandOptionType, ButtonInteraction, ChatInputCommandInteraction, PermissionFlagsBits, StringSelectMenuInteraction } from "discord.js"; import { ApplicationCommandOptionType, ChatInputCommandInteraction, GuildMember, PermissionFlagsBits, StringSelectMenuInteraction } from "discord.js";
import { getVoiceConnection, joinVoiceChannel } from "@discordjs/voice"; import { getVoiceConnection, joinVoiceChannel } from "@discordjs/voice";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
@ -10,16 +10,9 @@ export default {
{ type: ApplicationCommandOptionType.String, name: "query", description: "Select station", required: false} { type: ApplicationCommandOptionType.String, name: "query", description: "Select station", required: false}
], ],
category: "radio", category: "radio",
async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) { async execute(interaction: ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) {
let message: any = {}; let message: any = {};
if(client.config.maintenanceMode){
return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
}
if(!client.stations) { if(!client.stations) {
message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild); message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild);
return interaction.reply({ return interaction.reply({
@ -28,13 +21,23 @@ export default {
}); });
} }
let query = interaction.options?.getString("query") ?? interaction.values?.[0]; let query : number | string | null = null;
if(interaction.isChatInputCommand()){
query = interaction.options?.getNumber("query");
}
if(interaction.isStringSelectMenu()){
query = interaction.values?.[0];
}
if(!query){ if(!query){
return client.funcs.listStations(client, interaction); return client.funcs.listStations(client, interaction);
} }
const radio = client.radio.get(interaction.guild.id); const radio = client.radio?.get(interaction.guild?.id);
const voiceChannel = interaction.member.voice.channel; if(!(interaction.member instanceof GuildMember)) return;
const voiceChannel = interaction.member?.voice.channel;
if (!voiceChannel) return interaction.reply({ if (!voiceChannel) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.noVoiceChannel, content: client.messageEmojis["error"] + client.messages.noVoiceChannel,
ephemeral: true ephemeral: true
@ -50,13 +53,13 @@ export default {
ephemeral: true ephemeral: true
}); });
const permissions = voiceChannel.permissionsFor(interaction.client.user); const permissions = voiceChannel.permissionsFor(interaction.client.user);
if (!permissions.has(PermissionFlagsBits.Connect)) { if (!permissions?.has(PermissionFlagsBits.Connect)) {
return interaction.reply({ return interaction.reply({
content: client.messageEmojis["error"] + client.messages.noPermsConnect, content: client.messageEmojis["error"] + client.messages.noPermsConnect,
ephemeral: true ephemeral: true
}); });
} }
if (!permissions.has(PermissionFlagsBits.Speak)) { if (!permissions?.has(PermissionFlagsBits.Speak)) {
return interaction.reply({ return interaction.reply({
content: client.messageEmojis["error"] + client.messages.noPermsSpeak, content: client.messageEmojis["error"] + client.messages.noPermsSpeak,
ephemeral: true ephemeral: true
@ -64,7 +67,7 @@ export default {
} }
let station; let station;
if (!isNaN(query)) { if (typeof query === 'number') {
const number = parseInt((query - 1) as unknown as string); const number = parseInt((query - 1) as unknown as string);
if (number > client.stations.length - 1) { if (number > client.stations.length - 1) {
return interaction.reply({ return interaction.reply({
@ -75,17 +78,20 @@ export default {
station = client.stations[number]; station = client.stations[number];
} }
} else { } else {
if (query.length < 3) return interaction.reply({ if(!(typeof query === 'string')) return;
if(query.length < 3) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.tooShortSearch, content: client.messageEmojis["error"] + client.messages.tooShortSearch,
ephemeral: true ephemeral: true
}); });
let type = ""; let type = "";
if(interaction.values?.[0]){ if(interaction.isStringSelectMenu()){
type = "direct"; if(interaction.values?.[0]){
} else { type = "direct";
type = "text"; } else {
type = "text";
}
} }
const sstation = await client.stations.search(query, type); const sstation = await client.stations.search(query, type);
@ -97,7 +103,7 @@ export default {
} }
if (radio) { if (radio) {
client.statistics.update(client, interaction.guild, radio); client.statistics?.update(client, interaction.guild, radio);
let date = new Date(); let date = new Date();
radio.station = station; radio.station = station;
@ -117,7 +123,7 @@ export default {
station: station, station: station,
startTime: date.getTime() startTime: date.getTime()
}; };
client.radio.set(interaction.guild.id, construct); client.radio?.set(interaction.guild?.id, construct);
try { try {
const connection = const connection =
@ -130,11 +136,11 @@ export default {
construct.connection = connection; construct.connection = connection;
let date = new Date(); let date = new Date();
construct.startTime = date.getTime(); construct.startTime = date.getTime();
client.datastore.checkEntry(interaction.guild.id); client.datastore?.checkEntry(interaction.guild?.id);
client.funcs.play(client, interaction, interaction.guild, station); client.funcs.play(client, interaction, interaction.guild, station);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
client.radio.delete(interaction.guild.id); client.radio?.delete(interaction.guild?.id);
return interaction.reply({ return interaction.reply({
content: client.messageEmojis["error"] + `An error occured: ${error}`, content: client.messageEmojis["error"] + `An error occured: ${error}`,
ephemeral: true ephemeral: true

View File

@ -1,6 +1,7 @@
import { ButtonInteraction, ChatInputCommandInteraction, StringSelectMenuInteraction } from "discord.js"; import { ButtonInteraction, ChatInputCommandInteraction, StringSelectMenuInteraction } from "discord.js";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
import { command } from "../commands"; import { command } from "../commands";
import { station } from "../classes/Stations"
export default { export default {
name: 'prev', name: 'prev',
@ -8,9 +9,14 @@ export default {
category: 'radio', category: 'radio',
async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: command) { async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: command) {
if (client.funcs.check(client, interaction, command)) { if (client.funcs.check(client, interaction, command)) {
const radio = client.radio.get(interaction.guild.id); const radio = client.radio?.get(interaction.guild?.id);
let index = client.stations.findIndex((station: { name: any; }) => station.name == radio.station.name) - 1; if(!client.stations) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
let index = client.stations.findIndex((station: station) => station.name == radio.station.name) - 1;
if(index == -1) index = client.stations.length - 1; if(index == -1) index = client.stations.length - 1;
let station = client.stations[index]; let station = client.stations[index];
@ -20,7 +26,7 @@ export default {
ephemeral: true ephemeral: true
}); });
client.statistics.update(client, interaction.guild, radio); client.statistics?.update(client, interaction.guild, radio);
let date = new Date(); let date = new Date();
radio.station = station; radio.station = station;

View File

@ -8,6 +8,12 @@ export default {
category: 'info', category: 'info',
execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) { execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) {
let message: any = {}; let message: any = {};
if(!interaction.guild) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
let stations = client.stations; let stations = client.stations;
let currentGuild = client.datastore?.getEntry(interaction.guild.id); let currentGuild = client.datastore?.getEntry(interaction.guild.id);
let global = client.datastore?.getEntry("global"); let global = client.datastore?.getEntry("global");

View File

@ -8,20 +8,25 @@ export default {
async execute(interaction: any, client: RadioClient) { async execute(interaction: any, client: RadioClient) {
let message: any = {}; let message: any = {};
if(!client.user) return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
message.statusTitle = client.messages.statusTitle.replace("%client.user.username%", client.user.username); message.statusTitle = client.messages.statusTitle.replace("%client.user.username%", client.user.username);
let uptime = client.funcs.msToTime(client.uptime); let uptime = client.funcs.msToTime(client.uptime || 0);
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle(message.statusTitle) .setTitle(message.statusTitle)
.setThumbnail("https://cdn.discordapp.com/emojis/" + client.messageEmojis["logo"].replace(/[^0-9]+/g, '')) .setThumbnail("https://cdn.discordapp.com/emojis/" + client.messageEmojis["logo"].replace(/[^0-9]+/g, ''))
.setColor(client.config.embedColor as ColorResolvable) .setColor(client.config.embedColor as ColorResolvable)
.addFields( .addFields([
{ name: client.messages.statusField1, value: uptime }, { name: client.messages.statusField1, value: uptime },
{ name: client.messages.statusField2, value: client.config.version }, { name: client.messages.statusField2, value: client.config.version },
{ name: client.messages.statusField3, value: Date.now() - interaction.createdTimestamp + "ms" }, { name: client.messages.statusField3, value: Date.now() - interaction.createdTimestamp + "ms" },
{ name: client.messages.statusField4, value: client.ws.ping.toString() }, { name: client.messages.statusField4, value: client.ws.ping.toString() },
{ name: client.messages.statusField5, value: client.config.hostedBy } { name: client.messages.statusField5, value: client.config.hostedBy }
) ])
.setImage('https://waren.io/berriabot-temp-sa7a36a9xm6837br/images/empty-3.png') .setImage('https://waren.io/berriabot-temp-sa7a36a9xm6837br/images/empty-3.png')
.setFooter({ .setFooter({
text: client.messages.footerText, text: client.messages.footerText,

View File

@ -7,13 +7,13 @@ export default {
category: 'radio', category: 'radio',
async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: any) { async execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient, command: any) {
if (client.funcs.check(client, interaction, command)) { if (client.funcs.check(client, interaction, command)) {
const radio = client.radio?.get(interaction.guild.id); const radio = client.radio?.get(interaction.guild?.id);
client.statistics?.update(client, interaction.guild, radio); client.statistics?.update(client, interaction.guild, radio);
radio.connection?.destroy(); radio.connection?.destroy();
client.funcs.logger('Radio', interaction.guild.id + " / " + 'Stop'); client.funcs.logger('Radio', interaction.guild?.id + " / " + 'Stop');
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle(client.user.username) .setTitle(client.user?.username || "-")
.setThumbnail("https://cdn.discordapp.com/emojis/" + client.messageEmojis["stop"].replace(/[^0-9]+/g, '')) .setThumbnail("https://cdn.discordapp.com/emojis/" + client.messageEmojis["stop"].replace(/[^0-9]+/g, ''))
.setColor(client.config.embedColor as ColorResolvable) .setColor(client.config.embedColor as ColorResolvable)
.addFields({ .addFields({
@ -40,7 +40,7 @@ export default {
await radio.message?.delete(); await radio.message?.delete();
}, 5000); }, 5000);
client.radio?.delete(interaction.guild.id); client.radio?.delete(interaction.guild?.id);
interaction.reply({ interaction.reply({
content: client.messageEmojis["stop"] + client.messages.stop, content: client.messageEmojis["stop"] + client.messages.stop,

View File

@ -1,6 +1,6 @@
import RadioClient from "../Client"; import RadioClient from "../Client";
export default { export const emojis = {
name: 'emojis', name: 'emojis',
async execute(client: RadioClient): Promise<any> { async execute(client: RadioClient): Promise<any> {
let customEmojis: any = { let customEmojis: any = {

View File

@ -7,6 +7,6 @@ import uncaughtException from "./events/uncaughtException"
import voiceStateUpdate from "./events/voiceStateUpdate" import voiceStateUpdate from "./events/voiceStateUpdate"
import warning from "./events/warning" import warning from "./events/warning"
export default { export const events = {
interactionCreate, messageDelete, ready, SIGINT, SIGTERM, uncaughtException, voiceStateUpdate, warning interactionCreate, messageDelete, ready, SIGINT, SIGTERM, uncaughtException, voiceStateUpdate, warning
} }

View File

@ -3,7 +3,7 @@ import RadioClient from "../../Client";
export default { export default {
name: 'SIGINT', name: 'SIGINT',
execute(client: RadioClient) { execute(client: RadioClient) {
client.user.setStatus('dnd'); client.user?.setStatus('dnd');
client.streamer?.leave(client); client.streamer?.leave(client);
client.radio?.save(client); client.radio?.save(client);

View File

@ -5,6 +5,13 @@ export default {
name: 'interactionCreate', name: 'interactionCreate',
async execute(client: RadioClient, interaction: any) { async execute(client: RadioClient, interaction: any) {
if(client.config.maintenanceMode){
return interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
}
const permissions = interaction.channel.permissionsFor(interaction.client.user); const permissions = interaction.channel.permissionsFor(interaction.client.user);
if (!permissions.has(PermissionFlagsBits.ViewChannel)) return; if (!permissions.has(PermissionFlagsBits.ViewChannel)) return;

View File

@ -1,10 +1,10 @@
import { Message } from "discord.js"; import { Message, PartialMessage } from "discord.js";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
export default { export default {
name: 'messageDelete', name: 'messageDelete',
async execute(client: RadioClient, msg: Message) { async execute(client: RadioClient, msg: Message | PartialMessage) {
if(!msg.author.bot || !msg.guild) return; if(!msg.author?.bot || !msg.guild) return;
const radio = client.radio?.get(msg.guild.id); const radio = client.radio?.get(msg.guild.id);
if(!radio) return; if(!radio) return;
if(!radio.message) return; if(!radio.message) return;

View File

@ -4,7 +4,7 @@ import Radio from "../classes/Radio";
import Stations from "../classes/Stations"; import Stations from "../classes/Stations";
import Streamer from "../classes/Streamer"; import Streamer from "../classes/Streamer";
import Statistics from "../classes/Statistics"; import Statistics from "../classes/Statistics";
import emojis from "../emojis" import { emojis } from "../emojis"
import commands from "../commands"; import commands from "../commands";
export default { export default {
@ -48,7 +48,7 @@ export default {
client.streamer.init(client); client.streamer.init(client);
if(!client.stations) { if(!client.stations) {
client.user.setStatus('dnd'); client.user?.setStatus('dnd');
} }
/*GUILDS*/ /*GUILDS*/
@ -76,7 +76,7 @@ export default {
setTimeout(function () { setTimeout(function () {
/*RESTORE RADIOS*/ /*RESTORE RADIOS*/
client.radio.restore(client, guilds); client.radio?.restore(client, guilds);
}, 5000); }, 5000);
setTimeout(function () { setTimeout(function () {

View File

@ -13,7 +13,7 @@ export default {
const radio = client.radio?.get(newState.guild.id); const radio = client.radio?.get(newState.guild.id);
if (!radio) return; if (!radio) return;
if (newState.member?.id === client.user.id && oldState.member?.id === client.user.id) { if (newState.member?.id === client.user?.id && oldState.member?.id === client.user?.id) {
if (newState.channel === null) { if (newState.channel === null) {
client.statistics?.update(client, newState.guild, radio); client.statistics?.update(client, newState.guild, radio);

View File

@ -7,6 +7,6 @@ import msToTime from "./funcs/msToTime";
import play from "./funcs/play"; import play from "./funcs/play";
import saveState from "./funcs/saveState"; import saveState from "./funcs/saveState";
export default { export const funcs = {
check, isDev, listStations, loadState, logger, msToTime, play, saveState check, isDev, listStations, loadState, logger, msToTime, play, saveState
} }

View File

@ -1,15 +1,9 @@
import RadioClient from "../../Client"; import RadioClient from "../../Client";
import { command } from "../commands";
export default function check(client: RadioClient, interaction: any, command: any) { export default function check(client: RadioClient, interaction: any, command: command) {
let message: any = {}; let message: any = {};
const radio = client.radio?.get(interaction.guild.id); const radio = client.radio?.get(interaction.guild.id);
if(client.config.maintenanceMode){
interaction.reply({
content: client.messageEmojis["error"] + client.messages.maintenance,
ephemeral: true
});
return false;
}
if(!client.stations) { if(!client.stations) {
message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild); message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild);
interaction.reply({ interaction.reply({

View File

@ -1,5 +1,5 @@
export default function logger(area : string, text: string){ export default function logger(area: string, text?: string){
let date = new Date(); let date = new Date();
console.log('[' + area + '] - ' + date.toISOString()); console.log('[' + area + '] - ' + date.toISOString());
if(text) console.log(text + '\n'); if(text) console.log(text + '\n');
} }

View File

@ -15,7 +15,7 @@ export default async function play(client: RadioClient, interaction: any, guild:
message.nowplayingDescription = message.nowplayingDescription.replace("**", ""); message.nowplayingDescription = message.nowplayingDescription.replace("**", "");
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle(client.user.username) .setTitle(client.user?.username || "-")
.setThumbnail((radio.station.logo || "https://cdn.discordapp.com/emojis/" + client.messageEmojis["play"].replace(/[^0-9]+/g, ''))) .setThumbnail((radio.station.logo || "https://cdn.discordapp.com/emojis/" + client.messageEmojis["play"].replace(/[^0-9]+/g, '')))
.setColor(client.config.embedColor as ColorResolvable) .setColor(client.config.embedColor as ColorResolvable)
.addFields({ .addFields({

View File

@ -1,4 +1,4 @@
export default { export const messages = {
wrongVoiceChannel: "You need to be in the same voice channel as RadioX to use this command!", wrongVoiceChannel: "You need to be in the same voice channel as RadioX to use this command!",
noPerms: "You need the %command.permission% permission to use this command!", noPerms: "You need the %command.permission% permission to use this command!",
notPlaying: "There is nothing playing!", notPlaying: "There is nothing playing!",

View File

@ -18,7 +18,7 @@ export default {
hostedBy: "[Warén Group](https://waren.io)", hostedBy: "[Warén Group](https://waren.io)",
//Settings //Settings
version: process.env.DEV_MODE ? process.env.npm_package_version + "-dev" : process.env.npm_package_version, version: process.env.DEV_MODE ? (process.env.npm_package_version ?? "0.0.0") + "-dev" : process.env.npm_package_version ?? "-",
debug: process.env.DEBUG_MODE || false, debug: process.env.DEBUG_MODE || false,
devMode: process.env.DEV_MODE || false, devMode: process.env.DEV_MODE || false,
maintenanceMode: false, maintenanceMode: false,