diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 4ab91c1..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "Bun Development Container", - "image": "ghcr.io/nhaef/devcontainer-bun:latest", - "features": { - "ghcr.io/devcontainers/features/common-utils:2": { - "installZsh": true, - "installOhMyZsh": true, - "configureZshAsDefaultShell": true - } - }, - "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "ms-python.python", - "esbenp.prettier-vscode" - ] - } - }, - "remoteUser": "vscode", - "postCreateCommand": "sudo chown -R vscode:vscode /workspaces/DiscordBots && sudo chown -R vscode:vscode /workspaces/DiscordBots/node_modules || true" -} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 87e5610..0000000 --- a/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel - -**/*.trace -**/*.zip -**/*.tar.gz -**/*.tgz -**/*.log -package-lock.json -**/*.bun \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 8cd355e..0000000 --- a/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -FROM oven/bun AS build - -WORKDIR /app - -COPY package.json package.json -COPY bun.lock bun.lock - -RUN bun install - -COPY ./src ./src - -ENV NODE_ENV=production - -RUN bun build \ - --compile \ - --minify-whitespace \ - --minify-syntax \ - --target bun \ - --outfile server \ - ./src/index.ts - -FROM gcr.io/distroless/base - -WORKDIR /app - -COPY --from=build /app/server server - -ENV NODE_ENV=production - -CMD ["./server"] - -EXPOSE 3000 diff --git a/Makefile b/Makefile deleted file mode 100644 index e38d297..0000000 --- a/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Makefile - -BW_PROJECT_NAME=BoredGods.dev -BW_PROJECT_ID=9d72d613-8d1f-4455-8676-b2c10167aa94 -BW_DOMAIN=https://vault.bitwarden.eu - -run: - @if ! command -v bws >/dev/null 2>&1; then \ - echo "Error: bws is not installed."; \ - exit 1; \ - fi - - @if [ -z "$$BWS_ACCESS_TOKEN" ]; then \ - echo "Error: BWS_ACCESS_TOKEN environment variable is not set."; \ - exit 1; \ - fi - - @bws config server-base $(BW_DOMAIN) - @echo "Set EU connection $(BW_DOMAIN)" - - @echo "Starting app with project ${BW_PROJECT_NAME}" - @bws run --project-id $(BW_PROJECT_ID) -- bun src/index.ts diff --git a/dummy b/dummy deleted file mode 100644 index 2995a4d..0000000 --- a/dummy +++ /dev/null @@ -1 +0,0 @@ -dummy \ No newline at end of file diff --git a/package.json b/package.json deleted file mode 100644 index 7ae8bb3..0000000 --- a/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "app", - "version": "1.0.50", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "dev": "bun run --watch src/index.ts" - }, - "dependencies": { - "discord.js": "^14.18.0", - "elysia": "^1.2.25" - }, - "devDependencies": { - "bun-types": "^1.2.9" - }, - "module": "src/index.js" -} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 93a49bf..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,264 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - discord.js: - specifier: ^14.18.0 - version: 14.18.0 - elysia: - specifier: ^1.2.25 - version: 1.2.25(@sinclair/typebox@0.34.33) - devDependencies: - bun-types: - specifier: ^1.2.9 - version: 1.2.9 - -packages: - - '@discordjs/builders@1.10.1': - resolution: {integrity: sha512-OWo1fY4ztL1/M/DUyRPShB4d/EzVfuUvPTRRHRIt/YxBrUYSz0a+JicD5F5zHFoNs2oTuWavxCOVFV1UljHTng==} - engines: {node: '>=16.11.0'} - - '@discordjs/collection@1.5.3': - resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} - engines: {node: '>=16.11.0'} - - '@discordjs/collection@2.1.1': - resolution: {integrity: sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==} - engines: {node: '>=18'} - - '@discordjs/formatters@0.6.0': - resolution: {integrity: sha512-YIruKw4UILt/ivO4uISmrGq2GdMY6EkoTtD0oS0GvkJFRZbTSdPhzYiUILbJ/QslsvC9H9nTgGgnarnIl4jMfw==} - engines: {node: '>=16.11.0'} - - '@discordjs/rest@2.4.3': - resolution: {integrity: sha512-+SO4RKvWsM+y8uFHgYQrcTl/3+cY02uQOH7/7bKbVZsTfrfpoE62o5p+mmV+s7FVhTX82/kQUGGbu4YlV60RtA==} - engines: {node: '>=18'} - - '@discordjs/util@1.1.1': - resolution: {integrity: sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==} - engines: {node: '>=18'} - - '@discordjs/ws@1.2.1': - resolution: {integrity: sha512-PBvenhZG56a6tMWF/f4P6f4GxZKJTBG95n7aiGSPTnodmz4N5g60t79rSIAq7ywMbv8A4jFtexMruH+oe51aQQ==} - engines: {node: '>=16.11.0'} - - '@sapphire/async-queue@1.5.5': - resolution: {integrity: sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - - '@sapphire/shapeshift@4.0.0': - resolution: {integrity: sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==} - engines: {node: '>=v16'} - - '@sapphire/snowflake@3.5.3': - resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - - '@sinclair/typebox@0.34.33': - resolution: {integrity: sha512-5HAV9exOMcXRUxo+9iYB5n09XxzCXnfy4VTNW4xnDv+FgjzAGY989C28BIdljKqmF+ZltUwujE3aossvcVtq6g==} - - '@types/node@22.14.1': - resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==} - - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - - '@vladfrangu/async_event_emitter@2.4.6': - resolution: {integrity: sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - - bun-types@1.2.9: - resolution: {integrity: sha512-dk/kOEfQbajENN/D6FyiSgOKEuUi9PWfqKQJEgwKrCMWbjS/S6tEXp178mWvWAcUSYm9ArDlWHZKO3T/4cLXiw==} - - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} - engines: {node: '>=18'} - - discord-api-types@0.37.120: - resolution: {integrity: sha512-7xpNK0EiWjjDFp2nAhHXezE4OUWm7s1zhc/UXXN6hnFFU8dfoPHgV0Hx0RPiCa3ILRpdeh152icc68DGCyXYIw==} - - discord.js@14.18.0: - resolution: {integrity: sha512-SvU5kVUvwunQhN2/+0t55QW/1EHfB1lp0TtLZUSXVHDmyHTrdOj5LRKdR0zLcybaA15F+NtdWuWmGOX9lE+CAw==} - engines: {node: '>=18'} - - elysia@1.2.25: - resolution: {integrity: sha512-WsdQpORJvb4uszzeqYT0lg97knw1iBW1NTzJ1Jm57tiHg+DfAotlWXYbjmvQ039ssV0fYELDHinLLoUazZkEHg==} - peerDependencies: - '@sinclair/typebox': '>= 0.34.0' - openapi-types: '>= 12.0.0' - typescript: '>= 5.0.0' - peerDependenciesMeta: - openapi-types: - optional: true - typescript: - optional: true - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - lodash.snakecase@4.1.1: - resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - magic-bytes.js@1.10.0: - resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==} - - memoirist@0.3.0: - resolution: {integrity: sha512-wR+4chMgVPq+T6OOsk40u9Wlpw1Pjx66NMNiYxCQQ4EUJ7jDs3D9kTCeKdBOkvAiqXlHLVJlvYL01PvIJ1MPNg==} - - ts-mixer@6.0.4: - resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - undici@6.21.1: - resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==} - engines: {node: '>=18.17'} - - ws@8.18.1: - resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - -snapshots: - - '@discordjs/builders@1.10.1': - dependencies: - '@discordjs/formatters': 0.6.0 - '@discordjs/util': 1.1.1 - '@sapphire/shapeshift': 4.0.0 - discord-api-types: 0.37.120 - fast-deep-equal: 3.1.3 - ts-mixer: 6.0.4 - tslib: 2.8.1 - - '@discordjs/collection@1.5.3': {} - - '@discordjs/collection@2.1.1': {} - - '@discordjs/formatters@0.6.0': - dependencies: - discord-api-types: 0.37.120 - - '@discordjs/rest@2.4.3': - dependencies: - '@discordjs/collection': 2.1.1 - '@discordjs/util': 1.1.1 - '@sapphire/async-queue': 1.5.5 - '@sapphire/snowflake': 3.5.3 - '@vladfrangu/async_event_emitter': 2.4.6 - discord-api-types: 0.37.120 - magic-bytes.js: 1.10.0 - tslib: 2.8.1 - undici: 6.21.1 - - '@discordjs/util@1.1.1': {} - - '@discordjs/ws@1.2.1': - dependencies: - '@discordjs/collection': 2.1.1 - '@discordjs/rest': 2.4.3 - '@discordjs/util': 1.1.1 - '@sapphire/async-queue': 1.5.5 - '@types/ws': 8.18.1 - '@vladfrangu/async_event_emitter': 2.4.6 - discord-api-types: 0.37.120 - tslib: 2.8.1 - ws: 8.18.1 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - '@sapphire/async-queue@1.5.5': {} - - '@sapphire/shapeshift@4.0.0': - dependencies: - fast-deep-equal: 3.1.3 - lodash: 4.17.21 - - '@sapphire/snowflake@3.5.3': {} - - '@sinclair/typebox@0.34.33': {} - - '@types/node@22.14.1': - dependencies: - undici-types: 6.21.0 - - '@types/ws@8.18.1': - dependencies: - '@types/node': 22.14.1 - - '@vladfrangu/async_event_emitter@2.4.6': {} - - bun-types@1.2.9: - dependencies: - '@types/node': 22.14.1 - '@types/ws': 8.18.1 - - cookie@1.0.2: {} - - discord-api-types@0.37.120: {} - - discord.js@14.18.0: - dependencies: - '@discordjs/builders': 1.10.1 - '@discordjs/collection': 1.5.3 - '@discordjs/formatters': 0.6.0 - '@discordjs/rest': 2.4.3 - '@discordjs/util': 1.1.1 - '@discordjs/ws': 1.2.1 - '@sapphire/snowflake': 3.5.3 - discord-api-types: 0.37.120 - fast-deep-equal: 3.1.3 - lodash.snakecase: 4.1.1 - tslib: 2.8.1 - undici: 6.21.1 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - elysia@1.2.25(@sinclair/typebox@0.34.33): - dependencies: - '@sinclair/typebox': 0.34.33 - cookie: 1.0.2 - memoirist: 0.3.0 - - fast-deep-equal@3.1.3: {} - - lodash.snakecase@4.1.1: {} - - lodash@4.17.21: {} - - magic-bytes.js@1.10.0: {} - - memoirist@0.3.0: {} - - ts-mixer@6.0.4: {} - - tslib@2.8.1: {} - - undici-types@6.21.0: {} - - undici@6.21.1: {} - - ws@8.18.1: {} diff --git a/pusmirror b/pusmirror deleted file mode 100644 index e69de29..0000000 diff --git a/src/boredBot/commands.ts b/src/boredBot/commands.ts deleted file mode 100644 index 456fc10..0000000 --- a/src/boredBot/commands.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { SlashCommandBuilder } from "discord.js"; -import { Command } from "../discordBot/types"; - -export const boredBotCommands = [ - new SlashCommandBuilder() - .setName(Command.Roll) - .setDescription("Roll dice (e.g. 'd20', '6d12-4', '2d8 + 1d6+4')") - .addStringOption((option) => - option - .setName("input") - .setDescription("The dice you want to roll") - .setRequired(true), - ), - new SlashCommandBuilder() - .setName(Command.Help) - .setDescription("Displays a list of available commands."), -]; diff --git a/src/boredBot/index.ts b/src/boredBot/index.ts deleted file mode 100644 index 156d9b7..0000000 --- a/src/boredBot/index.ts +++ /dev/null @@ -1,123 +0,0 @@ -import type { SlashCommandOptionsOnlyBuilder } from "discord.js"; -import { DiceRoller } from "../diceRoller"; -import type { DiceParseResult } from "../diceRoller/types"; -import { parseDiceUserInput } from "../diceRoller/utils/parseDiceUserInput"; -import { DiscordBot } from "../discordBot"; -import { Command, MessageContent } from "../discordBot/types"; - -export class BoredBot extends DiscordBot { - private static instance: BoredBot; - - private constructor( - token: string, - applicationId: string, - commands: SlashCommandOptionsOnlyBuilder[], - ) { - super(token, applicationId, commands); - this.useCommand(); - } - - public static async getInstance( - token: string, - applicationId: string, - commands: SlashCommandOptionsOnlyBuilder[], - ): Promise { - if (!BoredBot.instance) { - BoredBot.instance = new BoredBot(token, applicationId, commands); - await BoredBot.instance.initialize("Bored Bot"); - } - return BoredBot.instance; - } - - private async useCommand() { - this.client.on("interactionCreate", async (interaction) => { - if (!interaction.isChatInputCommand()) return; - - const command = interaction.commandName as Command; - const userName = interaction.user.displayName; - const userInput = interaction.options.getString(MessageContent.Input); - - if (!userInput) throw new Error("Expected input to be defined"); - - console.log("got command"); - - switch (command) { - case Command.Roll: { - await interaction.reply( - await this.handleRollCommand(userInput, userName), - ); - } - } - }); - } - - private async handleRollCommand( - inputStringFromUser: string, - username: string, - ): Promise { - let parsedInputResult: DiceParseResult = { dices: [], mod: 0 }; - - try { - parsedInputResult = parseDiceUserInput(inputStringFromUser); - } catch (error) { - if (error instanceof Error) return error.message; - } - - const roller = new DiceRoller(username); - const resultsMessages: string[] = []; - - if (parsedInputResult.dices.length === 1) { - const singleDie = parsedInputResult.dices[0]; - const { rollResult, message } = await roller.roll(singleDie); - - const mod = parsedInputResult.mod; - const finalResult = rollResult + mod; - - let singleLine = `(${singleDie.toString()}) => ${rollResult}`; - if (mod !== 0) { - const sign = mod > 0 ? "+" : "-"; - singleLine += ` ${sign}${Math.abs(mod)} = ${finalResult}`; - } - - if (message) { - singleLine += `\n${message}`; - } - - resultsMessages.push(singleLine); - } else { - resultsMessages.push( - `You rolled ${parsedInputResult.dices.length} dice!`, - ); - - let sum = 0; - let rollCount = 1; - - for (const dieInput of parsedInputResult.dices) { - const { rollResult, message } = await roller.roll(dieInput); - sum += rollResult; - - const prefix = `Roll #${rollCount}: `; - const suffix = message ? ` **${message}**` : ""; - - resultsMessages.push( - `${prefix}(d${dieInput.toString()}) => ${rollResult}${suffix}`, - ); - rollCount++; - } - - const mod = parsedInputResult.mod; - const finalResult = sum + mod; - if (mod !== 0) { - const sign = mod > 0 ? "+" : "-"; - - resultsMessages.push( - `Result: ${sum} ${sign} ${Math.abs(mod)} = ${finalResult}`, - ); - } else { - resultsMessages.push(`**Final result: ${sum}**`); - } - } - - return resultsMessages.join("\n"); - } -} diff --git a/src/diceRoller/index.ts b/src/diceRoller/index.ts deleted file mode 100644 index 0176f49..0000000 --- a/src/diceRoller/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Critical, Dice } from "./types"; - -export class DiceRoller { - private username: string; - constructor(user: string) { - this.username = user; - } - - public async roll( - dice: (typeof Dice)[keyof typeof Dice], - ): Promise<{ rollResult: number; message?: string }> { - if (!Object.values(Dice).includes(dice)) - throw new Error(`Invalid dice type: ${dice}`); - - const { outcome: result, crit } = this.getSingleDiceRollOutcome(dice); - - if (crit.failure || crit.success) { - return { - rollResult: result, - message: crit.success - ? await this.handleCritical(Critical.Success) - : await this.handleCritical(Critical.Fail), - }; - } - return { rollResult: result }; - } - - private getSingleDiceRollOutcome(dice: (typeof Dice)[keyof typeof Dice]): { - outcome: number; - crit: { failure: boolean; success: boolean }; - } { - const roll = Math.floor(Math.random() * dice) + 1; - - switch (dice) { - case Dice.Twenty: - return { - outcome: roll, - crit: { failure: roll === 1, success: roll === 20 }, - }; - default: - return { outcome: roll, crit: { failure: false, success: false } }; - } - } - - private async handleCritical(critical: Critical): Promise { - switch (critical) { - case Critical.Fail: - return "Critical FAIL!"; - case Critical.Success: - return "Critical SUCCESS!"; - } - } -} diff --git a/src/diceRoller/types.ts b/src/diceRoller/types.ts deleted file mode 100644 index 9d8419a..0000000 --- a/src/diceRoller/types.ts +++ /dev/null @@ -1,18 +0,0 @@ -export const Dice = { - Four: 4, - Six: 6, - Ten: 10, - Twelve: 12, - Twenty: 20, - Hundrer: 100, -}; - -export enum Critical { - Fail = "fail", - Success = "success", -} - -export type DiceParseResult = { - dices: number[]; - mod: number; -}; diff --git a/src/diceRoller/utils/handleRollCommand.ts b/src/diceRoller/utils/handleRollCommand.ts deleted file mode 100644 index 8637c4a..0000000 --- a/src/diceRoller/utils/handleRollCommand.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { DiceRoller } from "../discord/dice"; -import { parseDiceUserInput } from "./parseDiceUserInput"; -import type { DiceParseResult } from "../types"; - -export async function handleRollCommand( - inputStringFromUser: string, - username: string, -): Promise { - let parsedInputResult: DiceParseResult = { dices: [], mod: 0 }; - - try { - parsedInputResult = parseDiceUserInput(inputStringFromUser); - } catch (error) { - if (error instanceof Error) return error.message; - } - - const roller = new DiceRoller(username); - const resultsMessages: string[] = []; - - if (parsedInputResult.dices.length === 1) { - const singleDie = parsedInputResult.dices[0]; - const { rollResult, message } = await roller.roll(singleDie); - - const mod = parsedInputResult.mod; - const finalResult = rollResult + mod; - - let singleLine = `(${singleDie.toString()}) => ${rollResult}`; - if (mod !== 0) { - const sign = mod > 0 ? "+" : "-"; - singleLine += ` ${sign}${Math.abs(mod)} = ${finalResult}`; - } - - if (message) { - singleLine += `\n${message}`; - } - - resultsMessages.push(singleLine); - } else { - resultsMessages.push(`You rolled ${parsedInputResult.dices.length} dice!`); - - let sum = 0; - let rollCount = 1; - - for (const dieInput of parsedInputResult.dices) { - const { rollResult, message } = await roller.roll(dieInput); - sum += rollResult; - - const prefix = `Roll #${rollCount}: `; - const suffix = message ? ` **${message}**` : ""; - - resultsMessages.push( - `${prefix}(d${dieInput.toString()}) => ${rollResult}${suffix}`, - ); - rollCount++; - } - - const mod = parsedInputResult.mod; - const finalResult = sum + mod; - if (mod !== 0) { - const sign = mod > 0 ? "+" : "-"; - - resultsMessages.push( - `Result: ${sum} ${sign} ${Math.abs(mod)} = ${finalResult}`, - ); - } else { - resultsMessages.push(`**Final result: ${sum}**`); - } - } - - return resultsMessages.join("\n"); -} diff --git a/src/diceRoller/utils/parseDiceUserInput.ts b/src/diceRoller/utils/parseDiceUserInput.ts deleted file mode 100644 index e810f03..0000000 --- a/src/diceRoller/utils/parseDiceUserInput.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Dice } from "../types"; - -const ALLOWED_DICE_SIDES = new Set(Object.values(Dice)); - -export function parseDiceUserInput(input: string): DiceParseResult { - if (typeof input !== "string" || !input.trim()) { - throw new Error("Input must be a non-empty string."); - } - - let clean = input.toLowerCase().trim(); - clean = clean.replace(/\b(roll|dice|die)\b/g, ""); - clean = clean.replace(/\s+/g, ""); - - if (/^\d+$/.test(clean)) { - const sides = Number.parseInt(clean, 10); - if (!ALLOWED_DICE_SIDES.has(sides)) { - throw new Error( - `Allowed dice sides are ${[...ALLOWED_DICE_SIDES].join(", ")}. Received: ${sides}`, - ); - } - return { dices: [sides], mod: 0 }; - } - - const tokenRegex = /(\d*d\d+|[+\-]\d+)/g; - const tokens = clean.match(tokenRegex); - - if (!tokens) { - throw new Error( - "Unable to parse any dice or modifiers. Examples: '3d6+5', 'd20-2', '2d8+1d6+4'.", - ); - } - - const dices: number[] = []; - let mod = 0; - - for (const token of tokens) { - if (token.includes("d")) { - const [countPart, sidesPart] = token.split("d"); - - let diceCount = countPart ? Number.parseInt(countPart, 10) : 1; - if (Number.isNaN(diceCount) || diceCount < 1) { - diceCount = 1; - } - - const sides = Number.parseInt(sidesPart, 10); - if (Number.isNaN(sides) || sides <= 0) { - throw new Error(`Invalid number of sides: "${sidesPart}"`); - } - - if (!ALLOWED_DICE_SIDES.has(sides)) { - throw new Error( - `Allowed dice sides are ${[...ALLOWED_DICE_SIDES].join(", ")}. Received: ${sides}`, - ); - } - - for (let i = 0; i < diceCount; i++) { - dices.push(sides); - } - } else { - const parsedMod = Number.parseInt(token, 10); - if (Number.isNaN(parsedMod)) { - throw new Error(`Invalid modifier: "${token}"`); - } - mod += parsedMod; - } - } - - return { dices, mod }; -} diff --git a/src/discordBot/index.ts b/src/discordBot/index.ts deleted file mode 100644 index 23e0b2d..0000000 --- a/src/discordBot/index.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - Client, - GatewayIntentBits, - REST, - Routes, - type SlashCommandOptionsOnlyBuilder, -} from "discord.js"; - -export abstract class DiscordBot { - private token: string; - private applicationId: string; - protected client: Client; - private commands: SlashCommandOptionsOnlyBuilder[]; - - protected constructor( - token: string, - applicationId: string, - commands: SlashCommandOptionsOnlyBuilder[], - ) { - this.client = new Client({ - intents: [ - GatewayIntentBits.Guilds, - GatewayIntentBits.GuildMessages, - GatewayIntentBits.MessageContent, - ], - }); - this.token = token; - this.applicationId = applicationId; - this.commands = commands; - } - - private async login(): Promise { - if (!this.token) { - throw new Error("No token provided when attempting to log in bot"); - } - try { - await this.client.login(this.token); - } catch (error) { - throw new Error(`Bot failed to log in: ${error}`); - } - } - - private async registerCommands(): Promise { - try { - await new REST({ version: "10" }) - .setToken(this.token) - .put(Routes.applicationCommands(this.applicationId), { - body: this.commands, - }); - } catch (error) { - throw new Error(`Failed to register slash commands: ${error}`); - } - } - - protected async initialize(botName: string): Promise { - console.log(`Initializing bot '${botName}'...`); - try { - await this.login(); - await this.registerCommands(); - console.log(`${botName} is ready!`); - } catch (error) { - console.log("Initialization error:", error); - } - } -} diff --git a/src/discordBot/types.ts b/src/discordBot/types.ts deleted file mode 100644 index 7062087..0000000 --- a/src/discordBot/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum Command { - Roll = "roll", - Help = "help", -} - -export enum MessageContent { - Input = "input", -} diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index ceaf642..0000000 --- a/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -// import { Elysia } from "elysia"; -import { BoredBot } from "./boredBot"; -import { boredBotCommands } from "./boredBot/commands"; - -// new Elysia().get("/", () => "Hello Elysia").listen(3000); -if (!process.env.DISCORD_BOT_TOKEN || !process.env.APPLICATION_ID) { - throw new Error("DISCORD_BOT_TOKEN and APPLICATION_ID must be defined in the environment variables."); -} - -await BoredBot.getInstance(process.env.DISCORD_BOT_TOKEN, process.env.APPLICATION_ID, boredBotCommands); diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 1ca2350..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "ES2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "ES2022", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - "types": ["bun-types"], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/wps/compose.yml b/wps/compose.yml deleted file mode 100644 index 1d0cf1f..0000000 --- a/wps/compose.yml +++ /dev/null @@ -1,43 +0,0 @@ -services: - bookstack: - image: lscr.io/linuxserver/bookstack:latest - container_name: bookstack - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/Oslo - - APP_URL=$APP_URL - - APP_KEY=$APP_KEY - - DB_HOST=mariadb - - DB_PORT=3306 - - DB_DATABASE=bookstack - - DB_USERNAME=bookstack - - DB_PASSWORD=$DB_PASSWORD - volumes: - - ~/bookstack/bookstack_app_data:/config - ports: - - 6875:80 - restart: always - networks: - - bookstack_network - - mariadb: - image: lscr.io/linuxserver/mariadb:latest - container_name: mariadb - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/Oslo - - MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD - - MYSQL_DATABASE=bookstack - - MYSQL_USER=bookstack - - MYSQL_PASSWORD=$DB_PASSWORD - volumes: - - ~/bookstack/bookstack_db_data:/config - restart: always - networks: - - bookstack_network - -networks: - bookstack_network: - driver: bridge \ No newline at end of file diff --git a/wps/todo.md b/wps/todo.md deleted file mode 100644 index 80cb4aa..0000000 --- a/wps/todo.md +++ /dev/null @@ -1,5 +0,0 @@ -- import stack from prod -- reverse proxy -- point domain provider to hostmanet -- ??? -- Profit \ No newline at end of file