worked on NSFW Image testing
diff --git a/package.json b/package.json
index 96c93ce..6a9a795 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
         "@tensorflow/tfjs-node": "^3.18.0",
         "@total-typescript/ts-reset": "^0.3.7",
         "@tsconfig/node18-strictest-esm": "^1.0.0",
+        "@types/gm": "^1.25.0",
         "@types/node": "^18.14.6",
         "@ungap/structured-clone": "^1.0.1",
         "agenda": "^4.3.0",
@@ -15,6 +16,8 @@
         "eslint": "^8.21.0",
         "express": "^4.18.1",
         "fuse.js": "^6.6.2",
+        "gifencoder": "^2.0.1",
+        "gm": "^1.25.0",
         "humanize-duration": "^3.27.1",
         "immutable": "^4.1.0",
         "lodash": "^4.17.21",
@@ -66,6 +69,7 @@
     "type": "module",
     "devDependencies": {
         "@types/clamscan": "^2.0.4",
+        "@types/gifencoder": "^2.0.1",
         "@types/lodash": "^4.14.191",
         "@typescript-eslint/eslint-plugin": "^5.32.0",
         "@typescript-eslint/parser": "^5.32.0",
diff --git a/src/api/index.ts b/src/api/index.ts
index 41f281d..79b115e 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -1,3 +1,4 @@
+#!/bin
 import type { Guild, GuildMember } from "discord.js";
 import type { NucleusClient } from "../utils/client.js";
 //@ts-expect-error
diff --git a/src/commands/settings/logs/warnings.ts b/src/commands/settings/logs/warnings.ts
index 38b645a..a988fae 100644
--- a/src/commands/settings/logs/warnings.ts
+++ b/src/commands/settings/logs/warnings.ts
@@ -5,12 +5,14 @@
     ButtonBuilder,
     ButtonStyle,
     ChannelSelectMenuBuilder,
-    ChannelType
+    ChannelType,
+    ComponentType
 } from "discord.js";
 import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../../utils/getEmojiByName.js";
 import type { SlashCommandSubcommandBuilder } from "discord.js";
 import client from "../../../utils/client.js";
+import _ from "lodash";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder.setName("warnings").setDescription("Settings for the staff notifications channel");
@@ -24,7 +26,7 @@
     });
 
     let data = await client.database.guilds.read(interaction.guild.id);
-    let channel = data.logging.staff.channel;
+    let channel = _.clone(data.logging.staff.channel);
     let closed = false;
     do {
         const channelMenu = new ActionRowBuilder<ChannelSelectMenuBuilder>().addComponents(
@@ -45,7 +47,7 @@
                 .setLabel("Save")
                 .setStyle(ButtonStyle.Success)
                 .setEmoji(getEmojiByName("ICONS.SAVE", "id") as Discord.APIMessageComponentEmoji)
-                .setDisabled(channel === data.logging.staff.channel)
+                .setDisabled(_.isEqual(channel, data.logging.staff.channel))
         );
 
         const embed = new EmojiEmbed()
@@ -62,12 +64,12 @@
             components: [channelMenu, buttons]
         });
 
-        let i: Discord.ButtonInteraction | Discord.SelectMenuInteraction;
+        let i: Discord.ButtonInteraction | Discord.ChannelSelectMenuInteraction;
         try {
-            i = (await interaction.channel!.awaitMessageComponent({
+            i = (await interaction.channel!.awaitMessageComponent<ComponentType.Button | ComponentType.ChannelSelect>({
                 filter: (i: Discord.Interaction) => i.user.id === interaction.user.id,
                 time: 300000
-            })) as Discord.ButtonInteraction | Discord.SelectMenuInteraction;
+            }))
         } catch (e) {
             closed = true;
             continue;
@@ -81,7 +83,7 @@
                 }
                 case "save": {
                     await client.database.guilds.write(interaction.guild!.id, {
-                        "logging.warnings.channel": channel
+                        "logging.staff.channel": channel
                     });
                     data = await client.database.guilds.read(interaction.guild!.id);
                     await client.memory.forceUpdate(interaction.guild!.id);
diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts
index 537a483..fe11ee1 100644
--- a/src/events/guildMemberUpdate.ts
+++ b/src/events/guildMemberUpdate.ts
@@ -93,7 +93,7 @@
     if (!auditLog) return;
     if (auditLog.executor!.id === client.user!.id) return;
     if (before.nickname !== after.nickname) {
-        await doMemberChecks(after, after.guild);
+        await doMemberChecks(after);
         await client.database.history.create(
             "nickname",
             after.guild.id,
@@ -125,6 +125,7 @@
         };
         await log(data);
     }
+    if (before.displayAvatarURL !== after.displayAvatarURL) await doMemberChecks(after);
     if (
         (before.communicationDisabledUntilTimestamp ?? 0) < Date.now() &&
         new Date(after.communicationDisabledUntil ?? 0).getTime() > Date.now()
diff --git a/src/events/memberJoin.ts b/src/events/memberJoin.ts
index b01eb60..55f9ba8 100644
--- a/src/events/memberJoin.ts
+++ b/src/events/memberJoin.ts
@@ -9,7 +9,7 @@
 export async function callback(client: NucleusClient, member: GuildMember) {
     await welcome(member);
     await statsChannelAdd(member.user, member.guild);
-    await doMemberChecks(member, member.guild);
+    await doMemberChecks(member);
     const { log, isLogging, NucleusColors, entry, renderUser, renderDelta } = client.logger;
     if (!(await isLogging(member.guild.id, "guildMemberUpdate"))) return;
     await client.database.history.create("join", member.guild.id, member.user, null, null);
diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts
index 5369bf4..38c7674 100644
--- a/src/events/messageCreate.ts
+++ b/src/events/messageCreate.ts
@@ -105,42 +105,42 @@
         for (const element of fileNames.files) {
             const url = element.url ? element.url : element.local;
             if (
-                /\.(j(pe?g|fif)|a?png|gifv?|w(eb[mp]|av)|mp([34]|eg-\d)|ogg|avi|h\.26(4|5)|cda)$/.test(
+                /\.(jpg|jpeg|png|apng|gif|gifv|webm|webp|mp4|wav|mp3|ogg|jfif|mpeg-\d|avi|h\.264|h\.265)$/.test(
                     url.toLowerCase()
                 )
             ) {
-                // jpg|jpeg|png|apng|gif|gifv|webm|webp|mp4|wav|mp3|ogg|jfif|MPEG-#|avi|h.264|h.265
+                // j(pe?g|fif)|a?png|gifv?|w(eb[mp]|av)|mp([34]|eg-\d)|ogg|avi|h\.26(4|5)
+                // ^no
                 if (
                     config.filters.images.NSFW &&
-                    !(message.channel instanceof ThreadChannel ? message.channel.parent?.nsfw : message.channel.nsfw)
+                    !(message.channel instanceof ThreadChannel ? message.channel.parent?.nsfw : message.channel.nsfw) &&
+                    (await NSFWCheck(element))
                 ) {
-                    if (await NSFWCheck(url)) {
-                        messageException(message.guild.id, message.channel.id, message.id);
-                        await message.delete();
-                        const data = {
-                            meta: {
-                                type: "messageDelete",
-                                displayName: "Message Deleted",
-                                calculateType: "autoModeratorDeleted",
-                                color: NucleusColors.red,
-                                emoji: "MESSAGE.DELETE",
-                                timestamp: Date.now()
-                            },
-                            separate: {
-                                start:
-                                    filter +
-                                    " Image detected as NSFW\n\n" +
-                                    (content
-                                        ? `**Message:**\n\`\`\`${content}\`\`\``
-                                        : "**Message:** *Message had no content*")
-                            },
-                            list: list,
-                            hidden: {
-                                guild: message.channel.guild.id
-                            }
-                        };
-                        return log(data);
-                    }
+                    messageException(message.guild.id, message.channel.id, message.id);
+                    await message.delete();
+                    const data = {
+                        meta: {
+                            type: "messageDelete",
+                            displayName: "Message Deleted",
+                            calculateType: "autoModeratorDeleted",
+                            color: NucleusColors.red,
+                            emoji: "MESSAGE.DELETE",
+                            timestamp: Date.now()
+                        },
+                        separate: {
+                            start:
+                                filter +
+                                " Image detected as NSFW\n\n" +
+                                (content
+                                    ? `**Message:**\n\`\`\`${content}\`\`\``
+                                    : "**Message:** *Message had no content*")
+                        },
+                        list: list,
+                        hidden: {
+                            guild: message.channel.guild.id
+                        }
+                    };
+                    return log(data);
                 }
                 if (config.filters.wordFilter.enabled) {
                     const text = await TestImage(url);
@@ -209,34 +209,30 @@
                     }
                 }
             }
-            if (config.filters.malware) {
-                if (!(await MalwareCheck(url))) {
-                    messageException(message.guild.id, message.channel.id, message.id);
-                    await message.delete();
-                    const data = {
-                        meta: {
-                            type: "messageDelete",
-                            displayName: "Message Deleted",
-                            calculateType: "autoModeratorDeleted",
-                            color: NucleusColors.red,
-                            emoji: "MESSAGE.DELETE",
-                            timestamp: Date.now()
-                        },
-                        separate: {
-                            start:
-                                filter +
-                                " File detected as malware\n\n" +
-                                (content
-                                    ? `**Message:**\n\`\`\`${content}\`\`\``
-                                    : "**Message:** *Message had no content*")
-                        },
-                        list: list,
-                        hidden: {
-                            guild: message.channel.guild.id
-                        }
-                    };
-                    return log(data);
-                }
+            if (config.filters.malware && (await MalwareCheck(url))) {
+                messageException(message.guild.id, message.channel.id, message.id);
+                await message.delete();
+                const data = {
+                    meta: {
+                        type: "messageDelete",
+                        displayName: "Message Deleted",
+                        calculateType: "autoModeratorDeleted",
+                        color: NucleusColors.red,
+                        emoji: "MESSAGE.DELETE",
+                        timestamp: Date.now()
+                    },
+                    separate: {
+                        start:
+                            filter +
+                            " File detected as malware\n\n" +
+                            (content ? `**Message:**\n\`\`\`${content}\`\`\`` : "**Message:** *Message had no content*")
+                    },
+                    list: list,
+                    hidden: {
+                        guild: message.channel.guild.id
+                    }
+                };
+                return log(data);
             }
         }
     }
diff --git a/src/reflex/scanners.ts b/src/reflex/scanners.ts
index cce8b84..acd3b41 100644
--- a/src/reflex/scanners.ts
+++ b/src/reflex/scanners.ts
@@ -12,13 +12,16 @@
 import getEmojiByName from "../utils/getEmojiByName.js";
 import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
 import config from "../config/main.js";
+import GIFEncoder from "gifencoder";
+import gm_var from 'gm';
+const gm = gm_var.subClass({ imageMagick: '7+' });
 
 interface NSFWSchema {
     nsfw: boolean;
     errored?: boolean;
 }
 interface MalwareSchema {
-    safe: boolean;
+    malware: boolean;
     errored?: boolean;
 }
 
@@ -29,15 +32,28 @@
     }
 });
 
-export async function testNSFW(link: string): Promise<NSFWSchema> {
-    const [fileStream, hash] = await streamAttachment(link);
+export async function testNSFW(attachment: {
+    url: string;
+    local: string;
+    height: number | null;
+    width: number | null;
+}): Promise<NSFWSchema> {
+    const [fileStream, hash] = await streamAttachment(attachment.url);
     const alreadyHaveCheck = await client.database.scanCache.read(hash);
-    if (alreadyHaveCheck?.nsfw !== undefined) return { nsfw: alreadyHaveCheck.nsfw };
+    if (alreadyHaveCheck && ("nsfw" in alreadyHaveCheck!)) {
+        return { nsfw: alreadyHaveCheck.nsfw }
+    };
 
-    const image = tf.tensor3d(new Uint8Array(fileStream));
+    const image = gm(fileStream).command('convert').in('-')
 
-    const predictions = (await nsfw_model.classify(image, 1))[0]!;
-    image.dispose();
+    const encoder = new GIFEncoder(attachment.width ?? 1024, attachment.height ?? 1024);
+
+
+    // const array = new Uint8Array(fileStream);
+    const img = tf.node.decodeImage(array) as tf.Tensor3D;
+
+    const predictions = (await nsfw_model.classify(img, 1))[0]!;
+    console.log(2, predictions);
 
     const nsfw = predictions.className === "Hentai" || predictions.className === "Porn";
     await client.database.scanCache.write(hash, "nsfw", nsfw);
@@ -48,51 +64,42 @@
 export async function testMalware(link: string): Promise<MalwareSchema> {
     const [fileName, hash] = await saveAttachment(link);
     const alreadyHaveCheck = await client.database.scanCache.read(hash);
-    if (alreadyHaveCheck?.malware !== undefined) return { safe: alreadyHaveCheck.malware };
+    if (alreadyHaveCheck?.malware !== undefined) return { malware: alreadyHaveCheck.malware };
     let malware;
     try {
         malware = (await clamscanner.scanFile(fileName)).isInfected;
     } catch (e) {
-        return { safe: true };
+        return { malware: true };
     }
     await client.database.scanCache.write(hash, "malware", malware);
-    return { safe: !malware };
+    return { malware };
 }
 
 export async function testLink(link: string): Promise<{ safe: boolean; tags: string[] }> {
     const alreadyHaveCheck = await client.database.scanCache.read(link);
-    if (alreadyHaveCheck?.bad_link !== undefined) return { safe: alreadyHaveCheck.bad_link, tags: alreadyHaveCheck.tags ?? [] };
-    const scanned: { safe?: boolean; tags?: string[] } = await fetch("https://unscan.p.rapidapi.com/link", {
-        method: "POST",
-        headers: {
-            "X-RapidAPI-Key": client.config.rapidApiKey,
-            "X-RapidAPI-Host": "unscan.p.rapidapi.com"
-        },
-        body: `{"link":"${link}"}`
-    })
-        .then((response) => response.json() as Promise<MalwareSchema>)
-        .catch((err) => {
-            console.error(err);
-            return { safe: true, tags: [] };
-        });
-    await client.database.scanCache.write(link, "bad_link", scanned.safe ?? true, scanned.tags ?? []);
-    return {
-        safe: scanned.safe ?? true,
-        tags: scanned.tags ?? []
-    };
+    if (alreadyHaveCheck?.bad_link !== undefined)
+        return { safe: alreadyHaveCheck.bad_link, tags: alreadyHaveCheck.tags ?? [] };
+    return { safe: true, tags: [] };
+    // const scanned: { safe?: boolean; tags?: string[] } = {}
+    // await client.database.scanCache.write(link, "bad_link", scanned.safe ?? true, scanned.tags ?? []);
+    // return {
+    //     safe: scanned.safe ?? true,
+    //     tags: scanned.tags ?? []
+    // };
 }
 
-export async function streamAttachment(link: string): Promise<[ArrayBuffer, string]> {
+export async function streamAttachment(link: string): Promise<[Buffer, string]> {
     const image = await (await fetch(link)).arrayBuffer();
     const enc = new TextDecoder("utf-8");
-    return [image, createHash("sha512").update(enc.decode(image), "base64").digest("base64")];
+    const buf = Buffer.from(image);
+    return [buf, createHash("sha512").update(enc.decode(image), "base64").digest("base64")];
 }
 
 export async function saveAttachment(link: string): Promise<[string, string]> {
     const image = await (await fetch(link)).arrayBuffer();
     const fileName = await generateFileName(link.split("/").pop()!.split(".").pop()!);
     const enc = new TextDecoder("utf-8");
-    writeFileSync(fileName, new DataView(image), "base64");
+    writeFileSync(fileName, new DataView(image));
     return [fileName, createHash("sha512").update(enc.decode(image), "base64").digest("base64")];
 }
 
@@ -147,10 +154,16 @@
     return detectionsTypes as string[];
 }
 
-export async function NSFWCheck(element: string): Promise<boolean> {
+export async function NSFWCheck(element: {
+    url: string;
+    local: string;
+    height: number | null;
+    width: number | null;
+}): Promise<boolean> {
     try {
         return (await testNSFW(element)).nsfw;
-    } catch {
+    } catch (e) {
+        console.log(e)
         return false;
     }
 }
@@ -163,7 +176,7 @@
 
 export async function MalwareCheck(element: string): Promise<boolean> {
     try {
-        return (await testMalware(element)).safe;
+        return (await testMalware(element)).malware;
     } catch {
         return true;
     }
@@ -200,15 +213,20 @@
     return text;
 }
 
-export async function doMemberChecks(member: Discord.GuildMember, guild: Discord.Guild): Promise<void> {
+export async function doMemberChecks(member: Discord.GuildMember): Promise<void> {
     if (member.user.bot) return;
+    console.log("Checking member " + member.user.tag)
+    const guild = member.guild;
     const guildData = await client.database.guilds.read(guild.id);
     if (!guildData.logging.staff.channel) return;
     const [loose, strict] = [guildData.filters.wordFilter.words.loose, guildData.filters.wordFilter.words.strict];
+    console.log(1, loose, strict)
     // Does the username contain filtered words
     const usernameCheck = TestString(member.user.username, loose, strict, guildData.filters.wordFilter.enabled);
+    console.log(2, usernameCheck)
     // Does the nickname contain filtered words
     const nicknameCheck = TestString(member.nickname ?? "", loose, strict, guildData.filters.wordFilter.enabled);
+    console.log(3, nicknameCheck)
     // Does the profile picture contain filtered words
     const avatarTextCheck = TestString(
         (await TestImage(member.user.displayAvatarURL({ forceStatic: true }))) ?? "",
@@ -216,15 +234,19 @@
         strict,
         guildData.filters.wordFilter.enabled
     );
+    console.log(4, avatarTextCheck)
     // Is the profile picture NSFW
+    const avatar = member.displayAvatarURL({ extension: "png", size: 1024, forceStatic: true });
     const avatarCheck =
-        guildData.filters.images.NSFW && (await NSFWCheck(member.user.displayAvatarURL({ forceStatic: true })));
+        guildData.filters.images.NSFW && (await NSFWCheck({url: avatar, local: "", height: 1024, width: 1024}));
+    console.log(5, avatarCheck)
     // Does the username contain an invite
     const inviteCheck = guildData.filters.invite.enabled && /discord\.gg\/[a-zA-Z0-9]+/gi.test(member.user.username);
+    console.log(6, inviteCheck)
     // Does the nickname contain an invite
     const nicknameInviteCheck =
         guildData.filters.invite.enabled && /discord\.gg\/[a-zA-Z0-9]+/gi.test(member.nickname ?? "");
-
+    console.log(7, nicknameInviteCheck)
     if (
         usernameCheck !== null ||
         nicknameCheck !== null ||
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index a417f6f..59befe6 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -291,10 +291,13 @@
                     cancelled = true;
                     continue;
                 }
-                if (out === null || out.isButton()) {
+                if (out === null) {
                     cancelled = true;
                     continue;
                 }
+                if (out.isButton()) {
+                    continue;
+                }
                 if (out instanceof ModalSubmitInteraction) {
                     newReason = out.fields.getTextInputValue("reason");
                     continue;
@@ -339,7 +342,11 @@
                     cancelled = true;
                     continue;
                 }
-                if (out === null || out.isButton()) {
+                if (out === null) {
+                    cancelled = true;
+                    continue;
+                }
+                if (out.isButton()) {
                     continue;
                 }
                 if (out instanceof ModalSubmitInteraction) {