Compare commits

..

No commits in common. "866beb0e049e4ca2a098f11a0293c0822082a58b" and "4d20d9e6080d30fae268c8be9516186f70208740" have entirely different histories.

18 changed files with 536 additions and 530 deletions

View file

@ -16,7 +16,7 @@ jobs:
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20.x node-version: 18.x
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn build - run: yarn build
- run: yarn test - run: yarn test
@ -29,7 +29,7 @@ jobs:
needs: build needs: build
runs-on: node runs-on: node
steps: steps:
- uses: https://github.com/appleboy/ssh-action@v1.1.0 - uses: https://github.com/appleboy/ssh-action@v1.0.3
env: env:
DB_NAME: ${{ secrets.PROD_DB_NAME }} DB_NAME: ${{ secrets.PROD_DB_NAME }}
DB_AUTH_USER: ${{ secrets.PROD_DB_AUTH_USER }} DB_AUTH_USER: ${{ secrets.PROD_DB_AUTH_USER }}

View file

@ -16,7 +16,7 @@ jobs:
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20.x node-version: 18.x
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn build - run: yarn build
- run: yarn test - run: yarn test
@ -29,7 +29,7 @@ jobs:
needs: build needs: build
runs-on: node runs-on: node
steps: steps:
- uses: https://github.com/appleboy/ssh-action@v1.1.0 - uses: https://github.com/appleboy/ssh-action@v1.0.3
env: env:
DB_NAME: ${{ secrets.STAGE_DB_NAME }} DB_NAME: ${{ secrets.STAGE_DB_NAME }}
DB_AUTH_USER: ${{ secrets.STAGE_DB_AUTH_USER }} DB_AUTH_USER: ${{ secrets.STAGE_DB_AUTH_USER }}

View file

@ -18,7 +18,7 @@ jobs:
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20.x node-version: 18.x
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn build - run: yarn build
- run: yarn test - run: yarn test

View file

@ -1,6 +1,6 @@
{ {
"name": "vylbot-app", "name": "vylbot-app",
"version": "3.2.3", "version": "3.2.2",
"description": "A discord bot made for Vylpes' Den", "description": "A discord bot made for Vylpes' Den",
"main": "./dist/vylbot", "main": "./dist/vylbot",
"typings": "./dist", "typings": "./dist",
@ -32,12 +32,14 @@
"discord.js": "^14.3.0", "discord.js": "^14.3.0",
"dotenv": "^16.0.0", "dotenv": "^16.0.0",
"emoji-regex": "^10.0.0", "emoji-regex": "^10.0.0",
"minimatch": "10.0.1", "minimatch": "9.0.5",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"random-bunny": "^2.1.6", "random-bunny": "^2.1.6",
"typeorm": "^0.3.20" "typeorm": "0.3.20"
}, },
"resolutions": { "resolutions": {
"**/semver": "^7.5.2",
"**/undici": "^6.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",

View file

@ -29,18 +29,7 @@ export default async function List(interaction: ButtonInteraction) {
const totalPages = Math.ceil(moons[1] / pageLength); const totalPages = Math.ceil(moons[1] / pageLength);
let description = ["*none*"]; const description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
if (moons[0].length > 0) {
description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
}
const moonDifference = totalMoons - moons[1];
const isLastPage = pageNumber + 1 == totalPages || moons[0].length == 0;
if (isLastPage && moonDifference > 0) {
description.push(`...plus ${moonDifference} more untracked`);
}
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle(`${member?.user.username}'s Moons`) .setTitle(`${member?.user.username}'s Moons`)
@ -59,7 +48,7 @@ export default async function List(interaction: ButtonInteraction) {
.setCustomId(`moons list ${userId} ${pageNumber + 1}`) .setCustomId(`moons list ${userId} ${pageNumber + 1}`)
.setLabel("Next") .setLabel("Next")
.setStyle(ButtonStyle.Primary) .setStyle(ButtonStyle.Primary)
.setDisabled(isLastPage)); .setDisabled(pageNumber + 1 == totalPages));
await interaction.update({ await interaction.update({
embeds: [ embed ], embeds: [ embed ],

View file

@ -11,23 +11,17 @@ export default async function ListMoons(interaction: CommandInteraction) {
const moons = await Moon.FetchPaginatedMoonsByUserId(user.id, pageLength, page); const moons = await Moon.FetchPaginatedMoonsByUserId(user.id, pageLength, page);
if (!moons || moons[0].length == 0) {
await interaction.reply(`${user.username} does not have any moons or page is invalid.`);
return;
}
const moonSetting = await UserSetting.FetchOneByKey(interaction.user.id, "moons"); const moonSetting = await UserSetting.FetchOneByKey(interaction.user.id, "moons");
const totalMoons = moonSetting && Number(moonSetting.Value) ? Number(moonSetting.Value) : 0; const totalMoons = moonSetting && Number(moonSetting.Value) ? Number(moonSetting.Value) : 0;
const totalPages = Math.ceil(moons[1] / pageLength); const totalPages = Math.ceil(moons[1] / pageLength);
let description = ["*none*"]; const description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
if (moons[0].length > 0) {
description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
}
const moonDifference = totalMoons - moons[1];
const isLastPage = page + 1 == totalPages || moons[0].length == 0;
if (isLastPage && moonDifference > 0) {
description.push(`...plus ${moonDifference} more untracked`);
}
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setTitle(`${user.username}'s Moons`) .setTitle(`${user.username}'s Moons`)
@ -46,7 +40,7 @@ export default async function ListMoons(interaction: CommandInteraction) {
.setCustomId(`moons list ${user.id} ${page + 1}`) .setCustomId(`moons list ${user.id} ${page + 1}`)
.setLabel("Next") .setLabel("Next")
.setStyle(ButtonStyle.Primary) .setStyle(ButtonStyle.Primary)
.setDisabled(isLastPage)); .setDisabled(page + 1 == totalPages));
await interaction.reply({ await interaction.reply({
embeds: [ embed ], embeds: [ embed ],

View file

@ -0,0 +1,28 @@
import { CommandInteraction, PermissionFlagsBits, SlashCommandBuilder } from "discord.js";
import { Command } from "../../type/command";
import UserSetting from "../../database/entities/UserSetting";
export default class MoonSet extends Command {
constructor() {
super();
this.CommandBuilder = new SlashCommandBuilder()
.setName("moonset")
.setDescription("Manually set a user's moons")
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
.addUserOption(x => x
.setName("user")
.setDescription("The user to set")
.setRequired(true))
.addNumberOption(x => x
.setName("count")
.setDescription("The amount the user will have")
.setRequired(true)
.setMinValue(0));
}
public override async execute(interaction: CommandInteraction) {
const user = interaction.options.get("user", true).user!;
const count = interaction.options.get("count", true).value! as number;
}
}

View file

@ -1,4 +1,4 @@
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
import { Command } from "../../type/command"; import { Command } from "../../type/command";
@ -24,8 +24,6 @@ export default class Entry extends Command {
.setTitle("Welcome") .setTitle("Welcome")
.setDescription(`Welcome to the server! Please make sure to read the rules in the <#${rulesChannelId}> channel and type the code found there in here to proceed to the main part of the server.`); .setDescription(`Welcome to the server! Please make sure to read the rules in the <#${rulesChannelId}> channel and type the code found there in here to proceed to the main part of the server.`);
const channel = interaction.channel as TextChannel; await interaction.channel.send({ embeds: [ embed ]});
await channel.send({ embeds: [ embed ]});
} }
} }

View file

@ -1,4 +1,4 @@
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import SettingsHelper from "../helpers/SettingsHelper"; import SettingsHelper from "../helpers/SettingsHelper";
import StringTools from "../helpers/StringTools"; import StringTools from "../helpers/StringTools";
import { Command } from "../type/command"; import { Command } from "../type/command";
@ -59,8 +59,6 @@ export default class Code extends Command {
.setTitle("Entry Code") .setTitle("Entry Code")
.setDescription(code); .setDescription(code);
const channel = interaction.channel as TextChannel; await interaction.channel.send({ embeds: [ embed ]});
await channel.send({ embeds: [ embed ]});
} }
} }

View file

@ -1,30 +0,0 @@
import { CommandInteraction, PermissionFlagsBits, SlashCommandBuilder } from "discord.js";
import { Command } from "../type/command";
import SettingsHelper from "../helpers/SettingsHelper";
export default class Linkonly extends Command {
constructor() {
super();
this.CommandBuilder = new SlashCommandBuilder()
.setName("linkonly")
.setDescription("Set the link only channel, leave blank to disable")
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
.addChannelOption(x => x
.setName("channel")
.setDescription("The channel"));
}
public override async execute(interaction: CommandInteraction) {
if (!interaction.guild) return;
const channel = interaction.options.get("channel")?.channel;
const channelid = channel?.id ?? "";
const channelName = channel?.name ?? "<NONE>";
await SettingsHelper.SetSetting("channel.linkonly", interaction.guild.id, channelid);
await interaction.reply(`Set the link only channel to \`${channelName}\``);
}
}

View file

@ -1,4 +1,4 @@
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import { existsSync, readFileSync } from "fs"; import { existsSync, readFileSync } from "fs";
import EmbedColours from "../constants/EmbedColours"; import EmbedColours from "../constants/EmbedColours";
import { Command } from "../type/command"; import { Command } from "../type/command";
@ -79,7 +79,7 @@ export default class Rules extends Command {
embeds.push(embed); embeds.push(embed);
}); });
const channel = interaction.channel as TextChannel; const channel = interaction.channel;
if (!channel) { if (!channel) {
await interaction.reply({ content: "Channel not found.", ephemeral: true }); await interaction.reply({ content: "Channel not found.", ephemeral: true });
@ -109,9 +109,7 @@ export default class Rules extends Command {
.setLabel(buttonLabel || "Verify") .setLabel(buttonLabel || "Verify")
]); ]);
const channel = interaction.channel as TextChannel; await interaction.channel?.send({
await channel.send({
components: [ row ] components: [ row ]
}); });

View file

@ -44,9 +44,6 @@ export default class DefaultValues {
this.values.push({ Key: "verification.role", Value: "Entry" }); this.values.push({ Key: "verification.role", Value: "Entry" });
this.values.push({ Key: "verification.code", Value: "" }); this.values.push({ Key: "verification.code", Value: "" });
// Gif Only Mode
this.values.push({ Key: "channel.linkonly", Value: "" })
// Event // Event
this.values.push({ Key: "event.message.delete.enabled", Value: "false" }); this.values.push({ Key: "event.message.delete.enabled", Value: "false" });
this.values.push({ Key: "event.message.delete.channel", Value: "message-logs" }); this.values.push({ Key: "event.message.delete.channel", Value: "message-logs" });

View file

@ -2,7 +2,6 @@ import { Message } from "discord.js";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
import VerificationCheck from "./MessageCreate/VerificationCheck"; import VerificationCheck from "./MessageCreate/VerificationCheck";
import CacheHelper from "../../helpers/CacheHelper"; import CacheHelper from "../../helpers/CacheHelper";
import LinkOnlyMode from "./MessageCreate/LinkOnlyMode";
export default async function MessageCreate(message: Message) { export default async function MessageCreate(message: Message) {
if (!message.guild) return; if (!message.guild) return;
@ -10,8 +9,6 @@ export default async function MessageCreate(message: Message) {
await CacheHelper.UpdateServerCache(message.guild); await CacheHelper.UpdateServerCache(message.guild);
await LinkOnlyMode(message);
const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id); const isVerificationEnabled = await SettingsHelper.GetSetting("verification.enabled", message.guild.id);
if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") { if (isVerificationEnabled && isVerificationEnabled.toLocaleLowerCase() == "true") {

View file

@ -1,20 +0,0 @@
import { Message } from "discord.js";
import SettingsHelper from "../../../helpers/SettingsHelper";
export default async function LinkOnlyMode(message: Message) {
if (!message.guild) return;
const gifOnlyMode = await SettingsHelper.GetSetting("channel.linkonly", message.guild.id);
if (!gifOnlyMode) return;
const channel = message.guild.channels.cache.find(x => x.id == gifOnlyMode) || message.guild.channels.fetch(gifOnlyMode);
if (!channel) return;
if (message.content.startsWith("https://") || message.content.startsWith("http://")) return;
if (!message.deletable) return;
await message.delete();
}

View file

@ -0,0 +1,5 @@
import DefaultValues from "../constants/DefaultValues";
import UserSetting from "../database/entities/UserSetting";
export default class UserSettingsHelper {
}

View file

@ -12,7 +12,6 @@ import Config from "./commands/config";
import Disable from "./commands/disable"; import Disable from "./commands/disable";
import Ignore from "./commands/ignore"; import Ignore from "./commands/ignore";
import Kick from "./commands/kick"; import Kick from "./commands/kick";
import Linkonly from "./commands/linkonly";
import Poll from "./commands/poll"; import Poll from "./commands/poll";
import Role from "./commands/Role/role"; import Role from "./commands/Role/role";
import ConfigRole from "./commands/Role/config"; import ConfigRole from "./commands/Role/config";
@ -56,7 +55,6 @@ export default class Registry {
CoreClient.RegisterCommand("disable", new Disable()); CoreClient.RegisterCommand("disable", new Disable());
CoreClient.RegisterCommand("ignore", new Ignore()); CoreClient.RegisterCommand("ignore", new Ignore());
CoreClient.RegisterCommand("kick", new Kick()); CoreClient.RegisterCommand("kick", new Kick());
CoreClient.RegisterCommand("linkonly", new Linkonly());
CoreClient.RegisterCommand("poll", new Poll()); CoreClient.RegisterCommand("poll", new Poll());
CoreClient.RegisterCommand("rules", new Rules()); CoreClient.RegisterCommand("rules", new Rules());
CoreClient.RegisterCommand("say", new Say()); CoreClient.RegisterCommand("say", new Say());

900
yarn.lock

File diff suppressed because it is too large Load diff