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) => {
|
||||
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);
|
||||
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 { client, logger, config } = require('..');
|
||||
const getUser = require('../util/get_user');
|
||||
const { levels, levelups } = require('../util/levels');
|
||||
|
||||
module.exports.meta = {
|
||||
name: 'whois',
|
||||
|
@ -13,18 +15,22 @@ module.exports.meta = {
|
|||
* @param { string[] } args
|
||||
*/
|
||||
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
|
||||
let uid = args[0];
|
||||
if (!uid)
|
||||
return client.channels.sendMessage(message.channel, 'Please <@mention> the target user or type their ID.');
|
||||
if (!args[0])
|
||||
return client.channels.sendMessage(message.channel, ':x: Please specify the user\'s name or 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)
|
||||
.catch(e => { return reject(e) });
|
||||
|
||||
let msgContent =
|
||||
`${JSON.stringify(target)}`
|
||||
let msgContent = `> ## \u200b ${target.username}\n` +
|
||||
`> \u200b\n` +
|
||||
`> **ID**: \`${target._id}\`\n` +
|
||||
`> **Online**: \`${target.online ?? 'Unknown'}\`\n` +
|
||||
`> **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);
|
||||
});
|
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);
|
||||
|
||||
client.on("message", async message => {
|
||||
const author = await client.users.fetch(message.author);
|
||||
const channel = await client.channels.fetch(message.channel);
|
||||
const author = await client.users.fetch(message.author).catch(()=>{});
|
||||
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)
|
||||
return logger.debug(`Sent message -> ${channel.name} => ${message.content}`);
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
/**
|
||||
/**if () {
|
||||
|
||||
} else
|
||||
* Automatically accepts friend requests and
|
||||
* sends requests to users messaging the bot.
|
||||
* Required for users to add it to groups.
|
||||
*/
|
||||
|
||||
const { client, logger, config } = require('..');
|
||||
const { client, logger } = require('..');
|
||||
|
||||
client.on("packet", async packet => {
|
||||
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