335 lines
8.7 KiB
JavaScript
335 lines
8.7 KiB
JavaScript
const { SlashCommandBuilder, Discord, codeBlock, EmbedBuilder } = require('discord.js');
|
||
const fs = require('fs');
|
||
var path = require('node:path');
|
||
//const { writeFile } = require('../main.cjs');
|
||
|
||
module.exports = {
|
||
data: new SlashCommandBuilder()
|
||
.setName('drawdesign')
|
||
.setDescription('Draws a design in a codeblock')
|
||
.addStringOption(option =>
|
||
option.setName('design')
|
||
.setDescription("Pick a design. (number 1-5)")
|
||
.setRequired(true)
|
||
)
|
||
.addStringOption(option =>
|
||
option.setName('string')
|
||
.setDescription("String to feed into input")
|
||
.setRequired(true)
|
||
),
|
||
async execute(interaction, client) {
|
||
let inputString = interaction.options.getString('string');
|
||
let design = parseInt(interaction.options.getString('design'));
|
||
if (design < 1 || design > 5) {
|
||
await interaction.reply('Invalid design choice.');
|
||
return;
|
||
}
|
||
let output;
|
||
switch (design) {
|
||
case 1:
|
||
output = design1(inputString);
|
||
break;
|
||
case 2:
|
||
output = design2(inputString);
|
||
break;
|
||
case 3:
|
||
output = design3(inputString);
|
||
break;
|
||
case 4:
|
||
output = design4(inputString);
|
||
break;
|
||
case 5:
|
||
output = design5(inputString);
|
||
break;
|
||
}
|
||
//console.log(codeBlock("", output));
|
||
let testLength = "\n" + 'output length was ' + (output.length) + " characters.";
|
||
if (output.length + testLength.length > 2000) {
|
||
//await interaction.reply('Error: String is too big. Resultant output would be too big to send to Discord. (the output length was ' + (output.length + testLength.length) + " characters.)");
|
||
let replyString = "output length was " + (output.length) + " characters.";
|
||
let filePath = writeFile(output);
|
||
await interaction.reply({ content: replyString, files: [filePath] });
|
||
fs.unlinkSync(filePath); // Delete file once we're done with it
|
||
} else {
|
||
await interaction.reply(codeBlock("", output) + testLength);
|
||
}
|
||
console.log("User " + interaction.user.tag + " ran /drawtriangle");
|
||
},
|
||
};
|
||
|
||
function writeFile(content) {
|
||
//console.log(content);
|
||
console.log("Attempting to write string to file...");
|
||
let filename = Date.now() + '.txt';
|
||
console.log(filename);
|
||
var filePath = path.join(__dirname, '..', filename);
|
||
console.log(filePath);
|
||
fs.writeFile(filePath, content, err => {
|
||
if (err) {
|
||
console.error(err);
|
||
}
|
||
});
|
||
return filePath;
|
||
}
|
||
|
||
function design1(input) {
|
||
console.log("Running design1...");
|
||
let outputString;
|
||
let startEnd = "";
|
||
for (let i = 0; i < input.length + 2; i++) {
|
||
startEnd += "*";
|
||
}
|
||
outputString = startEnd + "\n";
|
||
outputString += "*" + "\n";
|
||
outputString += "* " + input + "\n";
|
||
outputString += "*" + "\n";
|
||
outputString += startEnd;
|
||
return outputString;
|
||
}
|
||
function design2(input) {
|
||
console.log("Running design2...");
|
||
let outputString;
|
||
let height = (input.length * 2) + 6;
|
||
let mid = Math.trunc(height / 2) + 1;
|
||
if (height % 2 == 0) {
|
||
height++;
|
||
}
|
||
outputString = "";
|
||
for (let i = 0; i < height; i++) {
|
||
if (mid == i) { //Determine if we're in the middle of the triangle
|
||
outputString += "**" + input + "**";
|
||
} else {
|
||
for (let j = 0; j < i; j++) {
|
||
outputString += "*";
|
||
}
|
||
}
|
||
outputString += "\n";
|
||
}
|
||
return outputString;
|
||
}
|
||
function design3(input) {
|
||
console.log("Running design3...");
|
||
let outputString;
|
||
let height = (input.length * 2) + 6;
|
||
let mid = Math.trunc(height / 2) + 1;
|
||
if (height % 2 == 0) {
|
||
height++;
|
||
}
|
||
outputString = "";
|
||
if (mid % 2 == 1) { // Skip a line if odd
|
||
var subOffset = 1;
|
||
var addOffset = 0;
|
||
} else {
|
||
var subOffset = 0;
|
||
var addOffset = 1;
|
||
}
|
||
for (let i = 0; i < mid - addOffset; i++) {
|
||
for (let j = 0; j < i; j++) {
|
||
if (i % 2 == 1) {
|
||
if (i != (mid - 1)) {
|
||
if (i == 0 || (j == 0 || j == (i - 1))) { // Check if we're at the beginning or end of the line
|
||
outputString += "*";
|
||
} else {
|
||
outputString += " ";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
outputString += "\n";
|
||
}
|
||
outputString += "* " + input + " *\n";
|
||
for (let i = mid - subOffset; i > 0; i--) {
|
||
for (let j = 0; j < i; j++) {
|
||
if (i % 2 == 1) {
|
||
if (j != (mid - 1) || (j != mid)) {
|
||
if ((i == 0 || (j == 0 || j == (i - 1)))) { // Check if we're at the beginning or end of the line
|
||
outputString += "*";
|
||
} else {
|
||
outputString += " ";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
outputString += "\n";
|
||
}
|
||
return outputString;
|
||
}
|
||
|
||
function design4(input) {
|
||
let outputString = "";
|
||
let outputLine = "";
|
||
let radius = (input.length + 1);
|
||
let mid = radius;
|
||
if (mid % 2 == 1) {
|
||
var spaceOffset = " ";
|
||
} else {
|
||
var spaceOffset = "";
|
||
}
|
||
console.log(radius, mid);
|
||
// dist represents distance to the center
|
||
let dist = parseFloat(0);
|
||
let space = ""
|
||
for (let i = 0; i < (input.length / 2); ++i) {
|
||
space += " ";
|
||
}
|
||
// for horizontal movement
|
||
var i;
|
||
var j;
|
||
let lineHasInput = false;
|
||
for (i = 0; i <= 2 * radius; i++) {
|
||
lineHasInput = false;
|
||
if (Math.trunc(i) != mid) {
|
||
// for vertical movement
|
||
for (j = 0; j <= 2 * radius; j++) {
|
||
dist = Math.sqrt(
|
||
((i - radius) * (i - radius) * 4) + // (* 4) accounts for the offset between lines
|
||
(j - radius) * (j - radius)
|
||
);
|
||
//console.log(i, j, radius, dist);
|
||
// dist should be in the range (radius - 0.5)
|
||
// and (radius + 0.5) to print stars(*)
|
||
|
||
|
||
if (dist > radius - 1 && dist < radius + 1) { //&& dist > radius - 1
|
||
lineHasInput = true;
|
||
outputLine += "·"; //zero-width space
|
||
} else {
|
||
outputLine += " ";
|
||
}
|
||
}
|
||
} else {
|
||
lineHasInput = true;
|
||
outputLine += "·" + space + input + space + spaceOffset + "·"; //zero-width space
|
||
}
|
||
|
||
//console.log(i, j, outputLine);
|
||
if (lineHasInput) {
|
||
outputString += outputLine + "\n";
|
||
}
|
||
outputLine = "";
|
||
}
|
||
return outputString;
|
||
}
|
||
const surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
||
var charIterateState;
|
||
function charIterate(input) {
|
||
let stringLength = (input.length - 1);
|
||
let temp = input.split('');
|
||
for (let i = 0; i < stringLength; ++i) {
|
||
let compareString = temp.join("");
|
||
let stringEval = undefined, stringEvalIndex = undefined;
|
||
while ((stringEval = surrogatePairs.exec(compareString)) !== null) {
|
||
stringEvalIndex = stringEval.index;
|
||
//console.log("emoji is at index", stringEvalIndex);
|
||
}
|
||
if (stringEvalIndex == i) {
|
||
stringLength--;
|
||
temp.splice(i, 1);
|
||
//console.log("Decreasing stringLength variable to", stringLength);
|
||
}
|
||
}
|
||
if (charIterateState == undefined) {
|
||
//console.log("undefined! setting to zero");
|
||
charIterateState = 0;
|
||
} else {
|
||
if (charIterateState < stringLength) {
|
||
charIterateState++;
|
||
} else {
|
||
charIterateState = 0;
|
||
}
|
||
}
|
||
//console.log(charIterateState, fixedCharAt(input, charIterateState));
|
||
return charIterateState;
|
||
}
|
||
|
||
function design5(input) {
|
||
charIterateState = undefined;
|
||
let outputString = "";
|
||
let outputLine = "";
|
||
let radius = (input.length);
|
||
let mid = radius;
|
||
if (mid % 2 == 1) {
|
||
var spaceOffset = " ";
|
||
} else {
|
||
var spaceOffset = "";
|
||
}
|
||
console.log(radius, mid);
|
||
// dist represents distance to the center
|
||
let dist = parseFloat(0);
|
||
let space = ""
|
||
for (let i = 0; i < (input.length / 2); ++i) {
|
||
space += " ";
|
||
}
|
||
// for horizontal movement
|
||
var i;
|
||
var j;
|
||
let lineHasInput = false;
|
||
for (i = 0; i <= 2 * radius; i++) {
|
||
lineHasInput = false;
|
||
if (Math.trunc(i) != mid) {
|
||
// for vertical movement
|
||
for (j = 0; j <= 2 * radius; j++) {
|
||
dist = Math.sqrt(
|
||
((i - radius) * (i - radius) * 4) + // (* 4) accounts for the offset between lines
|
||
(j - radius) * (j - radius)
|
||
);
|
||
//console.log(i, j, radius, dist);
|
||
// dist should be in the range (radius - 0.5)
|
||
// and (radius + 0.5) to print stars(*)
|
||
|
||
|
||
if (dist > radius - 1 && dist < radius + 1) { //&& dist > radius - 1
|
||
lineHasInput = true;
|
||
outputLine += "" + fixedCharAt(input, charIterate(input)); //zero-width space
|
||
} else {
|
||
outputLine += " ";
|
||
}
|
||
}
|
||
} else {
|
||
lineHasInput = true;
|
||
outputLine += fixedCharAt(input, charIterate(input)) + space + input + space + spaceOffset + fixedCharAt(input, charIterate(input));
|
||
}
|
||
|
||
//console.log(i, j, outputLine);
|
||
if (lineHasInput) {
|
||
outputString += outputLine + "\n";
|
||
}
|
||
outputLine = "";
|
||
}
|
||
return outputString;
|
||
}
|
||
|
||
// Code from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt
|
||
|
||
function fixedCharAt(str, idx) {
|
||
str = String(str);
|
||
|
||
//const surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
||
while (surrogatePairs.exec(str) !== null) {
|
||
const lastIdx = surrogatePairs.lastIndex;
|
||
if (lastIdx - 2 < idx) {
|
||
idx++;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (idx >= str.length || idx < 0) {
|
||
return "";
|
||
}
|
||
|
||
let ret = str.charAt(idx);
|
||
|
||
if (
|
||
/[\uD800-\uDBFF]/.test(ret) &&
|
||
/[\uDC00-\uDFFF]/.test(str.charAt(idx + 1))
|
||
) {
|
||
// Go one further, since one of the "characters" is part of a surrogate pair
|
||
ret += str.charAt(idx + 1);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
//console.log(design4("super long test string super long test string"));
|
||
//"super long test string super long test string"
|