tictactoe
This commit is contained in:
parent
05d0972ec8
commit
b6b9eb66ab
|
@ -15,7 +15,7 @@ module.exports.meta = {
|
||||||
*/
|
*/
|
||||||
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
|
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
|
||||||
const channel = await client.channels.fetch(message.channel);
|
const channel = await client.channels.fetch(message.channel);
|
||||||
if (channel.channel_type != "Group") return client.channels.sendMessage(message.channel, `You can't earn XP in this channel.`);
|
if (channel.channel_type !== "Group") return client.channels.sendMessage(message.channel, `You can't earn XP in this channel.`);
|
||||||
let groupLevels = levels.get(message.channel);
|
let groupLevels = levels.get(message.channel);
|
||||||
const { xp, level, enabled } = (groupLevels?.[message.author] || {});
|
const { xp, level, enabled } = (groupLevels?.[message.author] || {});
|
||||||
|
|
||||||
|
|
174
commands/tictactoe.js
Normal file
174
commands/tictactoe.js
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
const Revolt = require('revolt.js');
|
||||||
|
const { client, logger, config } = require('..');
|
||||||
|
const { levels, levelups } = require('../util/levels');
|
||||||
|
const getUser = require('../util/get_user');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Map<String, { createdBy: String, opponent: String, messageID: String }>}
|
||||||
|
*/
|
||||||
|
let sessions = new Map();
|
||||||
|
|
||||||
|
module.exports.meta = {
|
||||||
|
name: 'tictactoe',
|
||||||
|
aliases: [],
|
||||||
|
description: 'Play tic tac toe.'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param { Revolt.Message } message
|
||||||
|
* @param { string[] } args
|
||||||
|
*/
|
||||||
|
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
|
||||||
|
if ((await client.channels.fetch(message.channel)).channel_type !== 'Group')
|
||||||
|
return client.channels.sendMessage(message.channel, ':x: You can\'t play here.');
|
||||||
|
|
||||||
|
if (args[0]?.toLowerCase() === 'stop') {
|
||||||
|
if (!sessions.get(message.channel)?.messageID)
|
||||||
|
return client.channels.sendMessage(message.channel, `:x: No ongoing match found.`);
|
||||||
|
|
||||||
|
sessions.delete(message.channel);
|
||||||
|
await client.channels.sendMessage(message.channel, `:white_check_mark: Game stopped`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessions.get(message.channel))
|
||||||
|
return client.channels.sendMessage(message.channel, `:x: There's an ongoing match ` +
|
||||||
|
`[here](https://app.revolt.chat/channel/${message.channel}/${sessions.get(message.channel).messageID}), ` +
|
||||||
|
`please wait for it to finish or use \`${config.prefix}tictactoe stop\`.`);
|
||||||
|
|
||||||
|
if (!args[0])
|
||||||
|
return client.channels.sendMessage(message.channel, ':x: Please specify the ID or username of your opponent.');
|
||||||
|
|
||||||
|
let opponent = await getUser(args.join(' '));
|
||||||
|
if (!opponent)
|
||||||
|
return client.channels.sendMessage(message.channel, 'I can\'t find that user.');
|
||||||
|
if (opponent._id === client.user._id)
|
||||||
|
return client.channels.sendMessage(message.channel, ':x: You can\'t play against me. (yet)');
|
||||||
|
if (opponent._id === message.author)
|
||||||
|
return client.channels.sendMessage(message.channel, ':x: You can\'t play against yourself, dumbus');
|
||||||
|
if (client.channels.get(message.channel).recipients?.indexOf(opponent._id) === -1)
|
||||||
|
return client.channels.sendMessage(message.channel, ':x: That user is not in this group.');
|
||||||
|
|
||||||
|
let field = [
|
||||||
|
[' ',' ',' '],
|
||||||
|
[' ',' ',' '],
|
||||||
|
[' ',' ',' '],
|
||||||
|
];
|
||||||
|
let x = message.author;
|
||||||
|
let o = opponent._id;
|
||||||
|
if (Math.random() > 0.5) [x, o] = [o, x];
|
||||||
|
let turn = Math.random() > 0.5 ? 'X' : 'O';
|
||||||
|
let winner = null;
|
||||||
|
|
||||||
|
let text;
|
||||||
|
let msg;
|
||||||
|
const updateMsg = async () => {
|
||||||
|
text =
|
||||||
|
`**X**: <@${x}> \u200b **O**: <@${o}>\n\u200b\n` +
|
||||||
|
`|${turn}| \u200b \u200b **1** \u200b \u200b | \u200b \u200b **2** \u200b \u200b | \u200b \u200b **3** \u200b \u200b |\n` +
|
||||||
|
`|-|:-:|:-:|:-:|\n` +
|
||||||
|
`|**A**|${field[0][0]}|${field[0][1]}|${field[0][2]}|\n` +
|
||||||
|
`|**B**|${field[1][0]}|${field[1][1]}|${field[1][2]}|\n` +
|
||||||
|
`|**C**|${field[2][0]}|${field[2][1]}|${field[2][2]}|\n` +
|
||||||
|
(winner ? `\n\u200b\n# Winner: <@${winner === 'X' ? x : o}>\n\u200b` : '');
|
||||||
|
|
||||||
|
if (!msg) {
|
||||||
|
msg = await client.channels.sendMessage(message.channel, text);
|
||||||
|
sessions.set(message.channel, { messageID: msg._id, createdBy: message.author, opponent: opponent._id });
|
||||||
|
} else
|
||||||
|
await client.channels.editMessage(message.channel, msg._id, { content: text });
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateMsg();
|
||||||
|
|
||||||
|
const end = awaitMessages(message.channel, msg => {
|
||||||
|
let [ column, row, bruh ] = msg.content?.toLowerCase().split('');
|
||||||
|
if (column === 'a') column = 0;
|
||||||
|
if (column === 'b') column = 1;
|
||||||
|
if (column === 'c') column = 2;
|
||||||
|
row = Number(row); row--;
|
||||||
|
column = Number(column); // Prevent borking
|
||||||
|
|
||||||
|
if ((isNaN(row) || isNaN(column)) || bruh) return;
|
||||||
|
|
||||||
|
if (field[column]?.[row] !== ' ')
|
||||||
|
return client.channels.sendMessage(msg.channel, 'That field is not available.');
|
||||||
|
|
||||||
|
let curPlayer = turn === 'X' ? x : o;
|
||||||
|
|
||||||
|
if (msg.author !== x && msg.author !== o)
|
||||||
|
return client.channels.sendMessage(message.channel, `<@${msg.author}>, you are not part of this game.`);
|
||||||
|
|
||||||
|
if (msg.author !== curPlayer)
|
||||||
|
return client.channels.sendMessage(message.channel, `<@${msg.author}>, it's <@${curPlayer}>'s turn.`);
|
||||||
|
|
||||||
|
field[column][row] = turn;
|
||||||
|
turn = turn === 'X' ? 'O' : 'X';
|
||||||
|
|
||||||
|
let w = getWinner(field);
|
||||||
|
console.log(w);
|
||||||
|
if (w) {
|
||||||
|
end();
|
||||||
|
winner = w;
|
||||||
|
updateMsg();
|
||||||
|
sessions.delete(message.channel);
|
||||||
|
client.channels.sendMessage(message.channel, `<@${w === 'X' ? x : o}> wins!`);
|
||||||
|
} else {
|
||||||
|
updateMsg();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} channel
|
||||||
|
* @param {function} callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
const emitter = new (require('events'));
|
||||||
|
client.on('message', message => {
|
||||||
|
emitter.emit('message', message);
|
||||||
|
});
|
||||||
|
|
||||||
|
function awaitMessages(channel, callback) {
|
||||||
|
let ended = false;
|
||||||
|
const listener = emitter.on('message', message => {
|
||||||
|
if (message.channel === channel && !ended) {
|
||||||
|
callback(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
// somehow remove the listener idk how
|
||||||
|
ended = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {('X'|'O'|' ')[][]} field
|
||||||
|
*/
|
||||||
|
const getWinner = field => {
|
||||||
|
let winner = null;
|
||||||
|
['X', 'O'].forEach(player => {
|
||||||
|
// Horizontal lines
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (field[i][0] === player &&
|
||||||
|
field[i][1] === player &&
|
||||||
|
field[i][2] === player) if (!winner) winner = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertical lines
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (field[0][i] === player &&
|
||||||
|
field[1][i] === player &&
|
||||||
|
field[2][i] === player) if (!winner) winner = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Diagonal lines
|
||||||
|
if ((field[0][0] === player || field[0][2] === player) &&
|
||||||
|
(field[2][0] === player || field[2][2] === player) &&
|
||||||
|
(field[1][1] === player)) if (!winner) winner = player;
|
||||||
|
});
|
||||||
|
|
||||||
|
return winner;
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
const Revolt = require('revolt.js');
|
const Revolt = require('revolt.js');
|
||||||
const { client, logger, config } = require('..');
|
const { client, logger, config } = require('..');
|
||||||
|
const getUser = require('../util/get_user');
|
||||||
|
const { levels, levelups } = require('../util/levels');
|
||||||
|
|
||||||
module.exports.meta = {
|
module.exports.meta = {
|
||||||
name: 'whois',
|
name: 'whois',
|
||||||
|
@ -13,18 +15,22 @@ module.exports.meta = {
|
||||||
* @param { string[] } args
|
* @param { string[] } args
|
||||||
*/
|
*/
|
||||||
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
|
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
|
||||||
let uid = args[0];
|
if (!args[0])
|
||||||
if (!uid)
|
return client.channels.sendMessage(message.channel, ':x: Please specify the user\'s name or ID.');
|
||||||
return client.channels.sendMessage(message.channel, 'Please <@mention> the target user or type their ID.');
|
|
||||||
|
|
||||||
|
let target = await getUser(args.join(' '));
|
||||||
|
if (!target)
|
||||||
|
return client.channels.sendMessage(message.channel, ':x: I can\'t find that user. Type their name or ID.');
|
||||||
|
|
||||||
if (uid.startsWith('<@') && uid.endsWith('>')) uid = uid.substr(2, uid.length - 3);
|
const avatarURL = `https://api.revolt.chat/users/${target._id}/avatar`;
|
||||||
|
const { xp, level, enabled } = (levels.get(message.channel)?.[target._id] || {});
|
||||||
|
|
||||||
const target = await client.users.fetch(uid)
|
let msgContent = `> ## \u200b ${target.username}\n` +
|
||||||
.catch(e => { return reject(e) });
|
`> \u200b\n` +
|
||||||
|
`> **ID**: \`${target._id}\`\n` +
|
||||||
let msgContent =
|
`> **Online**: \`${target.online ?? 'Unknown'}\`\n` +
|
||||||
`${JSON.stringify(target)}`
|
`> **XP**: \`${xp ? `${xp} XP, Level ${level}. Level up in ${levelups.find(l => l > xp) - xp} XP` : 'None'}\`\n` +
|
||||||
|
`> [\\[Avatar\\]](${avatarURL})\n`
|
||||||
|
|
||||||
await client.channels.sendMessage(message.channel, msgContent);
|
await client.channels.sendMessage(message.channel, msgContent);
|
||||||
});
|
});
|
6
index.js
6
index.js
|
@ -22,8 +22,10 @@ const logger = new Logger(config.debug ? LogLevel.Debug : LogLevel.Standard);
|
||||||
const client = new Revolt.Client(config.revoltClient);
|
const client = new Revolt.Client(config.revoltClient);
|
||||||
|
|
||||||
client.on("message", async message => {
|
client.on("message", async message => {
|
||||||
const author = await client.users.fetch(message.author);
|
const author = await client.users.fetch(message.author).catch(()=>{});
|
||||||
const channel = await client.channels.fetch(message.channel);
|
const channel = await client.channels.fetch(message.channel).catch(()=>{});
|
||||||
|
|
||||||
|
if (!author || !channel) return logger.debug(`Received message with unknown author or channel`);
|
||||||
|
|
||||||
if (author._id === client.user._id)
|
if (author._id === client.user._id)
|
||||||
return logger.debug(`Sent message -> ${channel.name} => ${message.content}`);
|
return logger.debug(`Sent message -> ${channel.name} => ${message.content}`);
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
/**
|
/**if () {
|
||||||
|
|
||||||
|
} else
|
||||||
* Automatically accepts friend requests and
|
* Automatically accepts friend requests and
|
||||||
* sends requests to users messaging the bot.
|
* sends requests to users messaging the bot.
|
||||||
* Required for users to add it to groups.
|
* Required for users to add it to groups.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { client, logger, config } = require('..');
|
const { client, logger } = require('..');
|
||||||
|
|
||||||
client.on("packet", async packet => {
|
client.on("packet", async packet => {
|
||||||
try {
|
try {
|
||||||
|
|
21
util/get_user.js
Normal file
21
util/get_user.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
const { client, logger, config } = require('..');
|
||||||
|
|
||||||
|
module.exports = async (input) => {
|
||||||
|
try {
|
||||||
|
let output;
|
||||||
|
if (input.startsWith('<@') && input.endsWith('>'))
|
||||||
|
output = input.substr(2, input.length - 3);
|
||||||
|
else {
|
||||||
|
if (input.startsWith('@')) input = input.substr(1);
|
||||||
|
if (client.users.get(input))
|
||||||
|
output = input;
|
||||||
|
else
|
||||||
|
output = client.users.toArray().find(user => user.username?.toLowerCase() === input?.toLowerCase())?._id;
|
||||||
|
}
|
||||||
|
if (!output) output = input;
|
||||||
|
return await client.users.fetch(output)
|
||||||
|
.catch(()=>{});
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue