1
- import { APIEmbed , EmbedBuilder , flatten , RESTPostAPIWebhookWithTokenJSONBody } from "discord.js" ;
2
- import { getAutomodRules } from "../api/automod" ;
1
+ import { APIEmbed , EmbedBuilder , RESTPostAPIWebhookWithTokenJSONBody } from "discord.js" ;
2
+ import { getAutomodRules , getBadFiles } from "../api/automod" ;
3
3
import { ISlackMessage , PublishToDiscord , PublishToSlack } from "../api/moderationWebhooks" ;
4
4
import { IMod } from "../api/queries/v2" ;
5
5
import { IModResults } from "../api/queries/v2-latestmods" ;
6
6
import { getUserByNexusModsId } from "../api/users" ;
7
7
import { logMessage } from "../api/util" ;
8
8
import { ClientExt } from "../types/DiscordTypes" ;
9
- import { IAutomodRule } from "../types/util" ;
9
+ import { IAutomodRule , IBadFileRule } from "../types/util" ;
10
10
import { tall } from 'tall' ;
11
11
import { DiscordBotUser , DummyNexusModsUser } from "../api/DiscordBotUser" ;
12
12
import axios , { AxiosResponse } from "axios" ;
@@ -21,10 +21,13 @@ interface IModWithFlags {
21
21
}
22
22
}
23
23
24
+
25
+
24
26
export class AutoModManager {
25
27
private static instance : AutoModManager ;
26
28
27
29
private AutoModRules : IAutomodRule [ ] = [ ] ;
30
+ private BadFiles : IBadFileRule [ ] = [ ] ;
28
31
private client : ClientExt ;
29
32
private updateTimer : NodeJS . Timeout ;
30
33
private lastCheck : Date = new Date ( new Date ( ) . valueOf ( ) - ( 60000 * 10 ) )
@@ -71,7 +74,8 @@ export class AutoModManager {
71
74
72
75
private async getRules ( ) {
73
76
try {
74
- this . AutoModRules = await getAutomodRules ( )
77
+ this . AutoModRules = await getAutomodRules ( ) ;
78
+ this . BadFiles = await getBadFiles ( ) ;
75
79
}
76
80
catch ( err ) {
77
81
logMessage ( "Error getting automod rules" , err , true )
@@ -105,7 +109,7 @@ export class AutoModManager {
105
109
106
110
let results : IModWithFlags [ ] = [ ]
107
111
for ( const mod of modsToCheck ) {
108
- results . push ( await analyseMod ( mod , this . AutoModRules , user ) )
112
+ results . push ( await analyseMod ( mod , this . AutoModRules , this . BadFiles , user ) )
109
113
}
110
114
this . addToLastReports ( results ) ;
111
115
// const concerns = results.filter(m => (m.flags.high.length) !== 0);
@@ -139,7 +143,7 @@ export class AutoModManager {
139
143
const mod = modInfo [ 0 ] ;
140
144
if ( ! mod ) throw new Error ( 'Mod not found' )
141
145
logMessage ( 'Checking specific mod' , { name : mod . name , game : mod . game . name } ) ;
142
- const analysis = await analyseMod ( mod , this . AutoModRules , user ) ;
146
+ const analysis = await analyseMod ( mod , this . AutoModRules , this . BadFiles , user ) ;
143
147
if ( analysis . flags . high . length ) {
144
148
await PublishToDiscord ( flagsToDiscordEmbeds ( [ analysis ] ) )
145
149
await PublishToSlack ( flagsToSlackMessage ( [ analysis ] ) )
@@ -252,7 +256,7 @@ function flagsToDiscordEmbeds(data: IModWithFlags[]): RESTPostAPIWebhookWithToke
252
256
}
253
257
}
254
258
255
- async function analyseMod ( mod : Partial < IMod > , rules : IAutomodRule [ ] , user : DiscordBotUser ) : Promise < IModWithFlags > {
259
+ async function analyseMod ( mod : Partial < IMod > , rules : IAutomodRule [ ] , badFiles : IBadFileRule [ ] , user : DiscordBotUser ) : Promise < IModWithFlags > {
256
260
let flags : { high : string [ ] , low : string [ ] } = { high : [ ] , low : [ ] } ;
257
261
const now = new Date ( )
258
262
const anHourAgo = new Date ( now . valueOf ( ) - ( 60000 * 60 ) )
@@ -269,7 +273,7 @@ async function analyseMod(mod: Partial<IMod>, rules: IAutomodRule[], user: Disco
269
273
// Check the content preview for first mod uploads
270
274
if ( mod . uploader ! . modCount <= 1 ) {
271
275
try {
272
- const previewCheck = await checkFilePreview ( mod , user )
276
+ const previewCheck = await checkFilePreview ( mod , user , badFiles )
273
277
if ( previewCheck . flags . high . length ) flags . high . push ( ...previewCheck . flags . high )
274
278
if ( previewCheck . flags . low . length ) flags . low . push ( ...previewCheck . flags . low )
275
279
}
@@ -356,7 +360,7 @@ const nonPlayableExtensions: string[] = [
356
360
"rtf" , "tex" , "docx" , "odt" , "pdf" , "url"
357
361
] ;
358
362
359
- async function checkFilePreview ( mod : Partial < IMod > , user : DiscordBotUser ) : Promise < IModWithFlags > {
363
+ async function checkFilePreview ( mod : Partial < IMod > , user : DiscordBotUser , badFiles : IBadFileRule [ ] ) : Promise < IModWithFlags > {
360
364
const flags : { high : string [ ] , low : string [ ] } = { high : [ ] , low : [ ] } ;
361
365
const modFiles = await user . NexusMods . API . v1 . ModFiles ( mod . game ! . domainName ! , mod . modId ! ) ;
362
366
const latestFile = modFiles . files . sort ( ( a , b ) => a . uploaded_timestamp > b . uploaded_timestamp ? 1 : - 1 ) [ 0 ] ;
@@ -375,6 +379,11 @@ async function checkFilePreview(mod: Partial<IMod>, user: DiscordBotUser): Promi
375
379
else {
376
380
const allFiles : string [ ] = flattenDirectory ( request . data ) ;
377
381
382
+ // Check known bad files
383
+ const fileFlags = checkKnownBadFiles ( allFiles , badFiles ) ;
384
+ if ( fileFlags . high ) flags . high . push ( ...fileFlags . high )
385
+ if ( fileFlags . low ) flags . low . push ( ...fileFlags . low )
386
+
378
387
// Check if it's exclusively non-playable files
379
388
const playableFiles = allFiles . filter ( file => {
380
389
const extension : string | undefined = file . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
@@ -406,3 +415,17 @@ function flattenDirectory(input: IPreviewDirectory): string[] {
406
415
}
407
416
return files ;
408
417
}
418
+
419
+ function checkKnownBadFiles ( flattenedFiles : string [ ] , badFiles : IBadFileRule [ ] ) : { low : string [ ] , high : string [ ] } {
420
+ const flags = { low : new Array < string > ( ) , high : new Array < string > ( ) } ;
421
+
422
+ for ( const badFileRule of badFiles ) {
423
+ let result = null ;
424
+ if ( badFileRule . funcName === 'match' ) result = flattenedFiles . find ( f => f . toLowerCase ( ) . match ( badFileRule . test ) !== null ) ;
425
+ else result = flattenedFiles . find ( f => f . toLowerCase ( ) [ badFileRule . funcName ] ( badFileRule . test ) )
426
+ // If we found something!
427
+ if ( result ) flags [ badFileRule . type ] . push ( `${ badFileRule . flagMessage } -- Rule: ${ badFileRule . test } , Func: ${ badFileRule . funcName } ` ) ;
428
+ }
429
+
430
+ return flags ;
431
+ }
0 commit comments