Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 31 additions & 39 deletions src/commands/context-menu/editMsg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,11 @@ export default class EditMessage extends BaseCommand {
messageInDb.originalMsg.serverId,
);

if (
hubSettings.has('BlockInvites') &&
(newMessage.includes('discord.gg') ||
newMessage.includes('discord.com/invite') ||
newMessage.includes('dsc.gg'))
) {
const inviteLinks = ['discord.gg', 'discord.com/invite', 'dsc.gg'];
const hasBlockInvites = hubSettings.has('BlockInvites');
const hasDiscordInvite = inviteLinks.some((link) => newMessage.includes(link));

if (hasBlockInvites && hasDiscordInvite) {
await interaction.editReply(
t({ phrase: 'errors.inviteLinks', locale: interaction.user.locale }, { emoji: emojis.no }),
);
Expand All @@ -168,7 +167,7 @@ export default class EditMessage extends BaseCommand {
.fetchWebhook(webhookURL[webhookURL.length - 2])
?.catch(() => null);

if (!webhook || webhook.owner?.id !== interaction.client.user.id) return false;
if (webhook?.owner?.id !== interaction.client.user.id) return false;

// finally, edit the message
return await webhook
Expand Down Expand Up @@ -217,49 +216,42 @@ export default class EditMessage extends BaseCommand {
target: Message,
newMessage: string,
serverId: string,
oldImageUrl?: string | null,
newImageUrl?: string | null,
opts?: {
oldImageUrl?: string | null;
newImageUrl?: string | null;
},
) {
let newEmbed = new EmbedBuilder();
const embedContent =
newMessage.replace(oldImageUrl ?? '', '').replace(newImageUrl ?? '', '') || null;

if (target.content) {
const guild = await target.client.fetchGuild(serverId);

// create a new embed if the message being edited is in compact mode
newEmbed
.setAuthor({ name: user.username, iconURL: user.displayAvatarURL() })
.setDescription(embedContent)
.setColor('Random')
.setImage(newImageUrl ?? oldImageUrl ?? null)
.addFields(
target.embeds.at(0)?.fields.at(0)
? [{ name: 'Replying-to', value: `${target.embeds[0].description}` }]
: [],
)
.setFooter({ text: `Server: ${guild?.name}` });
}
else {
newMessage.replace(opts?.oldImageUrl ?? '', '').replace(opts?.newImageUrl ?? '', '') ?? null;
const embedImage = opts?.newImageUrl ?? opts?.oldImageUrl ?? null;

if (!target.content) {
// utilize the embed directly from the message
newEmbed = EmbedBuilder.from(target.embeds[0])
.setDescription(embedContent)
.setImage(newImageUrl ?? oldImageUrl ?? null);
return EmbedBuilder.from(target.embeds[0]).setDescription(embedContent).setImage(embedImage);
}

return newEmbed;
const guild = await target.client.fetchGuild(serverId);

// create a new embed if the message being edited is in compact mode
return new EmbedBuilder()
.setAuthor({ name: user.username, iconURL: user.displayAvatarURL() })
.setDescription(embedContent)
.setColor('Random')
.setImage(embedImage)
.addFields(
target.embeds.at(0)?.fields.at(0)
? [{ name: 'Replying-to', value: `${target.embeds[0].description}` }]
: [],
)
.setFooter({ text: `Server: ${guild?.name}` });
}

static async fabricateNewMsg(user: User, target: Message, newMessage: string, serverId: string) {
const { oldImageUrl, newImageUrl } = await this.getImageUrls(target, newMessage);
const newEmbed = await this.buildNewEmbed(
user,
target,
newMessage,
serverId,
const newEmbed = await this.buildNewEmbed(user, target, newMessage, serverId, {
oldImageUrl,
newImageUrl,
);
});

// if the message being edited is in compact mode
// then we create a new embed with the new message and old reply
Expand Down
46 changes: 23 additions & 23 deletions src/commands/slash/Information/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ export default class Stats extends BaseCommand {
{
name: 'Bot Stats',
value: stripIndents`
- Up Since: ${time(upSince, 'R')}
- Up Since: ${time(upSince, 'R')}
- Servers: ${guildCount}
- Members: ${memberCount}
- Members: ${memberCount}
`,
inline: true,
},
Expand Down Expand Up @@ -120,37 +120,37 @@ export default class Stats extends BaseCommand {
}));
});

if (customId.suffix === 'shardStats') {
const embed = new EmbedBuilder()
.setColor(colors.invisible)
.setDescription(
stripIndents`
if (customId.suffix !== 'shardStats') return;

const embed = new EmbedBuilder()
.setColor(colors.invisible)
.setDescription(
stripIndents`
### Shard Stats
**Total Shards:** ${interaction.client.cluster.info.TOTAL_SHARDS}
**On Shard:** ${interaction.guild?.shardId}
`,
)
.setFields(
allCusterData.flat().map((shard) => {
return {
name: `Shard #${shard.id} - ${Status[shard.status]}`,
value: stripIndents`\`\`\`elm
)
.setFields(
allCusterData.flat().map((shard) => {
return {
name: `Shard #${shard.id} - ${Status[shard.status]}`,
value: stripIndents`\`\`\`elm
Ping: ${shard.ping}ms
Uptime: ${shard.uptime ? msToReadable(shard.uptime) : '0 ms'}
Servers: ${shard.totalGuilds}
RAM Usage: ${shard.memUsage} MB
\`\`\`
`,
inline: true,
};
}),
)
.setFooter({
text: `InterChat v${interaction.client.version}${isDevBuild ? '+dev' : ''}`,
iconURL: interaction.client.user.displayAvatarURL(),
});
inline: true,
};
}),
)
.setFooter({
text: `InterChat v${interaction.client.version}${isDevBuild ? '+dev' : ''}`,
iconURL: interaction.client.user.displayAvatarURL(),
});

await interaction.reply({ embeds: [embed], ephemeral: true });
}
await interaction.reply({ embeds: [embed], ephemeral: true });
}
}
10 changes: 4 additions & 6 deletions src/commands/slash/Staff/find/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export default class Server extends Find {
const hubsOwned = await db.hubs.findMany({
where: { ownerId: user.id },
});
const numServersOwned = serversOwned.length > 0 ? serversOwned.join(', ') : 'None';
const numHubOwned = hubsOwned.length > 0 ? hubsOwned.map((hub) => hub.name).join(', ') : 'None';

const embed = new EmbedBuilder()
.setAuthor({ name: user.username, iconURL: user.avatarURL()?.toString() })
Expand All @@ -43,17 +45,13 @@ export default class Server extends Find {
> ${emojis.mention} **Username:** ${user.username}
> ${emojis.members} **Created:** <t:${Math.round(user.createdTimestamp / 1000)}:R>
> ${emojis.bot} **Bot:** ${user.bot}
> ${emojis.owner} **Servers Owned:** ${
serversOwned.length > 0 ? serversOwned.join(', ') : 'None'
}
> ${emojis.owner} **Servers Owned:** ${numServersOwned}
`,
},
{
name: 'Network',
value: stripIndents`
> ${emojis.chat_icon} **Hubs Owned:** ${
hubsOwned.length > 0 ? hubsOwned.map((hub) => hub.name).join(', ') : 'None'
}
> ${emojis.chat_icon} **Hubs Owned:** ${numHubOwned}
> ${emojis.delete} **Blacklisted:** ${userInBlacklist ? 'Yes' : 'No'}`,
},
]);
Expand Down
8 changes: 0 additions & 8 deletions src/core/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import { commandsMap, interactionsMap } from './BaseCommand.js';
import db from '../utils/Db.js';
import Sentry, { captureException } from '@sentry/node';
import Scheduler from '../services/SchedulerService.js';
import NSFWClient from '../utils/NSFWDetection.js';
import ReactionUpdater from '../utils/ReactionUpdater.js';
import CooldownService from '../services/CooldownService.js';
import BlacklistManager from '../managers/BlacklistManager.js';
import { RemoveMethods } from '../typings/index.js';
Expand All @@ -28,7 +26,6 @@ import {
} from '../services/HubLoggerService.js';
import 'dotenv/config';
import { loadLocales, supportedLocaleCodes } from '../utils/Locale.js';
import EventManager from '../managers/EventManager.js';
import { connectedList } from '@prisma/client';
import Logger from '../utils/Logger.js';
import loadCommandFiles from '../utils/LoadCommands.js';
Expand All @@ -37,10 +34,6 @@ export default class SuperClient<R extends boolean = boolean> extends Client<R>
// A static instance of the SuperClient class to be used globally.
public static instance: SuperClient;

// classes
private readonly reactionUpdater = new ReactionUpdater();
private readonly eventManager = EventManager;

private _connectionCache: Collection<string, connectedList> = new Collection();
private _cachePopulated = false;
private readonly scheduler = new Scheduler();
Expand All @@ -53,7 +46,6 @@ export default class SuperClient<R extends boolean = boolean> extends Client<R>
readonly webhooks = new Collection<string, WebhookClient>();
readonly reactionCooldowns = new Collection<string, number>();

readonly nsfwDetector = new NSFWClient();
readonly commandCooldowns = new CooldownService();
readonly reportLogger = new ReportLogger(this);
readonly cluster = new ClusterClient(this);
Expand Down
8 changes: 8 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import Logger from './utils/Logger.js';
import SuperClient from './core/Client.js';
import { eventMethods } from './decorators/GatewayEvent.js';
import ReactionUpdater from './utils/ReactionUpdater.js';
import EventManager from './managers/EventManager.js';

const client = new SuperClient();

// dum classes
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _reactionUpdater = ReactionUpdater;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _eventManager = EventManager;

// decorator events
eventMethods.forEach((methods, eventName) => {
methods.forEach((method) => client.on(eventName, method.bind(this)));
Expand Down
Loading