Compare commits
18 commits
4d20d9e608
...
866beb0e04
Author | SHA1 | Date | |
---|---|---|---|
866beb0e04 | |||
8b0e93d324 | |||
2695219b20 | |||
56a04c2703 | |||
5f49117196 | |||
5beebba29a | |||
fdf52c2285 | |||
e3a583aa99 | |||
3a4665f907 | |||
60e736774d | |||
1aca8c7b60 | |||
b81f607702 | |||
6acc5a9a02 | |||
d75f7e650c | |||
923348d809 | |||
6f91134756 | |||
1acedfbd3d | |||
4ed5beb42a |
18 changed files with 530 additions and 536 deletions
|
@ -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: 18.x
|
node-version: 20.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.0.3
|
- uses: https://github.com/appleboy/ssh-action@v1.1.0
|
||||||
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 }}
|
||||||
|
|
|
@ -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: 18.x
|
node-version: 20.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.0.3
|
- uses: https://github.com/appleboy/ssh-action@v1.1.0
|
||||||
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 }}
|
||||||
|
|
|
@ -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: 18.x
|
node-version: 20.x
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- run: yarn build
|
- run: yarn build
|
||||||
- run: yarn test
|
- run: yarn test
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vylbot-app",
|
"name": "vylbot-app",
|
||||||
"version": "3.2.2",
|
"version": "3.2.3",
|
||||||
"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,14 +32,12 @@
|
||||||
"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": "9.0.5",
|
"minimatch": "10.0.1",
|
||||||
"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",
|
||||||
|
|
|
@ -29,7 +29,18 @@ export default async function List(interaction: ButtonInteraction) {
|
||||||
|
|
||||||
const totalPages = Math.ceil(moons[1] / pageLength);
|
const totalPages = Math.ceil(moons[1] / pageLength);
|
||||||
|
|
||||||
const description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
|
let description = ["*none*"];
|
||||||
|
|
||||||
|
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`)
|
||||||
|
@ -48,7 +59,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(pageNumber + 1 == totalPages));
|
.setDisabled(isLastPage));
|
||||||
|
|
||||||
await interaction.update({
|
await interaction.update({
|
||||||
embeds: [ embed ],
|
embeds: [ embed ],
|
||||||
|
|
|
@ -11,17 +11,23 @@ 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);
|
||||||
|
|
||||||
const description = moons[0].flatMap(x => `**${x.MoonNumber} -** ${x.Description.slice(0, 15)}`);
|
let description = ["*none*"];
|
||||||
|
|
||||||
|
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`)
|
||||||
|
@ -40,7 +46,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(page + 1 == totalPages));
|
.setDisabled(isLastPage));
|
||||||
|
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
embeds: [ embed ],
|
embeds: [ embed ],
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
|
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, TextChannel } 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,6 +24,8 @@ 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.`);
|
||||||
|
|
||||||
await interaction.channel.send({ embeds: [ embed ]});
|
const channel = interaction.channel as TextChannel;
|
||||||
|
|
||||||
|
await channel.send({ embeds: [ embed ]});
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
|
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, TextChannel } 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,6 +59,8 @@ export default class Code extends Command {
|
||||||
.setTitle("Entry Code")
|
.setTitle("Entry Code")
|
||||||
.setDescription(code);
|
.setDescription(code);
|
||||||
|
|
||||||
await interaction.channel.send({ embeds: [ embed ]});
|
const channel = interaction.channel as TextChannel;
|
||||||
|
|
||||||
|
await channel.send({ embeds: [ embed ]});
|
||||||
}
|
}
|
||||||
}
|
}
|
30
src/commands/linkonly.ts
Normal file
30
src/commands/linkonly.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
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}\``);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder, TextChannel } 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;
|
const channel = interaction.channel as TextChannel;
|
||||||
|
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
await interaction.reply({ content: "Channel not found.", ephemeral: true });
|
await interaction.reply({ content: "Channel not found.", ephemeral: true });
|
||||||
|
@ -109,7 +109,9 @@ export default class Rules extends Command {
|
||||||
.setLabel(buttonLabel || "Verify")
|
.setLabel(buttonLabel || "Verify")
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await interaction.channel?.send({
|
const channel = interaction.channel as TextChannel;
|
||||||
|
|
||||||
|
await channel.send({
|
||||||
components: [ row ]
|
components: [ row ]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@ 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" });
|
||||||
|
|
|
@ -2,6 +2,7 @@ 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;
|
||||||
|
@ -9,6 +10,8 @@ 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") {
|
||||||
|
|
20
src/events/MessageEvents/MessageCreate/LinkOnlyMode.ts
Normal file
20
src/events/MessageEvents/MessageCreate/LinkOnlyMode.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
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();
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
import DefaultValues from "../constants/DefaultValues";
|
|
||||||
import UserSetting from "../database/entities/UserSetting";
|
|
||||||
|
|
||||||
export default class UserSettingsHelper {
|
|
||||||
}
|
|
|
@ -12,6 +12,7 @@ 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";
|
||||||
|
@ -55,6 +56,7 @@ 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());
|
||||||
|
|
Loading…
Reference in a new issue