worked on NSFW Image testing
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 ||