import d2manifest from "@d2api/manifest-node" ; import { WishListRoll } from "./lib/types.js" ; import { toDimWishListRoll } from "./lib/wishlist-file.js" ; import fs from "fs" ; import readline from "readline" ; import { DestinyInventoryItemDefinition } from "bungie-api-ts/destiny2" ; const verboseMain = true ; const placesToLookForValidPerks = [ "randomizedPlugSetHash" , "reusablePlugSetHash" ] ; ( async ( ) => { await d2manifest . load ( ) ; [ "Mercules904" , "PandaPaxxy" , "AyyItsChevy" , "blueberries-dot-gg" , "YeezyGT" , ] . forEach ( ( dirName ) => { fs . readdirSync ( "../" + dirName ) . forEach ( async ( fileName ) => { if ( ! fileName . includes ( ".txt" ) || fileName . includes ( "-clean.txt" ) ) { return ; } verboseMain && console . log ( `\nloading ${ fileName }` ) ; const sourceFileName = "../" + dirName + "/" + fileName ; const fileStream = fs . createReadStream ( sourceFileName ) ; const cleanFileName = sourceFileName . replace ( ".txt" , "-clean.txt" ) ; const cleanFileStream = fs . createWriteStream ( "../" + dirName + "/" + cleanFileName , { flags : "a" , } ) ; const rl = readline . createInterface ( { input : fileStream , crlfDelay : Infinity , } ) ; for await ( const line of rl ) { if ( line . includes ( "dimwishlist:" ) ) { const dimWishListRoll = toDimWishListRoll ( line ) ; if ( isValidWishListRoll ( dimWishListRoll ) ) { cleanFileStream . write ( line + "\n" ) ; } } else { cleanFileStream . write ( line + "\n" ) ; } } fileStream . destroy ( ) ; cleanFileStream . end ( ) ; fs . rename ( cleanFileName , sourceFileName , ( err ) => { if ( err ) throw err ; } ) ; } ) ; } ) ; } ) ( ) ; function isValidWishListRoll ( roll , verbose = false ) { if ( ! roll ) { return false ; } const perksOnThisRoll = [ ... roll . recommendedPerks ] ; const rollItem = getItem ( roll . itemHash ) ; if ( ! rollItem ) { return false ; } const itemName = rollItem . displayProperties . name ; if ( isDummy ( rollItem ) ) { return false ; } const perksThisGunCanActuallyHave = ( rollItem . sockets ?. socketEntries . reduce ( ( acc , se ) => { const hashesInPlugsets = placesToLookForValidPerks . reduce ( ( inneracc , key ) => inneracc . concat ( getPlugSet ( se [ key ] ?? - 99999999 ) ?. reusablePlugItems ?. map ( ( p ) => p . plugItemHash ) ) , [ ] as ( number | undefined ) [ ] ) ; const reusablePlugItemHashes = se . reusablePlugItems . map ( ( pi ) => pi . plugItemHash ) ; return acc . concat ( [ ... hashesInPlugsets , ... reusablePlugItemHashes ] ) ; } , [ ] as ( number | undefined ) [ ] ) . filter ( Boolean ) ?? [ ] ) as number [ ] ; return perksOnThisRoll . every ( ( p ) => perksThisGunCanActuallyHave . includes ( p ) ) ; } function isDummy ( item ) { return item ?. itemCategoryHashes ?. includes ( 3109687656 ) ; } function getItem ( hash ) { return d2manifest . get ( "DestinyInventoryItemDefinition" , hash ) ; } function getPlugSet ( hash ) { return d2manifest . get ( "DestinyPlugSetDefinition" , hash ) ; }