1
+ const fs = require ( 'fs' )
2
+ const request = require ( 'request' ) ;
3
+ const fetch = require ( 'node-fetch' )
4
+ const cors = require ( 'cors' ) ( { origin : true } )
5
+ const cheerio = require ( 'cheerio' )
6
+ const vision = require ( '@google-cloud/vision' )
7
+ const ocrClient = new vision . ImageAnnotatorClient ( )
8
+ const Bottleneck = require ( "bottleneck" )
9
+ const { createWorker } = require ( 'tesseract.js' )
10
+ const worker = createWorker ( )
11
+ const limiter = new Bottleneck ( {
12
+ minTime : 1000 ,
13
+ maxConcurrent : 2
14
+ } )
15
+
16
+ module . exports = {
17
+ parseCharacters : async function parseCharacters ( players , Discord , message , client ) {
18
+ return new Promise ( async ( resolve , reject ) => {
19
+ var config = JSON . parse ( fs . readFileSync ( 'config.json' ) )
20
+ var statusDescription = 'Parse status: Retrieving players from RealmEye' ;
21
+ var statusEmbed = new Discord . MessageEmbed ( )
22
+ . setColor ( "#41f230" )
23
+ . setAuthor ( `${ message . member . displayName } \'s Parse ` , message . author . displayAvatarURL ( ) )
24
+ . setDescription ( `\`\`\`\n${ statusDescription } \n\`\`\`` )
25
+ . setTimestamp ( ) ;
26
+ statusMessage = await message . channel . send ( statusEmbed ) ;
27
+ try {
28
+ let classStats = {
29
+ "TEMPLATE" : [ "HP" , "MP" , "ATK" , "DEF" , "SPD" , "VIT" , "WIS" , "DEX" ] ,
30
+ "Rogue" : [ 720 , 252 , 50 , 25 , 75 , 40 , 50 , 75 ] ,
31
+ "Archer" : [ 700 , 252 , 75 , 25 , 50 , 40 , 50 , 50 ] ,
32
+ "Wizard" : [ 670 , 385 , 75 , 25 , 50 , 40 , 60 , 75 ] ,
33
+ "Priest" : [ 670 , 385 , 50 , 25 , 55 , 40 , 75 , 55 ] ,
34
+ "Warrior" : [ 770 , 252 , 75 , 25 , 50 , 75 , 50 , 50 ] ,
35
+ "Knight" : [ 770 , 252 , 50 , 40 , 50 , 75 , 50 , 50 ] ,
36
+ "Paladin" : [ 770 , 252 , 50 , 30 , 55 , 40 , 75 , 45 ] ,
37
+ "Assassin" : [ 720 , 252 , 60 , 25 , 75 , 40 , 60 , 75 ] ,
38
+ "Necromancer" : [ 670 , 385 , 75 , 25 , 50 , 30 , 75 , 60 ] ,
39
+ "Huntress" : [ 700 , 252 , 75 , 25 , 50 , 40 , 50 , 50 ] ,
40
+ "Mystic" : [ 670 , 385 , 60 , 25 , 60 , 40 , 75 , 55 ] ,
41
+ "Trickster" : [ 720 , 252 , 65 , 25 , 75 , 40 , 60 , 75 ] ,
42
+ "Sorcerer" : [ 670 , 385 , 70 , 25 , 60 , 75 , 60 , 60 ] ,
43
+ "Ninja" : [ 720 , 252 , 70 , 25 , 60 , 60 , 70 , 70 ] ,
44
+ "Samurai" : [ 720 , 252 , 75 , 30 , 55 , 60 , 60 , 50 ] ,
45
+ "Bard" : [ 670 , 385 , 55 , 25 , 55 , 45 , 75 , 70 ]
46
+ }
47
+
48
+ var bannedItems = client . guilds . cache . get ( config . parsesettings . bannedItemsServer ) . emojis . cache . map ( e => e . name . toLowerCase ( ) ) ;
49
+
50
+ var invalidUsers = [ ] ;
51
+ var validUsers = [ ] ;
52
+ var invalidUsers = [ ] ;
53
+ var validUsers = [ ] ;
54
+ var playersNotMeetingReqs = [ ] ;
55
+ var recieveRequests = 0 ;
56
+
57
+ var timeStarted = Date . now ( ) ;
58
+
59
+ var options = {
60
+ proxy :
'http://Nashex:[email protected] :31280' ,
61
+ headers : {
62
+ 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
63
+ }
64
+ } ;
65
+
66
+ returnEmbed = new Discord . MessageEmbed ( )
67
+ . setDescription ( `\`\`\`\nParse Status: Parsing Characters...\n\`\`\`` )
68
+ . setAuthor ( "The Following People Do Not Meet Requirements" )
69
+ . setColor ( "#41f230" )
70
+ . setTimestamp ( ) ;
71
+
72
+ const getPlayers = async ( ) => {
73
+ for ( var i in players ) {
74
+ try {
75
+ var url = `https://www.realmeye.com/player/${ players [ i ] } ` ;
76
+ await request ( url , options , async ( error , response , html ) => {
77
+ recieveRequests ++ ;
78
+ try {
79
+ if ( ! error && response . statusCode == 200 ) {
80
+ var $ = cheerio . load ( html ) ;
81
+ //const siteBody = $('body');
82
+ //console.log(siteBody.text());
83
+ let columns = [ ]
84
+ $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 0 ) . find ( 'th' ) . each ( async x => {
85
+ columns . push ( $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 0 ) . find ( 'th' ) . eq ( x ) . text ( ) )
86
+ } )
87
+ if ( columns . length != 10 ) {
88
+ invalidUsers . push ( players [ i ] )
89
+ } else {
90
+ var characterObject = { "Name" : $ ( 'title' ) . text ( ) . split ( ': ' ) [ 1 ] . split ( ' ' ) [ 0 ] }
91
+ columns . slice ( 2 )
92
+ $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 1 ) . find ( 'td' ) . each ( async x => {
93
+ if ( x < 8 ) {
94
+ characterObject [ columns [ x ] ] = $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 1 ) . find ( 'td' ) . eq ( x ) . text ( )
95
+ } else if ( x == 8 ) {
96
+ let itemArray = [ ]
97
+ $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 1 ) . find ( 'td' ) . eq ( x ) . find ( ".item" ) . each ( async item => {
98
+ let equip = $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 1 ) . find ( 'td' ) . eq ( x ) . find ( ".item" ) . eq ( item ) . prop ( "title" )
99
+ if ( item != 4 ) {
100
+ equip = equip . split ( " " )
101
+ let tier = equip . pop ( )
102
+ equip = equip . join ( "" )
103
+ equip = equip . replace ( / [ ^ a - z 0 - 9 ] / gi, "" )
104
+ equip = client . emojis . cache . find ( e => e . name . toLowerCase ( ) . includes ( equip . toLowerCase ( ) ) )
105
+ if ( equip ) {
106
+ itemArray . push ( [ `<:${ equip . name } :${ equip . id } >` , tier ] )
107
+
108
+ } else {
109
+ itemArray . push ( [ `🚫` , tier ] )
110
+ }
111
+ } else {
112
+ itemArray . push ( [ `<:Backpack:719952565139406928>` , "UT" ] )
113
+ }
114
+
115
+ } )
116
+ characterObject [ columns [ x ] ] = itemArray
117
+ } else if ( x == 9 ) {
118
+ try {
119
+ let totalStats = JSON . parse ( $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 1 ) . find ( 'td' ) . eq ( x ) . find ( ".player-stats" ) . prop ( "data-stats" ) )
120
+ let statBonuses = JSON . parse ( $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 1 ) . find ( 'td' ) . eq ( x ) . find ( ".player-stats" ) . prop ( "data-bonuses" ) )
121
+ let baseStats = [ ]
122
+ for ( var i in totalStats ) {
123
+ baseStats . push ( totalStats [ i ] - statBonuses [ i ] )
124
+ }
125
+ characterObject [ columns [ x ] ] = baseStats
126
+ characterObject . Maxed = $ ( 'table[class="table table-striped tablesorter"]' ) . find ( "tr" ) . eq ( 1 ) . find ( 'td' ) . eq ( x ) . text ( )
127
+ } catch ( e ) { }
128
+
129
+ }
130
+ } )
131
+ validUsers . push ( characterObject )
132
+ var valid = checkRequirements ( characterObject ) ;
133
+
134
+ if ( valid == undefined ) {
135
+ invalidUsers . push ( characterObject . Name )
136
+ } else {
137
+ if ( valid [ 0 ] != true ) {
138
+ var classEmote = client . emojis . cache . find ( e => e . name . toLowerCase ( ) == characterObject . Class . toLowerCase ( ) ) . toString ( ) ;
139
+ returnEmbed . setFooter ( `Retrieved in ${ ( Date . now ( ) - timeStarted ) / 1000 } seconds` )
140
+ . addField ( `${ characterObject . Name } ${ classEmote } ` , `[RealmEye](https://www.realmeye.com/player/${ characterObject . Name } ) | **Level:** \`${ characterObject . L } \` | **Fame:** \`${ characterObject . Fame } \` ${ characterObject . Equipment . map ( a => a [ 0 ] ) . join ( "" ) } | **Maxed:** \`${ characterObject . Maxed } \`\n\`/lock ${ characterObject . Name } \`\n ${ valid [ 1 ] ? valid [ 1 ] . join ( "\n" ) : undefined } ` )
141
+ playersNotMeetingReqs . push ( characterObject . Name ) ;
142
+ statusMessage . edit ( returnEmbed ) ;
143
+ }
144
+ if ( recieveRequests >= players . length ) {
145
+ returnEmbed . setDescription ( `\`\`\`\nParse Status: Complete\n\`\`\`` )
146
+ . setFooter ( `Time taken: ${ ( Date . now ( ) - timeStarted ) / 1000 } seconds` )
147
+ if ( playersNotMeetingReqs ) returnEmbed . addField ( "Additional Kick Commands" , `\`\`\`\n/kick ${ playersNotMeetingReqs . join ( " " ) } \n\`\`\`` )
148
+ if ( playersNotMeetingReqs ) returnEmbed . addField ( "Additional Find Command" , `\`\`\`\n${ config . prefix } find ${ playersNotMeetingReqs . join ( " " ) } \n\`\`\`` )
149
+ statusMessage . edit ( returnEmbed ) ;
150
+ resolve ( ) ;
151
+ }
152
+
153
+ }
154
+
155
+ }
156
+ } else {
157
+ //console.log('Something went wrong..')
158
+ }
159
+ } catch ( e ) {
160
+ //console.log(e)
161
+ invalidUsers . push ( characterObject . Name )
162
+ }
163
+ } ) ;
164
+ } catch ( e ) {
165
+ recieveRequests ++ ;
166
+ message . channel . send ( `There was an error fetching ${ players [ i ] } 's Realmeye page: ${ e } ` )
167
+ }
168
+ }
169
+ }
170
+
171
+ await getPlayers ( ) ;
172
+
173
+ let requirements = config . requirements ;
174
+
175
+ if ( invalidUsers . length > 0 ) {
176
+ var unreachedEmbed = new Discord . MessageEmbed ( )
177
+ . setAuthor ( "The Following People Have Unreachable Profiles" )
178
+ . setColor ( "#41f230" )
179
+ . setDescription ( invalidUsers . join ( ", " ) )
180
+ await message . channel . send ( unreachedEmbed )
181
+ }
182
+
183
+ function checkRequirements ( characterObject ) {
184
+ let valid = true
185
+ let reasons = [ ]
186
+ //Check Gear Requirements
187
+ let equipmentTier = characterObject . Equipment . map ( a => a [ 1 ] . replace ( / S T / gi, "-1" ) . replace ( / U T / gi, "-1" ) . replace ( / [ ^ 0 - 9 - \n] / gi, "" ) )
188
+ for ( var i in equipmentTier ) {
189
+ if ( equipmentTier [ i ] . length == 0 ) {
190
+ equipmentTier [ i ] = "None"
191
+ }
192
+ }
193
+
194
+ for ( var i in characterObject . Equipment ) {
195
+ if ( bannedItems . some ( e => e == ( characterObject . Equipment [ i ] [ 0 ] . split ( ":" ) [ 1 ] . toLowerCase ( ) ) ) ) {
196
+ valid = false ;
197
+ reasons . push ( `Item is banned (${ characterObject . Equipment [ i ] [ 0 ] } )` )
198
+ }
199
+ }
200
+
201
+ if ( characterObject . L < parseInt ( requirements . level ) ) {
202
+ valid = false
203
+ reasons . push ( `Player is below level ${ requirements . level } (Lvl ${ characterObject . L } ) ` )
204
+ }
205
+ if ( parseInt ( equipmentTier [ 0 ] ) < parseInt ( requirements . weapon ) && equipmentTier [ 0 ] != "-1" ) {
206
+ valid = false
207
+ reasons . push ( `Weapon is less than T${ requirements . weapon } (T${ equipmentTier [ 0 ] } ) ` )
208
+ }
209
+ if ( parseInt ( equipmentTier [ 1 ] ) < parseInt ( requirements . ability ) && equipmentTier [ 1 ] != "-1" ) {
210
+ valid = false
211
+ reasons . push ( `Ability is less than T${ requirements . ability } (T${ equipmentTier [ 1 ] } ) ` )
212
+ }
213
+ if ( parseInt ( equipmentTier [ 2 ] ) < parseInt ( requirements . armor ) && equipmentTier [ 2 ] != "-1" ) {
214
+ valid = false
215
+ reasons . push ( `Armor is less than T${ requirements . armor } (T${ equipmentTier [ 2 ] } ) ` )
216
+ }
217
+ if ( parseInt ( equipmentTier [ 3 ] ) < parseInt ( requirements . ring ) && equipmentTier [ 3 ] != "-1" ) {
218
+ valid = false
219
+ reasons . push ( `Ring is less than T${ requirements . ring } (T${ equipmentTier [ 3 ] } ) ` )
220
+ }
221
+ //Check Stat Requirements
222
+ let baseStats = characterObject . Stats
223
+ let maxStats = classStats [ characterObject . Class ]
224
+ let keys = Object . keys ( requirements ) . slice ( 4 )
225
+ for ( var i in baseStats ) {
226
+ if ( requirements [ keys [ i ] ] . toLowerCase ( ) == "true" && maxStats [ i ] - baseStats [ i ] > 0 ) {
227
+ valid = false
228
+ reasons . push ( `${ keys [ i ] } is not maxed (${ baseStats [ i ] } /${ maxStats [ i ] } )` )
229
+ }
230
+ }
231
+ return [ valid , reasons ]
232
+ }
233
+ } catch ( e ) {
234
+ reject ( ) ;
235
+ console . log ( e ) ;
236
+ }
237
+
238
+ } ) ;
239
+ }
240
+ }
0 commit comments