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
JavaScript
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;
;