Created
January 12, 2023 17:40
-
-
Save Ale32bit/2c441d06a71f4fe90713794683c7d9bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| Respects Bot by AlexDevs | |
| The only good respects bot | |
| Copyright (c) 2023 AlexDevs | |
| Press F to pay respects | |
| */ | |
| const path = require("path"); | |
| const fs = require("fs"); | |
| const SwitchChat = require("switchchat"); | |
| const config = require("./config.json"); | |
| // Only validates is a message only contains f or F | |
| const payRegex = /^f$/i; | |
| let lastDeath = null; | |
| let players = {}; | |
| let discordLinks = {}; | |
| let respecters = []; | |
| let linkCodes = {}; | |
| const client = new SwitchChat.Client(config.license); | |
| client.defaultFormattingMode = "format"; | |
| function pad(n, width, z) { | |
| z = z || '0'; | |
| n = n + ''; | |
| return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; | |
| } | |
| function randomId() { | |
| return pad(Math.floor(Math.random() * 1000000), 6); | |
| } | |
| function save() { | |
| fs.writeFile(path.resolve(__dirname, "respects.json"), JSON.stringify(players, null, 4), err => { | |
| if (err) console.error(err) | |
| }); | |
| fs.writeFile(path.resolve(__dirname, "discordLinks.json"), JSON.stringify(discordLinks, null, 4), err => { | |
| if (err) console.error(err) | |
| }); | |
| } | |
| // Create a new player object if non-existent | |
| function newPlayer(user) { | |
| if (!players[user.uuid]) { | |
| players[user.uuid] = { | |
| name: user.name, // Username saved as cache | |
| respects: 0, | |
| deaths: 0, | |
| given: 0, | |
| custom: undefined, // Custom message to display in top 10 leaderboard | |
| quiet: true, | |
| discordId: null, | |
| } | |
| } | |
| save(); | |
| } | |
| // Search a player by name | |
| function getPlayer(name) { | |
| for (let uuid in players) { | |
| if (players[uuid].name === name) return players[uuid]; | |
| } | |
| } | |
| function tell(user, message) { | |
| return client.tell(user, message, "&6Respects", "format"); | |
| } | |
| // Chatbox sub commands | |
| const commands = { | |
| top(command) { // Display top 10 respected players | |
| let message = "&6--- &aTop 10 Leaderboard &6---"; | |
| let sortable = []; | |
| for (let k in players) { | |
| sortable.push([ | |
| k, | |
| players[k].respects, | |
| ]) | |
| } | |
| sortable.sort((a, b) => b[1] - a[1]); | |
| for (let i = 0; i < 10; i++) { | |
| if (sortable[i]) { | |
| let player = players[sortable[i][0]]; | |
| message += `\n&b${i + 1}. &6${player.name}&7: &a${player.custom ? player.custom.replace(/{}/g, player.respects) : player.respects}`; | |
| } | |
| } | |
| tell(command.user.name, message); | |
| }, | |
| deaths(command) { // Display top 10 players who died the most times | |
| let message = "&6--- &aTop 10 Deaths Leaderboard &6---"; | |
| let sortable = []; | |
| for (let k in players) { | |
| sortable.push([ | |
| k, | |
| players[k].deaths, | |
| ]) | |
| } | |
| sortable.sort((a, b) => b[1] - a[1]); | |
| for (let i = 0; i < 10; i++) { | |
| if (sortable[i]) { | |
| let player = players[sortable[i][0]]; | |
| message += `\n&b${i + 1}. &6${player.name}&7: &a${player.deaths}`; | |
| } | |
| } | |
| tell(command.user.name, message); | |
| }, | |
| view(command) { // View more information about a player | |
| // If an argument is passed, use it to look for a player. | |
| let player = command.args.shift(); | |
| if (player) { | |
| player = getPlayer(player); | |
| } else { // View yourself if no argument instead | |
| player = players[command.user.uuid]; | |
| } | |
| if (!player) { | |
| tell(command.user.name, "&cPlayer not found!"); | |
| return; | |
| } | |
| let message = | |
| `&6--- &a${player.name} &6---\n` + | |
| `&6Respects received&7: &a${player.respects}\n` + | |
| `&6Respects paid&7: &a${player.given}\n` + | |
| `&6Deaths&7: &a${player.deaths}\n` + | |
| //`&6Active Time&7: &a${activetime[player.name] ? activetime[player.name].formatted : "&cUnexpected error"}\n` + | |
| `&6Custom counter message&7: &a${player.custom ? player.custom : "*None*"}` + | |
| `${player.custom ? `\n&6Preview&7: &a${player.custom.replace(/{}/g, player.respects)}` : ""}` // Preview | |
| tell(command.user.name, message); | |
| }, | |
| set(command) { // Set custom counter message | |
| let custom = command.args.join(" "); | |
| if (custom.trim() === "") { // If no arguments passed, reset the custom message | |
| players[command.user.uuid].custom = undefined; | |
| save(); | |
| tell(command.user.name, `&6Custom counter message reset.`) | |
| } else { | |
| custom = custom.replace(/\n/gi, "").substr(0, 64); | |
| players[command.user.uuid].custom = custom; | |
| save(); | |
| tell(command.user.name, `&6Custom counter message set to &a${custom}\n&6Preview: &a${custom.replace(/{}/g, players[command.user.uuid].respects)}`) | |
| } | |
| }, | |
| quiet(command) { | |
| players[command.user.uuid].quiet = !players[command.user.uuid].quiet; | |
| save(); | |
| tell(command.user.name, `&6Quiet mode ${players[command.user.uuid].quiet ? "&aenabled" : "&cdisabled"}&6!`) | |
| }, | |
| link(command) { | |
| let id = randomId(); | |
| linkCodes[command.user.uuid] = id; | |
| tell(command.user.name, `&6Your link code is &7${id}&6!\nSay your link code in the Discord &9#server-chat&6 channel to link your account!`); | |
| }, | |
| help(command) { | |
| let message = | |
| "&6--- &aCommands list &6---\n" + | |
| "&6top&7: &aShow leaderboard of top 10 respected players\n" + | |
| "&6deaths&7: &aShow leaderboard of top 10 death counts\n" + | |
| "&6view&7 [name]: &aView information about a player\n" + | |
| "&6set&7 [custom counter message]: &aSet custom counter message (&7{}&a is counter placeholder)\n" + | |
| "&6quiet&7: &aToggle quiet mode\n" + | |
| "&6link&7: &aLink your Discord account\n" + | |
| "&6help&7: &aShow the commands list\n" + | |
| `\n&aLast death from &6${players[lastDeath] ? players[lastDeath].name : "&oNone"}`; | |
| tell(command.user.name, message, "&6Respects") | |
| }, | |
| update(command) { // OP command to overwrite data | |
| if (!command.ownerOnly) { | |
| tell(command.user.name, "&cRun this command as owner only") | |
| return; | |
| } | |
| let cmd = command.args.shift(); | |
| if (!cmd) { | |
| tell(command.user.name, "Usage: update <field> <name> <...>") | |
| return; | |
| } | |
| let user = getPlayer(command.args.shift()); | |
| if (!user) { | |
| tell(command.user.name, "User not found"); | |
| return; | |
| } | |
| switch (cmd) { | |
| case "deaths": | |
| let deaths = parseInt(command.args.shift()); | |
| user.deaths = deaths; | |
| save(); | |
| break; | |
| case "given": | |
| let given = parseInt(command.args.shift()); | |
| user.given = given; | |
| save(); | |
| break; | |
| case "respects": | |
| let respects = parseInt(command.args.shift()); | |
| user.respects = respects; | |
| save(); | |
| break; | |
| case "custom": | |
| let custom = command.args.join(" "); | |
| user.custom = custom.trim() === "" ? undefined : custom; | |
| save(); | |
| break; | |
| default: | |
| tell(command.user.name, "Options: deaths, given, respects, custom") | |
| return; | |
| } | |
| } | |
| }; | |
| function payRespect(message, isDiscord) { | |
| newPlayer(message.user); | |
| let payerId = message.user.uuid; | |
| if (isDiscord) { | |
| payerId = discordLinks[message.user.id]; | |
| } | |
| if (!lastDeath) { | |
| if (isDiscord) return; | |
| tell(message.user.name, "&7&oNo one died since my last restart.") | |
| return; | |
| } | |
| if (lastDeath === payerId) { // Avoid paying respects to yourself | |
| if (isDiscord) return; | |
| tell(message.user.name, "&cYou cannot respect yourself >:(") | |
| return; | |
| } | |
| if (respecters.includes(payerId)) { // Avoid paying respects again | |
| if (isDiscord) return; | |
| tell(message.user.name, `&cYou already paid respects to &6${players[lastDeath].name || "Steve"}`) | |
| return; | |
| } | |
| players[lastDeath].respects++; | |
| players[payerId].given++; | |
| respecters.push(payerId); | |
| save(); | |
| if (!players[lastDeath].quiet) { | |
| tell(players[lastDeath].name, `&6${message.user.name} &apaid you respects!`) | |
| .catch(() => { | |
| }); | |
| } | |
| if (!players[payerId].quiet && !isDiscord) { | |
| tell(message.user.name, `&aYou paid respects to &6${players[lastDeath].name}`); | |
| } | |
| } | |
| client.on("command", command => { // run sub command | |
| let prefix = command.command.toLowerCase(); | |
| if (prefix !== "respects" && prefix !== "f") return; | |
| newPlayer(command.user); | |
| let cmd = command.args.shift(); | |
| if (command.args.length === 0 && !commands[cmd]) { | |
| commands.help(command); | |
| return; | |
| } | |
| try { | |
| commands[cmd](command); | |
| } catch (e) { | |
| console.error(e); | |
| tell(command.user.name, "&cAn unexpected error occurred!"); | |
| } | |
| }) | |
| client.on("chat_ingame", message => { | |
| if (payRegex.test(message.text)) { // a player said "f" | |
| payRespect(message) | |
| } | |
| }) | |
| client.on("chat_discord", message => { | |
| if (message.text.length === 6) { | |
| for (let k in linkCodes) { | |
| let v = linkCodes[k]; | |
| if (v === message.text) { | |
| let uuid = message.discordUser.id; | |
| players[k].discordId = uuid; | |
| discordLinks[uuid] = k; | |
| save(); | |
| tell(players[k].name, `&6Account linked to &9${message.discordUser.name}&6!`) | |
| .catch(console.error); | |
| } | |
| } | |
| } else if (payRegex.test(message.text)) { // a player said "f" | |
| let uuid = discordLinks[message.discordUser.id]; | |
| if (uuid) { | |
| let player = players[uuid]; | |
| if (player.discordId === message.discordUser.id) { | |
| payRespect(message, true) | |
| } | |
| } | |
| } | |
| }) | |
| client.on("death", death => { // increase death counter | |
| newPlayer(death.user); // failsafe in case the bot wasn't running when a new player joined | |
| players[death.user.uuid].deaths++; | |
| save(); | |
| respecters = []; | |
| lastDeath = death.user.uuid; | |
| }) | |
| client.on("join", join => { // update cached name | |
| let user = join.user; | |
| newPlayer(user); | |
| if (players[user.uuid].name !== user.name) { | |
| players[user.uuid].name = user.name; | |
| save(); | |
| } | |
| }) | |
| client.on("ready", () => { | |
| console.log("Logged in as " + client.owner); | |
| }) | |
| if (!fs.existsSync(path.resolve(__dirname, "respects.json"))) { | |
| fs.writeFileSync(path.resolve(__dirname, "respects.json"), "{}"); | |
| } | |
| players = JSON.parse(fs.readFileSync(path.resolve(__dirname, "respects.json")).toString()); | |
| if (!fs.existsSync(path.resolve(__dirname, "discordLinks.json"))) { | |
| fs.writeFileSync(path.resolve(__dirname, "discordLinks.json"), "{}"); | |
| } | |
| discordLinks = JSON.parse(fs.readFileSync(path.resolve(__dirname, "discordLinks.json")).toString()); | |
| /*process.on("uncaughtException", e => { | |
| console.error("Error", e); | |
| })*/ | |
| client.connect(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment