Merge branch 'master' into fix-33

This commit is contained in:
Christer Warén 2021-09-06 05:46:49 +03:00
commit c5d04aed3c
12 changed files with 252 additions and 187 deletions

View File

@ -42,6 +42,8 @@ class RadioClient extends Client {
this.funcs.searchStation = require("./client/funcs/searchStation.js"); this.funcs.searchStation = require("./client/funcs/searchStation.js");
this.funcs.play = require("./client/funcs/play.js"); this.funcs.play = require("./client/funcs/play.js");
this.funcs.listStations = require("./client/funcs/listStations.js"); this.funcs.listStations = require("./client/funcs/listStations.js");
this.funcs.restoreRadios = require("./client/funcs/restoreRadios.js");
this.funcs.saveRadios = require("./client/funcs/saveRadios.js");
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');

View File

@ -20,6 +20,7 @@ module.exports = {
if(command.options) { if(command.options) {
command.options.forEach(function(option) { command.options.forEach(function(option) {
if(option.type == "STRING") option.type = 3; if(option.type == "STRING") option.type = 3;
if(option.type == "NUMBER") option.type = 10;
command.data.options.push(option); command.data.options.push(option);
}); });
} }
@ -49,6 +50,7 @@ module.exports = {
client.funcs.logger('Slash Commands', 'Guild Applications Successful' + "\n" + guild.id + " / " + guild.name); client.funcs.logger('Slash Commands', 'Guild Applications Successful' + "\n" + guild.id + " / " + guild.name);
} catch (DiscordAPIError) { } catch (DiscordAPIError) {
client.funcs.logger('Slash Commands', 'Guild Applications Failed' + "\n" + guild.id + " / " + guild.name); client.funcs.logger('Slash Commands', 'Guild Applications Failed' + "\n" + guild.id + " / " + guild.name);
if(DiscordAPIError.name != "DiscordAPIError[50001]") console.error(DiscordAPIError.message + "\n\n");
} }
}); });
} else { } else {

View File

@ -5,58 +5,156 @@ module.exports = {
description: 'Bot Maintenance', description: 'Bot Maintenance',
permission: 'none', permission: 'none',
category: 'info', category: 'info',
execute(interaction, client) { options: [
{ type: "NUMBER", name: "action", description: "Select action", required: false}
],
async execute(interaction, client) {
let message = {}; let message = {};
if(!client.funcs.isDev(client.config.devId, interaction.user.id)) return interaction.reply(client.messageEmojis["error"] + client.messages.notAllowed); if(!client.funcs.isDev(client.config.devId, interaction.user.id)) return interaction.reply(client.messageEmojis["error"] + client.messages.notAllowed);
let action = interaction.options?.getNumber("action") ?? interaction.values?.[0];
if(client.config.version.includes("-dev")){ const options = new Array(
interaction.reply({ {
content: "Maintenance Initiated", emoji: "🌀",
ephemeral: true label: "Restart Bot",
}); description: "",
value: "0"
process.emit('SIGINT'); },
} else { {
if(!client.stations) { emoji: "<:RadioXStop:688541155377414168>",
message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild); label: "Save Radios",
return interaction.reply(client.messageEmojis["error"] + message.errorToGetPlaylist); description: "",
value: "4"
},
{
emoji: "<:RadioXPlay:688541155712827458>",
label: "Restore Radios",
description: "",
value: "5"
},
{
emoji: "#️⃣",
label: "Reload Commands",
description: "",
value: "6"
},
{
emoji: "<:dnd:746069698139127831>",
label: "Enable Maintenance Mode",
description: "",
value: "8"
},
{
emoji: "<:online:746069731836035098>",
label: "Disable Maintenance Mode",
description: "",
value: "9"
} }
);
let currentRadios = client.radio.keys(); const menu = new Discord.MessageActionRow()
let radio = currentRadios.next(); .addComponents(
let stoppedRadios = ""; new Discord.MessageSelectMenu()
.setCustomId('maintenance')
.setPlaceholder('Select action')
.addOptions(options)
);
client.user.setStatus('dnd'); if(!action){
return interaction.reply({
while (!radio.done) { content: "**" + client.messages.maintenanceTitle + "**",
let currentRadio = client.radio.get(radio.value); components: [menu],
currentRadio.guild = client.datastore.getEntry(radio.value).guild;
if(currentRadio){
client.funcs.statisticsUpdate(client, currentRadio.guild, currentRadio);
currentRadio.connection?.destroy();
currentRadio.audioPlayer?.stop();
currentRadio.message?.delete();
client.radio.delete(radio.value);
stoppedRadios += "-" + radio.value + ": " + currentRadio.guild.name + "\n";
}
radio = currentRadios.next();
}
const embed = new Discord.MessageEmbed()
.setTitle(client.messages.maintenanceTitle)
.setThumbnail("https://cdn.discordapp.com/emojis/" + client.messageEmojis["maintenance"].replace(/[^0-9]+/g, ''))
.setColor(client.config.embedColor)
.setDescription("Stopped all radios" + "\n" + stoppedRadios)
.setImage('https://waren.io/berriabot-temp-sa7a36a9xm6837br/images/empty-3.png')
.setFooter(client.messages.footerText, "https://cdn.discordapp.com/emojis/" + client.messageEmojis["eximiabots"].replace(/[^0-9]+/g, ''));
interaction.reply({
embeds: [embed],
ephemeral: true ephemeral: true
}); });
} }
client.funcs.logger('Maintenance', options.find(option => option.value == action).label);
const embed = new Discord.MessageEmbed()
.setTitle(client.messages.maintenanceTitle)
.setColor(client.config.embedColor)
.setDescription(options.find(option => option.value == action).label)
.setFooter(client.messages.footerText, "https://cdn.discordapp.com/emojis/" + client.messageEmojis["eximiabots"].replace(/[^0-9]+/g, ''));
interaction.reply({
embeds: [embed],
ephemeral: true
});
switch(action){
case "0":
process.emit('SIGINT');
break;
case "4":
client.user.setStatus('idle');
setTimeout(function () {
client.funcs.saveRadios(client);
}, 5000);
client.user.setStatus('online');
break;
case "5":
client.user.setStatus('idle');
let guilds = await client.guilds.fetch();
setTimeout(function () {
client.funcs.restoreRadios(client, guilds);
}, 5000);
client.user.setStatus('online');
break;
case "6":
client.user.setStatus('idle');
require(`../commands.js`).execute(client);
client.user.setStatus('online');
break;
case "8":
client.user.setStatus('dnd');
break;
case "9":
client.user.setStatus('online');
break;
default:
}
/*
if(!client.stations) {
message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild);
return interaction.reply(client.messageEmojis["error"] + message.errorToGetPlaylist);
}
let currentRadios = client.radio.keys();
let radio = currentRadios.next();
let stoppedRadios = "";
client.user.setStatus('dnd');
while (!radio.done) {
let currentRadio = client.radio.get(radio.value);
currentRadio.guild = client.datastore.getEntry(radio.value).guild;
if(currentRadio){
client.funcs.statisticsUpdate(client, currentRadio.guild, currentRadio);
currentRadio.connection?.destroy();
currentRadio.audioPlayer?.stop();
currentRadio.message?.delete();
client.radio.delete(radio.value);
stoppedRadios += "-" + radio.value + ": " + currentRadio.guild.name + "\n";
}
radio = currentRadios.next();
}
const embed = new Discord.MessageEmbed()
.setTitle(client.messages.maintenanceTitle)
.setThumbnail("https://cdn.discordapp.com/emojis/" + client.messageEmojis["maintenance"].replace(/[^0-9]+/g, ''))
.setColor(client.config.embedColor)
.setDescription("Stopped all radios" + "\n" + stoppedRadios)
.setImage('https://waren.io/berriabot-temp-sa7a36a9xm6837br/images/empty-3.png')
.setFooter(client.messages.footerText, "https://cdn.discordapp.com/emojis/" + client.messageEmojis["eximiabots"].replace(/[^0-9]+/g, ''));
interaction.reply({
embeds: [embed],
ephemeral: true
});*/
} }
}; };

View File

@ -15,14 +15,14 @@ module.exports = {
category: "radio", category: "radio",
async execute(interaction, client) { async execute(interaction, client) {
let message = {}; let message = {};
if(!client.stations) {
message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild);
return interaction.reply(client.messageEmojis["error"] + message.errorToGetPlaylist);
}
let query = interaction.options?.getString("query") ?? interaction.values?.[0]; let query = interaction.options?.getString("query") ?? interaction.values?.[0];
if(!query){ if(!query){
if(!client.stations) { return client.funcs.listStations(client, interaction);
message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace("%client.config.supportGuild%", client.config.supportGuild);
return interaction.reply(client.messageEmojis["error"] + message.errorToGetPlaylist);
}
client.funcs.listStations(client, interaction);
} }
let url = query ? query.replace(/<(.+)>/g, "$1") : ""; let url = query ? query.replace(/<(.+)>/g, "$1") : "";
const radio = client.radio.get(interaction.guild.id); const radio = client.radio.get(interaction.guild.id);
@ -40,16 +40,6 @@ module.exports = {
ephemeral: true ephemeral: true
}); });
} }
if (!client.stations) {
message.errorToGetPlaylist = client.messages.errorToGetPlaylist.replace(
"%client.config.supportGuild%",
client.config.supportGuild
);
return interaction.reply({
content: client.messageEmojis["error"] + message.errorToGetPlaylist,
ephemeral: true
});
}
if (!query) return interaction.reply(client.messages.noQuery); if (!query) return interaction.reply(client.messages.noQuery);
const permissions = voiceChannel.permissionsFor(interaction.client.user); const permissions = voiceChannel.permissionsFor(interaction.client.user);
if (!permissions.has("CONNECT")) { if (!permissions.has("CONNECT")) {

View File

@ -1,5 +1,6 @@
import Discord from "discord.js"; import Discord from "discord.js";
module.exports = { module.exports = {
name: 'statistics', name: 'statistics',
description: 'Show statistics', description: 'Show statistics',
@ -18,13 +19,13 @@ module.exports = {
} }
if(!currentGuild || currentGuild && !currentGuild.statistics){ if(!currentGuild || currentGuild && !currentGuild.statistics){
statistics = "You have not listened any radio station"; statistics = "You have not listened any radio stations";
} else { } else {
Object.keys(stations).forEach(function(station) { Object.keys(stations).forEach(function(station) {
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[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){
statistics += `**${parseInt(station) + 1}. ` + stations[station].name + "** \n"; statistics += `**${parseInt(station) + 1}. ` + stations[station].name + "** \n";
if(global && global.statistics[stations[station].name] && global.statistics[stations[station].name].time && parseInt(global.statistics[stations[station].name].time) > 0 && global.statistics[stations[station].name].used && parseInt(global.statistics[stations[station].name].used) > 0){ if(global && global.statistics[stations[station].name] && global.statistics[stations[station].name].time && parseInt(global.statistics[stations[station].name].time) > 0 && global.statistics[stations[station].name].used && parseInt(global.statistics[stations[station].name].used) > 0){
statistics += "Guild Time: " + client.funcs.msToTime(currentGuild.statistics[stations[station].name].time) + " (" + ((currentGuild.statistics[stations[station].name].time / global.statistics[stations[station].name].time) * 100) + "%" + ")" + " / " + "Used: " + currentGuild.statistics[stations[station].name].used + " (" + ((currentGuild.statistics[stations[station].name].used / global.statistics[stations[station].name].used) * 100) + "%" + ")" + "\n"; statistics += "Guild Time: " + client.funcs.msToTime(currentGuild.statistics[stations[station].name].time) + " (" + ((currentGuild.statistics[stations[station].name].time / global.statistics[stations[station].name].time) * 100).toFixed(0) + "%" + ")" + " / " + "Used: " + currentGuild.statistics[stations[station].name].used + " (" + ((currentGuild.statistics[stations[station].name].used / global.statistics[stations[station].name].used) * 100).toFixed(0) + "%" + ")" + "\n";
statistics += "Global Time: " + client.funcs.msToTime(global.statistics[stations[station].name].time) + " / " + "Used: " + global.statistics[stations[station].name].used + "\n\n"; statistics += "Global Time: " + client.funcs.msToTime(global.statistics[stations[station].name].time) + " / " + "Used: " + global.statistics[stations[station].name].used + "\n\n";
} else { } else {
statistics += "Time: " + client.funcs.msToTime(currentGuild.statistics[stations[station].name].time) + " / " + "Used: " + currentGuild.statistics[stations[station].name].used + "\n\n"; statistics += "Time: " + client.funcs.msToTime(currentGuild.statistics[stations[station].name].time) + " / " + "Used: " + currentGuild.statistics[stations[station].name].used + "\n\n";

View File

@ -16,50 +16,8 @@ module.exports = {
if (!client.stations) return process.exit(); if (!client.stations) return process.exit();
let currentRadios = client.radio.keys(); await client.funcs.saveRadios(client);
let radio = currentRadios.next(); await process.exit();
while (!radio.done) {
let currentRadio = client.radio.get(radio.value);
currentRadio.guild = client.datastore.getEntry(radio.value).guild;
if (currentRadio) {
await client.funcs.statisticsUpdate(client, currentRadio.guild, currentRadio);
await client.funcs.saveState(client, currentRadio.guild, currentRadio);
currentRadio.connection?.destroy();
currentRadio.audioPlayer?.stop();
currentRadio.message?.delete();
client.radio.delete(radio.value);
}
radio = currentRadios.next();
}
/*const rest = new REST({ version: '9' }).setToken(token);
if(version.includes("-dev")){
await rest.put(
Routes.applicationCommands(client.user.id),
{ body: [] },
);
let guilds = await client.guilds.fetch();
guilds.forEach(async guild => {
try {
await rest.put(
Routes.applicationGuildCommands(client.user.id, guild.id),
{ body: [] }
);
} catch (DiscordAPIError) {
}
});
}*/
setInterval(() => {
if(radio.done){
process.exit();
}
}, 1000);
}, 5000); }, 5000);
} }
} }

View File

@ -3,7 +3,12 @@ module.exports = {
async execute(client, interaction) { async execute(client, interaction) {
const permissions = interaction.channel.permissionsFor(interaction.client.user); const permissions = interaction.channel.permissionsFor(interaction.client.user);
if (!permissions.has('EMBED_LINKS')) return interaction.reply(client.messages.noPermsEmbed); if (!permissions.has('VIEW_CHANNEL')) return;
if (!permissions.has('EMBED_LINKS')) return interaction.reply({
content: client.messages.noPermsEmbed,
ephemeral: true
});
if(interaction.isCommand()){ if(interaction.isCommand()){
const commandName = interaction.commandName; const commandName = interaction.commandName;

View File

@ -94,8 +94,8 @@ module.exports = {
require(`../commands.js`).execute(client); require(`../commands.js`).execute(client);
setTimeout(function () { setTimeout(function () {
/*RESTORE RADIO*/ /*RESTORE RADIOS*/
require(`../restoreradio.js`).execute(client, guilds); client.funcs.restoreRadios(client, guilds);
}, 5000); }, 5000);
} }

View File

@ -2,27 +2,16 @@ import Discord from "discord.js";
module.exports = function (client, interaction){ module.exports = function (client, interaction){
let stations = new Array(); let stations = new Array();
let options = new Array(); let options = new Array();
options[1] = new Array();
options[2] = new Array();
stations[1] = client.stations.slice(0,24).forEach(station => { stations = client.stations.forEach(station => {
if(station.name == "GrooveFM") return;
station = { station = {
label: station.name, label: station.name,
description: station.owner, description: station.owner,
value: station.name value: station.name
}; };
options[1].push(station); options.push(station);
});
stations[2] = client.stations.slice(25).forEach(station => {
station = {
label: station.name,
description: station.owner,
value: station.name
};
options[2].push(station);
}); });
const menu = new Discord.MessageActionRow() const menu = new Discord.MessageActionRow()
@ -30,8 +19,7 @@ module.exports = function (client, interaction){
new Discord.MessageSelectMenu() new Discord.MessageSelectMenu()
.setCustomId('play') .setCustomId('play')
.setPlaceholder('Nothing selected') .setPlaceholder('Nothing selected')
.addOptions(options[1]) .addOptions(options)
.addOptions(options[2])
); );
stations = null; stations = null;

View File

@ -0,0 +1,62 @@
import Discord from "discord.js";
const {
createAudioPlayer,
getVoiceConnection,
joinVoiceChannel
} = require("@discordjs/voice");
module.exports = async function restoreRadios(client, guilds) {
if(!client.stations) return;
guilds.forEach(async guild => {
let state = client.funcs.loadState(client, guild);
if(!state) return;
if(!state.station || !state.channels.voice || !state.channels.text) return;
let voiceChannel = client.channels.cache.get(state.channels.voice);
if(!voiceChannel) return;
if(voiceChannel.members.size === 0) return;
const sstation = await client.funcs.searchStation(state.station.name, client);
let url = sstation.stream[sstation.stream.default];
let station = sstation;
const construct = {
textChannel: client.channels.cache.get(state.channels.text),
voiceChannel: client.channels.cache.get(state.channels.voice),
connection: null,
message: null,
audioPlayer: createAudioPlayer(),
station: station
};
client.radio.set(guild.id, construct);
try {
const connection =
getVoiceConnection(guild.id) ??
joinVoiceChannel({
channelId: voiceChannel.id,
guildId: voiceChannel.guild.id,
adapterCreator: voiceChannel.guild.voiceAdapterCreator
});
construct.connection = connection;
let date = new Date();
construct.startTime = date.getTime();
client.funcs.play(null, guild, client, url, Discord);
client.datastore.checkEntry(guild.id);
construct.datastore = client.datastore.getEntry(guild.id);
if (!construct.datastore.statistics[construct.station.name]) {
construct.datastore.statistics[construct.station.name] = {};
construct.datastore.statistics[construct.station.name].time = 0;
construct.datastore.statistics[construct.station.name].used = 0;
client.datastore.updateEntry(guild, construct.datastore);
}
} catch (error) {
console.log(error);
}
});
}

View File

@ -0,0 +1,20 @@
module.exports = async function saveRadios(client) {
let currentRadios = client.radio.keys();
let radio = currentRadios.next();
while (!radio.done) {
let currentRadio = client.radio.get(radio.value);
currentRadio.guild = client.datastore.getEntry(radio.value).guild;
if (currentRadio) {
await client.funcs.statisticsUpdate(client, currentRadio.guild, currentRadio);
await client.funcs.saveState(client, currentRadio.guild, currentRadio);
currentRadio.connection?.destroy();
currentRadio.audioPlayer?.stop();
currentRadio.message?.delete();
client.radio.delete(radio.value);
}
radio = currentRadios.next();
}
}

View File

@ -1,61 +0,0 @@
import Discord from "discord.js";
const {
createAudioPlayer,
getVoiceConnection,
joinVoiceChannel
} = require("@discordjs/voice");
module.exports = {
async execute(client, guilds) {
if(!client.stations) return;
guilds.forEach(async guild => {
let state = client.funcs.loadState(client, guild);
if(!state) return;
if(!state.station || !state.channels.voice || !state.channels.text) return;
const sstation = await client.funcs.searchStation(state.station.name, client);
let url = sstation.stream[sstation.stream.default];
let station = sstation;
const construct = {
textChannel: client.channels.cache.get(state.channels.text),
voiceChannel: client.channels.cache.get(state.channels.voice),
connection: null,
message: null,
audioPlayer: createAudioPlayer(),
station: station
};
client.radio.set(guild.id, construct);
try {
let voiceChannel = client.channels.cache.get(state.channels.voice);
const connection =
getVoiceConnection(guild.id) ??
joinVoiceChannel({
channelId: voiceChannel.id,
guildId: voiceChannel.guild.id,
adapterCreator: voiceChannel.guild.voiceAdapterCreator
});
construct.connection = connection;
let date = new Date();
construct.startTime = date.getTime();
client.funcs.play(null, guild, client, url, Discord);
client.datastore.checkEntry(guild.id);
construct.datastore = client.datastore.getEntry(guild.id);
if (!construct.datastore.statistics[construct.station.name]) {
construct.datastore.statistics[construct.station.name] = {};
construct.datastore.statistics[construct.station.name].time = 0;
construct.datastore.statistics[construct.station.name].used = 0;
client.datastore.updateEntry(guild, construct.datastore);
}
} catch (error) {
console.log(error);
}
});
}
}