Skip to content

Commit

Permalink
Merge pull request #34 from Chiissu/dev
Browse files Browse the repository at this point in the history
fix a bunch of issues
  • Loading branch information
MrSerge01 authored Nov 9, 2024
2 parents 18cf54f + 9ac1e41 commit abd8881
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 95 deletions.
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
<div align="center">
<p>
<img src="static/banner.png" />
</p>
<p>
<a href="https://discord.gg/c6C25P4BuY"><img src="https://img.shields.io/discord/903852579837059113?color=5865F2&logo=discord&logoColor=white" /></a>
<a href="https://ptb.discord.com/api/oauth2/authorize?client_id=873918300726394960&permissions=8&scope=bot%20applications.commands"><img src="https://img.shields.io/badge/bot-Invite%20the%20bot%20here!-blue" /></a>
</p>
</div>

# About
Sokora is a multiplatform, multipurpose bot with the ability to add extensions to have additional features.

**Please note that Sokora is currently unstable and is only usable within Discord.**
Sokora is a multipurpose Discord bot that lets you manage your servers easily.
**Please note that Sokora is currently unstable so it might have issues.**

# Contributing
While we're developing the multiplatform version of the bot, you can still [help us](CONTRIBUTING.MD) if you find any bugs.
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"type": "module",
"scripts": {
"setup": "bun i && bun run cli/setup.ts",
"dev": "bun --watch ./src/bot.ts",
"start": "bun ./src/index.ts"
},
"dependencies": {
Expand All @@ -20,7 +21,7 @@
},
"devDependencies": {
"@types/ms": "^0.7.34",
"bun-types": "^1.1.33",
"bun-types": "^1.1.34",
"typescript": "^5.6.3"
}
}
6 changes: 3 additions & 3 deletions src/commands/About.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class About {
{
name: "📃 • General",
value: [
"Version **0.1**, *Kaishi*",
"Version **0.1.1**, *Kaishi*",
`**${members}** members • **${guilds.size}** guild${guilds.size == 1 ? "" : "s"} ${
!shards ? "" : `• **${shards}** shard${shards == 1 ? "" : "s"}`
}`
Expand All @@ -47,9 +47,9 @@ export default class About {
name: "🌌 • Entities involved",
value: [
"**Founder**: Goos",
"**Translator Lead**: ThatBOI",
"**Developers**: Dimkauzh, Froxcey, Golem64, Koslz, MQuery, Nikkerudon, Spectrum, ThatBOI",
"**Designers**: ArtyH, ZakaHaceCosas, Pjanda",
"**Translator Lead**: ThatBOI",
"**Translators**: Dimkauzh, flojo, Golem64, GraczNet, Nikkerudon, ZakaHaceCosas, SaFire, TrulyBlue",
"**Testers**: Blaze, fishy, Trynera",
"And **YOU**, for using Sokora."
Expand All @@ -58,7 +58,7 @@ export default class About {
{
name: "🔗 • Links",
value:
"[GitHub](https://www.github.com/NebulaTheBot) • [YouTube](https://www.youtube.com/@NebulaTheBot) • [Instagram](https://instagram.com/NebulaTheBot) • [Mastodon](https://mastodon.online/@[email protected]) • [Guilded](https://guilded.gg/Nebula) • [Revolt](https://rvlt.gg/28TS9aXy)"
"[GitHub](https://www.github.com/SokoraDesu) • [YouTube](https://www.youtube.com/@SokoraDesu) • [Instagram](https://instagram.com/NebulaTheBot) • [Mastodon](https://mastodon.online/@[email protected]) • [Revolt](https://rvlt.gg/28TS9aXy)"
}
)
.setFooter({ text: `Made with ${randomise(emojis)} by the Sokora team` })
Expand Down
41 changes: 20 additions & 21 deletions src/commands/Leaderboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,32 +80,31 @@ export default class Leaderboard {
fetchReply: true
});

if (totalPages > 1) {
const collector = reply.createMessageComponentCollector({
time: 30000
});
if (totalPages <= 1) return;
const collector = reply.createMessageComponentCollector({
time: 30000
});

collector.on("collect", async (i: ButtonInteraction) => {
if (i.message.id != (await reply.fetch()).id)
return await errorEmbed(
i,
"For some reason, this click would've caused the bot to error. Thankfully, this message right here prevents that."
);
collector.on("collect", async (i: ButtonInteraction) => {
if (i.message.id != (await reply.fetch()).id)
return await errorEmbed(
i,
"For some reason, this click would've caused the bot to error. Thankfully, this message right here prevents that."
);

if (i.user.id != interaction.user.id)
return errorEmbed(i, "You are not the person who executed this command.");
if (i.user.id != interaction.user.id)
return errorEmbed(i, "You are not the person who executed this command.");

collector.resetTimer({ time: 30000 });
if (i.customId == "left") page = page > 1 ? page - 1 : totalPages;
else page = page < totalPages ? page + 1 : 1;
collector.resetTimer({ time: 30000 });
if (i.customId == "left") page = page > 1 ? page - 1 : totalPages;
else page = page < totalPages ? page + 1 : 1;

await i.update({
embeds: [await generateEmbed()],
components: [row]
});
await i.update({
embeds: [await generateEmbed()],
components: [row]
});
});

collector.on("end", async () => await interaction.editReply({ components: [] }));
}
collector.on("end", async () => await interaction.editReply({ components: [] }));
}
}
21 changes: 14 additions & 7 deletions src/commands/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,25 @@ export default class Settings {
const key = interaction.options.getSubcommand() as keyof typeof settingsDefinition;
const values = interaction.options.data[0].options!;
if (!values.length) {
const embed = new EmbedBuilder().setTitle(`Settings for ${key}`).setColor(genColor(100));
const description: string[] = [];
const settingsDef = settingsDefinition[key];
const field: string[] = [];
Object.keys(settingsDef.settings).forEach(name =>
field.push(`**${name}**: ${getSetting(guild.id, key, name)?.toString() || "Not set"}`)
);

Object.keys(settingsDefinition[key]).forEach(name => {
description.push(`${name}: ${getSetting(guild.id, key, name)?.toString() || "Not set"}`);
embed.setDescription(description.join("\n"));
});
const embed = new EmbedBuilder()
.setAuthor({ name: `Settings of ${key}` })
.setDescription(`${settingsDef.description}`)
.addFields({ name: "🧑‍🔧 • Settings", value: field.join("\n") })
.setColor(genColor(100));

return await interaction.reply({ embeds: [embed] });
}

const embed = new EmbedBuilder().setTitle(`Parameters changed`).setColor(genColor(100));
const embed = new EmbedBuilder()
.setAuthor({ name: "Parameters changed" })
.setColor(genColor(100));

values.forEach(option => {
setSetting(guild.id, key, option.name, option.value as string);
embed.addFields({
Expand Down
2 changes: 1 addition & 1 deletion src/commands/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default class User {
`**${guildRoles.filter(role => target.roles.cache.has(role.id)).size! - 1}** ${
memberRoles.length == 1 ? "role" : "roles"
}${memberRoles
.slice(0, 5)
.slice(0, 3)
.map(role => `<@&${role[1].id}>`)
.join(", ")}${rolesLength > 3 ? ` and **${rolesLength - 3}** more` : ""}`
);
Expand Down
7 changes: 6 additions & 1 deletion src/commands/news/View.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ export default class View {
.setStyle(ButtonStyle.Primary)
);

const reply = await interaction.reply({ embeds: [getEmbed()], components: [row] });
const reply = await interaction.reply({
embeds: [getEmbed()],
components: page >= 1 ? [row] : []
});

if (page < 1) return;
const collector = reply.createMessageComponentCollector({ time: 30000 });
collector.on("collect", async (i: ButtonInteraction) => {
if (i.message.id != (await reply.fetch()).id)
Expand Down
2 changes: 1 addition & 1 deletion src/events/easterEggs/fireship.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default async function run(message: Message) {
if (
content.startsWith("this has been") &&
content.endsWith("in 100 seconds") &&
message.content != "this has been in 100 seconds"
message.content.toLowerCase() != "this has been in 100 seconds"
)
await (message.channel as TextChannel).send(
"hit the like button and subscribe if you want to see more short videos like this thanks for watching and I will see you in the next one"
Expand Down
48 changes: 9 additions & 39 deletions src/events/interactionCreate.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,14 @@
import { file } from "bun";
import type { AutocompleteInteraction, CommandInteraction } from "discord.js";
import { join } from "path";
import { pathToFileURL } from "url";
import { capitalize } from "../utils/capitalize";
import { Commands } from "../handlers/commands";
import { Event } from "../utils/types";

async function getCommand(
interaction: CommandInteraction | AutocompleteInteraction,
options: any
): Promise<any> {
const commandName = capitalize(interaction.commandName)!;
const subcommandName = capitalize(options.getSubcommand(false));
const commandGroupName = capitalize(options.getSubcommandGroup(false));
let commandImportPath = join(
join(process.cwd(), "src", "commands"),
`${
subcommandName
? `${commandName.toLowerCase()}/${
commandGroupName ? `${commandGroupName}/${subcommandName}` : subcommandName
}`
: commandName
}.ts`
export default (async function run(interaction) {
if (!interaction.isChatInputCommand() && !interaction.isAutocomplete()) return;
const command = await new Commands(interaction.client).getCommand(
interaction.commandName,
interaction.options
);
if (!command) return;

if (!(await file(commandImportPath).exists()))
commandImportPath = join(join(process.cwd(), "src", "commands", `${commandName}.ts`));

return new (await import(pathToFileURL(commandImportPath).toString())).default();
}

export default (async function run(interaction) {
if (interaction.isChatInputCommand()) {
const command = await getCommand(interaction, interaction.options);
if (!command) return;
if (command.deferred) await interaction.deferReply();
command.run(interaction);
} else if (interaction.isAutocomplete()) {
const command = await getCommand(interaction, interaction.options);
if (!command) return;
if (!command.autocomplete) return;
command.autocomplete(interaction);
}
if (interaction.isChatInputCommand()) command.run(interaction);
if (command.autocomplete) command.autocomplete(interaction);
} as Event<"interactionCreate">);
52 changes: 39 additions & 13 deletions src/handlers/commands.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Guild,
SlashCommandBuilder,
SlashCommandSubcommandBuilder,
SlashCommandSubcommandGroupBuilder,
type Client
} from "discord.js";
Expand All @@ -9,18 +10,18 @@ import { join } from "path";
import { pathToFileURL } from "url";
import { getDisabledCommands } from "../utils/database/disabledCommands";

export let commands: { data: SlashCommandBuilder; run: any; autocomplete: any }[] = [];
let subcommands: { data: SlashCommandSubcommandBuilder; run: any; autocomplete: any }[] = [];
export class Commands {
client: Client;
commands: any[] = [];
constructor(client: Client) {
this.client = client;
}

private async createSubCommand(
name: string,
...disabledCommands: string[]
): Promise<SlashCommandBuilder> {
private async createSubCommand(name: string, ...disabledCommands: string[]) {
const commandsPath = join(process.cwd(), "src", "commands");
const run = [];
const autocomplete = [];
const command = new SlashCommandBuilder()
.setName(name.toLowerCase())
.setDescription("This command has no description.");
Expand All @@ -43,7 +44,17 @@ export class Commands {
const subCommand = new subCommandModule.default();

command.addSubcommand(subCommand.data);
if ("autocompleteHandler" in subCommand) subCommand.autocompleteHandler(this.client);
run.push(subCommand.run);
subcommands.push({
data: subCommand.data,
run: subCommand.run,
autocomplete: subCommand.autocomplete
});

if ("autocompleteHandler" in subCommand) {
subCommand.autocompleteHandler(this.client);
autocomplete.push(subCommand.autocomplete);
}
continue;
}

Expand Down Expand Up @@ -76,12 +87,11 @@ export class Commands {
command.addSubcommandGroup(subCommandGroup);
}

return command;
return { data: command, run: run, autocomplete: autocomplete };
}

async loadCommands(...disabledCommands: string[]) {
const commandsPath = join(process.cwd(), "src", "commands");
this.commands = [];
const commandFiles = readdirSync(commandsPath, { withFileTypes: true });

for (const commandFile of commandFiles) {
Expand All @@ -90,7 +100,7 @@ export class Commands {

if (commandFile.isFile()) {
const commandImport = await import(pathToFileURL(join(commandsPath, name)).toString());
this.commands.push(new commandImport.default().data);
commands.push(new commandImport.default());
continue;
}

Expand All @@ -99,13 +109,20 @@ export class Commands {
join(commandsPath, name),
...disabledCommands
);
this.commands.push(subCommand);

commands.push({
data: subCommand.data,
run: subCommand.run,
autocomplete: subCommand.autocomplete
});
}

return commands;
}

async registerCommandsForGuild(guild: Guild, ...disabledCommands: string[]) {
await this.loadCommands(...disabledCommands);
await guild.commands.set(this.commands);
await guild.commands.set(commands.map(command => command.data));
}

async registerCommands(): Promise<any[]> {
Expand All @@ -115,9 +132,18 @@ export class Commands {
for (const guildID of guilds.keys()) {
const disabledCommands = getDisabledCommands(guildID);
if (disabledCommands.length > 0) await this.loadCommands(...disabledCommands);
await guilds.get(guildID)?.commands.set(this.commands);
await guilds.get(guildID)?.commands.set(commands.map(command => command.data));
}

return this.commands;
return commands;
}

async getCommand(name: string, options: any) {
const subcommandName = options.getSubcommand(false);

const command = commands.filter(command => command.data.name == name)[0];
const subcommand = subcommands.filter(subcommand => subcommand.data.name == subcommandName)[0];
if (!subcommand) return command;
return subcommand;
}
}
3 changes: 2 additions & 1 deletion src/utils/database/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const settingsDefinition: Record<
},
cooldown: {
type: "INTEGER",
desc: "Set the cooldown between messages that add XP.",
desc: "Set the cooldown between messages that add XP (in seconds).",
val: 2
},
difficulty: {
Expand Down Expand Up @@ -156,6 +156,7 @@ export function getSetting<
const set = settingsDefinition[key].settings[setting];

if (!res.length) {
if (!set) return null;
if (set.type == "LIST") return null;
return set.val;
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/embeds/errorEmbed.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmbedBuilder, type ChatInputCommandInteraction, type ButtonInteraction } from "discord.js";
import { EmbedBuilder, type ButtonInteraction, type ChatInputCommandInteraction } from "discord.js";
import { genColor } from "../colorGen";

/**
Expand Down
Binary file removed static/banner.png
Binary file not shown.

0 comments on commit abd8881

Please sign in to comment.