Skip to content

Commit 73d93e4

Browse files
authored
Merge pull request #3 from Nashex/master
Improved parsing with namematch + prxy
2 parents 2e62be5 + 749b06e commit 73d93e4

8 files changed

+492
-255
lines changed

commands/parsecharactersv2.js

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
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-z0-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(/ST/gi, "-1").replace(/UT/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

Comments
 (0)