diff --git a/README.md b/README.md index 1551c3dc..731882c1 100644 --- a/README.md +++ b/README.md @@ -579,11 +579,15 @@ Total: 417 * **join:** Joins your voice channel. * **leave:** Leaves the current voice channel. +### Phone: + +* **admin-phone:** Starts an admin phone call with a server. (Owner-Only) +* **phone-book:** Looks up phone-enabled servers. +* **phone:** Starts a phone call with a random server. + ### Other: * **cleverbot:** Talk to Cleverbot. (Owner-Only) -* **phone-book:** Looks up phone-enabled servers. -* **phone:** Starts a phone call with a random server. * **portal-send:** Send a message to a portal channel. * **prune:** Deletes up to 99 messages from the current channel. * **rename-all:** Renames every member of the server. (Owner-Only) diff --git a/Xiao.js b/Xiao.js index 39d4761f..4301d123 100644 --- a/Xiao.js +++ b/Xiao.js @@ -34,6 +34,7 @@ client.registry ['edit-text', 'Text Manipulation'], ['edit-number', 'Number Manipulation'], ['voice', 'Voice-Based'], + ['phone', 'Phone'], ['other', 'Other'], ['roleplay', 'Roleplay'], ['readme', 'README Generators'] @@ -83,6 +84,7 @@ client.on('message', async msg => { if (!origin && !recipient) return; const call = origin || recipient; if (!call.active) return; + if (call.ownerOrigin && msg.guild.id === origin.guild.id && !client.isOwner(msg.author)) return; try { await call.send(origin ? call.recipient : call.origin, msg, hasText, hasImage, hasEmbed); } catch { diff --git a/commands/phone/admin-phone.js b/commands/phone/admin-phone.js new file mode 100644 index 00000000..745f8548 --- /dev/null +++ b/commands/phone/admin-phone.js @@ -0,0 +1,41 @@ +const Command = require('../../structures/Command'); +const PhoneCall = require('../../structures/phone/PhoneCall'); + +module.exports = class AdminPhoneCommand extends Command { + constructor(client) { + super(client, { + name: 'admin-phone', + aliases: ['admin-phone-call', 'admin-call', 'a-phone', 'a-phone-call', 'a-call'], + group: 'phone', + memberName: 'admin-phone', + description: 'Starts an admin phone call with a server.', + guildOnly: true, + ownerOnly: true, + args: [ + { + key: 'channelID', + prompt: 'What channel would you like to start a call with?', + type: 'string', + validate: channelID => /^[0-9]+$/.test(channelID), + parse: channelID => channelID.toLowerCase() + } + ] + }); + } + + async run(msg, { channelID }) { + const inCall = this.client.phone.some(call => [call.origin.id, call.recipient.id].includes(msg.channel.id)); + if (inCall) return msg.say('This channel is already in a phone call.'); + if (channelID === 'count') return msg.say(`☎️ **${channels.size}** currently open lines.`); + const channel = this.client.channels.cache.get(channelID); + if (!channel || !channel.guild) return msg.reply('This channel does not exist.'); + try { + const id = `${msg.channel.id}:${channel.id}`; + this.client.phone.set(id, new PhoneCall(this.client, msg.channel, channel, true)); + await this.client.phone.get(id).start(); + return null; + } catch { + return msg.reply('Failed to start the call. Try again later!'); + } + } +}; diff --git a/commands/other/phone-book.js b/commands/phone/phone-book.js similarity index 98% rename from commands/other/phone-book.js rename to commands/phone/phone-book.js index b9ee4502..6e49807f 100644 --- a/commands/other/phone-book.js +++ b/commands/phone/phone-book.js @@ -5,7 +5,7 @@ module.exports = class PhoneBookCommand extends Command { constructor(client) { super(client, { name: 'phone-book', - group: 'other', + group: 'phone', memberName: 'phone-book', description: 'Looks up phone-enabled servers.', guildOnly: true, diff --git a/commands/other/phone.js b/commands/phone/phone.js similarity index 99% rename from commands/other/phone.js rename to commands/phone/phone.js index 3e6320e7..f1044747 100644 --- a/commands/other/phone.js +++ b/commands/phone/phone.js @@ -6,7 +6,7 @@ module.exports = class PhoneCommand extends Command { super(client, { name: 'phone', aliases: ['phone-call', 'call'], - group: 'other', + group: 'phone', memberName: 'phone', description: 'Starts a phone call with a random server.', guildOnly: true, diff --git a/package.json b/package.json index 5d044213..9ccde149 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "114.9.2", + "version": "114.10.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": { diff --git a/structures/phone/PhoneCall.js b/structures/phone/PhoneCall.js index 9a25703a..d1594520 100644 --- a/structures/phone/PhoneCall.js +++ b/structures/phone/PhoneCall.js @@ -1,7 +1,7 @@ const { shorten, stripInvites, verify } = require('../../util/Util'); module.exports = class PhoneCall { - constructor(client, origin, recipient) { + constructor(client, origin, recipient, ownerOrigin) { Object.defineProperty(this, 'client', { value: client }); this.id = `${origin.id}:${recipient.id}`; @@ -9,15 +9,20 @@ module.exports = class PhoneCall { this.recipient = recipient; this.active = false; this.timeout = null; + this.ownerOrigin = ownerOrigin || false; } async start() { await this.origin.send(`☎️ Calling **${this.recipient.guild.name}**...`); - await this.recipient.send(`☎️ Incoming call from **${this.origin.guild.name}**. Pick up?`); - const validation = await verify(this.recipient, null); - if (!validation) { - await this.hangup('declined', validation); - return this; + if (this.ownerOrigin) { + await this.recipient.send(`☎️ Incoming **ADMIN** call from **${this.origin.guild.name}**...`); + } else { + await this.recipient.send(`☎️ Incoming call from **${this.origin.guild.name}**. Pick up?`); + const validation = await verify(this.recipient, null); + if (!validation) { + await this.hangup('declined', validation); + return this; + } } await this.accept(); return this; @@ -26,6 +31,7 @@ module.exports = class PhoneCall { async accept() { this.active = true; this.setTimeout(); + if (this.ownerOrigin) return this; await this.origin.send(`☎️ **${this.recipient.guild.name}** picked up! Type \`hang up\` to hang up.`); await this.recipient.send(`☎️ Accepted call from **${this.origin.guild.name}**. Type \`hang up\` to hang up.`); return this; @@ -52,7 +58,12 @@ module.exports = class PhoneCall { } send(channel, msg, hasText, hasImage, hasEmbed) { - if (msg.content && msg.content.toLowerCase() === 'hang up') return this.hangup(channel); + if (msg.content && msg.content.toLowerCase() === 'hang up') { + if (this.ownerOrigin && channel.id !== this.origin.id) { + return this.recipient.send('☎️ You cannot hang up in an admin call.'); + } + return this.hangup(channel); + } this.setTimeout(); const attachments = hasImage ? msg.attachments.map(a => a.url).join('\n') : null; if (!hasText && hasImage) return channel.send(`☎️ **${msg.author.tag}:**\n${attachments}`);