UNPKG

discord-alt-detector

Version:

A small library for discord.js to detect the suspiciousness of level of a user.

276 lines (275 loc) 12 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AltDetector = void 0; const discord = __importStar(require("discord.js")); /**Discord Alt Detector. Use `AltDetector.check(member)` to check a server member! */ class AltDetector { settings; constructor(settings) { this.settings = Object.assign({ ageWeight: 1, statusWeight: 1, activityWeight: 1, usernameWordsWeight: 1, usernameSymbolsWeight: 1, displaynameWordsWeight: 1, displaynameCapsWeight: 1, displaynameSymbolsWeight: 1, flagsWeight: 1, boosterWeight: 1, pfpWeight: 1, bannerWeight: 1, customWeight: 1 }, (settings ?? {})); } check(member, custom) { if (!(member instanceof discord.GuildMember)) throw new Error("member parameter isn't a valid GuildMember!"); const user = member.user; //The higher the score, the better //The lower the score, the more suspicious const score = { total: 0, categories: { age: 0, status: 0, activity: 0, usernameWords: 0, usernameSymbols: 0, displaynameWords: 0, displaynameSymbols: 0, displaynameCaps: 0, flags: 0, booster: 0, pfp: 0, banner: 0, custom: 0 } }; //check for account age // 3 days or less => -6 // 1 week or less => -4 // 1 month or less => -2 // 1 year or less => 0 // 2 years or less => +1 // 3 years or less => +2 // 3 years or more => +4 const ageMs = new Date().getTime() - user.createdAt.getTime(); const ageDays = Math.round((((ageMs / 1000) / 60) / 60) / 24); if (ageDays <= 3) score.categories.age = score.categories.age - 6; else if (ageDays <= 7) score.categories.age = score.categories.age - 4; else if (ageDays <= 30) score.categories.age = score.categories.age - 2; else if (ageDays <= 365) score.categories.age = score.categories.age + 0; else if (ageDays <= 2 * 365) score.categories.age = score.categories.age + 1; else if (ageDays <= 3 * 365) score.categories.age = score.categories.age + 2; else if (ageDays > 3 * 365) score.categories.age = score.categories.age + 4; //check for status (presence intent required) // offline => -1 // online => +1 // idle/dnd => +2 if (member.presence) { if (member.presence.status == "offline") score.categories.status = score.categories.status - 1; else if (member.presence.status == "invisible") score.categories.status = score.categories.status + 0; else if (member.presence.status == "online") score.categories.status = score.categories.status + 1; else if (member.presence.status == "idle") score.categories.status = score.categories.status + 2; else if (member.presence.status == "dnd") score.categories.status = score.categories.status + 2; } //check for activity // no activity => -1 // activity => +3 if (member.presence) { if (member.presence.activities.length == 0) score.categories.activity = score.categories.activity - 1; else score.categories.activity = score.categories.activity + 3; } //check for username // for every bad word => -2 [money, sell, scam, nitro, nitr0, alt, boost, discord, disc0rd, shop, hot, teen, nsfw, ...] // when no bad words => +1 // for every ending number => -1 // for every ending dot/underscore => -2 const usernameWordRegex = /((n(?:i|l)tr(?:o|0)?)|mone?y|v?buc?ks?|acc?ounts?|sale|free|disc(?:o|0)r?d|boo?st|shop|hot|teens?|nsfw|alt|scam|sell)\b/gi; while (true) { //test until all parts are tested const result = usernameWordRegex.exec(user.username); if (!result) { score.categories.usernameWords = score.categories.usernameWords + 1; break; } else score.categories.usernameWords = score.categories.usernameWords - 2; } const usernameEndRegex = /[0-9_\-\.]+$/i; const usernameEndResult = usernameEndRegex.exec(user.username); if (usernameEndResult) score.categories.usernameSymbols = score.categories.usernameSymbols - usernameEndResult[0].length; //check for display name // no display name => -2 // special symbols => -1 [!, ?, (), [], <3, _, -, ...] // capital letter => +1 // for every bad word => -2 [money, sell, scam, nitro, nitr0, alt, boost, discord, disc0rd, shop, hot, teen, nsfw, ...] // when no bad words => +1 if (user.displayName == user.username) score.categories.displaynameWords = score.categories.displaynameWords - 2; const displaynameCapsRegex = /[A-Z]/g; while (true) { //test until all parts are tested const result = displaynameCapsRegex.exec(user.displayName); if (result) { score.categories.displaynameCaps = score.categories.displaynameCaps + 1; } else break; } const displaynameSpecialRegex = /[!?()\[\]{}"'&$*^%+=/:;,<>@#]/g; while (true) { //test until all parts are tested const result = displaynameSpecialRegex.exec(user.displayName); if (result) { score.categories.displaynameSymbols = score.categories.displaynameSymbols - 1; } else break; } const displaynameWordRegex = /((n(?:i|l)tr(?:o|0)?)|mone?y|v?buc?ks?|acc?ounts?|sale|free|disc(?:o|0)r?d|boo?st|shop|hot|teens?|nsfw|alt|scam|sell)\b/gi; while (true) { //test until all parts are tested const result = displaynameWordRegex.exec(user.displayName); if (!result) { score.categories.displaynameWords = score.categories.displaynameWords + 1; break; } else score.categories.displaynameWords = score.categories.displaynameWords - 2; } //user flags // staff/employe => +10 // bughunter => +7 // certified moderator => +6 // verified developer => +6 // partner => +6 // early supporter => +6 // active developer => +3 // hypesquad => +2 // quarantined => -7 // spammer => -7 if (user.flags) { if (user.flags.has("Staff")) score.categories.flags = score.categories.flags + 10; if (user.flags.has("BugHunterLevel1")) score.categories.flags = score.categories.flags + 7; if (user.flags.has("BugHunterLevel2")) score.categories.flags = score.categories.flags + 7; if (user.flags.has("CertifiedModerator")) score.categories.flags = score.categories.flags + 6; if (user.flags.has("VerifiedDeveloper")) score.categories.flags = score.categories.flags + 6; if (user.flags.has("Partner")) score.categories.flags = score.categories.flags + 6; if (user.flags.has("PremiumEarlySupporter")) score.categories.flags = score.categories.flags + 6; if (user.flags.has("ActiveDeveloper")) score.categories.flags = score.categories.flags + 3; if (user.flags.has("Hypesquad")) score.categories.flags = score.categories.flags + 2; if (user.flags.has("Quarantined")) score.categories.flags = score.categories.flags - 7; if (user.flags.has("Spammer")) score.categories.flags = score.categories.flags - 7; } //other // member.premiumSince => +2 [server booster when it exists] if (member.premiumSince) score.categories.booster = score.categories.booster + 2; //check pfp // default => -3 [one of the colors] // normal => +1 // animated => +3 if (!user.avatar) score.categories.pfp = score.categories.pfp - 2; else if (user.displayAvatarURL().endsWith(".gif")) score.categories.pfp = score.categories.pfp + 2; else score.categories.pfp = score.categories.pfp + 1; //check pfp banner // default => 0 // image/gif => +2 if (user.banner || user.bannerURL()) score.categories.banner = score.categories.banner + 1; if (custom) score.categories.custom = score.categories.custom + custom(member, user); //multiply categories by weight const c = score.categories; c.age *= this.settings.ageWeight; c.status *= this.settings.statusWeight; c.activity *= this.settings.activityWeight; c.usernameWords *= this.settings.usernameWordsWeight; c.usernameSymbols *= this.settings.usernameSymbolsWeight; c.displaynameWords *= this.settings.displaynameWordsWeight; c.displaynameCaps *= this.settings.displaynameCapsWeight; c.displaynameSymbols *= this.settings.displaynameSymbolsWeight; c.flags *= this.settings.flagsWeight; c.booster *= this.settings.boosterWeight; c.pfp *= this.settings.pfpWeight; c.banner *= this.settings.bannerWeight; c.custom *= this.settings.customWeight; //get total score.total = c.age + c.status + c.activity + c.usernameWords + c.usernameSymbols + c.displaynameWords + c.displaynameSymbols + c.displaynameCaps + c.flags + c.booster + c.pfp + c.banner + c.custom; return score; } /**Get the level of trust of a user. (ONLY APPLIES WHEN NO WEIGHTS USED!!!) */ getCategory(score) { var category = "normal"; if (score.total > 10) category = "highly-trusted"; else if (score.total > 6) category = "trusted"; else if (score.total > 4) category = "normal"; else if (score.total > 1) category = "newbie"; else if (score.total > -1) category = "suspicious"; else if (score.total > -3) category = "highly-suspicious"; else if (score.total <= -3) category = "mega-suspicious"; return category; } } exports.AltDetector = AltDetector;