· 4 years ago · Apr 20, 2021, 02:28 PM
1const request = require('request');
2//class for our members, each 'member' is a unique person, ie you, me, eitan, peony.
3let Member = class {
4 //when you call 'new Member' it automagically alls the constructor and requires 2 parameters, in this case
5 //its the _name and the _id, obviously this refers to the player name (RiceWilly) and the ID(208002)
6 constructor(_Name, _ID) {
7 this.Name = _Name;
8 this.ID = _ID;
9 }
10
11 //when you call member.GetName() it will return the name we assigned in the constructor
12 GetName() {
13 return this.Name;
14 }
15
16 //same goes for the ID
17 GetID() {
18 return this.ID;
19 }
20}
21
22//i didn't do this
23let totalE = new Array(3000000).fill(0)
24
25//this class stores our data, all of our data, but the only data we care about it a) contributions and b) who the contributions are
26let Data = class {
27 //same as above, when we create the Data class we load it with information via the constructor, ID and Contribution. In this case thought, contribution is actually a class in itself. It can be anything, but im actually loading an array into it.
28 constructor(_ID, _Contribution) {
29 this.ID = _ID;
30 this.Contribution = _Contribution
31 }
32
33 //when we return 'GetContribution', we actually return an array that contains the contribution of strength, speed, defense and dexterity
34 GetContribution() {
35 return this.Contribution;
36 }
37
38 //again just returns the ID of the person in question
39 GetID() {
40 return this.ID
41 }
42}
43
44
45//define 4 arrays, one for each stat
46let speed = [];
47let defense = [];
48let strength = [];
49let dexterity = [];
50
51//define an array of stats, we will hold speed, defense, strength, dexterity in here
52let stats = [];
53
54//this defines a class of a stat, this will just hold the information before it is passed into 'stats'
55let Stat = class {
56 constructor(_Name, _Data) {
57 this.Name = _Name;
58 this.Data = _Data;
59 }
60
61 GetStatName() {
62 return this.Name;
63 }
64
65 GetStatData() {
66 return this.Data;
67 }
68
69 AddData(_ID, _Contribution) {
70 this.ID = _ID;
71 this.Contribution = _Contribution;
72
73 this.Data.push(new Data(this.ID, this.Contribution));
74 }
75
76 ClearData() {
77 this.Data = [];
78 }
79
80}
81
82//now inside 'stats', we create each of our stats 1 at a time.
83stats.push(new Stat("speed", speed));
84stats.push(new Stat("strength", strength));
85stats.push(new Stat("dexterity", dexterity));
86stats.push(new Stat("defense", defense));
87
88//this will store our alerts and when we are ready to print it, we just cycle through alertInfo and print them out or use them however we want
89let alertInfo = [];
90
91//this class creates each individual alert
92let Alert = class {
93
94 constructor(_Name, _EnergySpent, _Stat) {
95 this.Name = _Name;
96 this.EnergySpent = _EnergySpent;
97 this.Stat = _Stat.charAt(0).toUpperCase() + _Stat.slice(1);
98 console.log("Added a new alert for " + this.Name);
99 }
100
101 GetStatName() {
102 return this.Stat;
103 }
104
105 GetMemberName() {
106 return this.Name;
107 }
108
109 GetEnergySpent() {
110 return this.EnergySpent;
111 }
112
113 GetInlineData() {
114 return this.Name + " spent " + this.EnergySpent + " Energy on " + this.Stat;
115 }
116
117 GetShortData() {
118 return this.Name + "\t \t \t \t \t" + this.EnergySpent + "E \t \t \t \t" + this.Stat;
119 }
120}
121
122//we create a new members array that allows us to compare Members against newMembers to see if anyone else has spent energy since we last checked
123let newMembers = [];
124//this does the same thing, checking our data against our new contributions.
125let newContributions = [];
126
127let updateOld;
128
129let key = "CgWsfUhtfSeEqizO"
130
131
132module.exports = {
133 name: 'gymtrain',
134 description: 'Stacking shit idk',
135 execute (msg, bot) {
136 let members = []; //stores our members
137 StartBot(bot.channels.cache.get('833658828926353428'))
138
139 function StartBot(id) {
140
141 console.log("Bot started. Getting Member List");
142
143
144 //runs this immediately
145 request({
146 url: "https://api.torn.com/faction/?selections=&key=" + key,
147 json: true
148 }, function (error, response, body) {
149 setTimeout(function () {
150 let memberData
151 try {
152 memberData = body.members //gets to the actual content
153 } catch(error)
154 {
155 bot.channels.cache.get('817360629097955348').send(error)
156 bot.channels.cache.get('817360629097955348').send("something did a fucky wucky i cri. i didn't crash doe :3")
157 }
158
159
160 for (i = 0; i < Object.keys(memberData).length; i++) {
161
162 //adds a new member to our members array.
163 members.push(new Member(
164 Object.entries(memberData)[i][1].name, //gets the members name from API
165 Object.entries(memberData)[i][0] //gets the members ID from the API
166 ));
167
168 }
169
170 console.log("Loaded current member list. Found " + members.length + " members.");
171
172 }, 7000);
173 });
174
175 //runs this after 15 seconds
176 setTimeout(function () {
177 for (s = 0; s < stats.length; s++) {
178 GetStatDataFromAPI(true, stats[s], id);
179 }
180 }, 15000);
181
182 //starts the loop after 30 seconds.
183 setTimeout(function () {
184 StartLoop(id);
185 console.log("Loop started");
186 }, 30000)
187
188 }
189
190 function StartLoop(id) {
191
192 //change the regularity to the how many minutes you want to check
193 let regularity = 15;
194
195 //this will run once a minute to ensure the time is correct.
196 setInterval(function GetData() {
197
198 //gets the date
199 let day = new Date();
200
201 //checks if the minutes divided by our regularity equals 0, if so then we Check the activity.
202 if (day.getMinutes() % regularity == 0) {
203 CheckActivity(id);
204 }
205
206 }, 60000);
207 }
208
209 function CheckActivity(id) {
210
211 console.log("Performing Faction Activity Checks")
212 if(process.env.gymbot === 'OFF')
213 return
214
215 //cycles through each of the stats and gets the data from the API and then checks for differences.
216 for (s = 0; s < stats.length; s++) {
217
218 GetStatDataFromAPI(false, stats[s], id);
219
220 }
221
222 //after 10 seconds it checks the 'alerts' and does whats required there
223 //10 seconds is probably long enough to figure out whats going on with the activity.
224 setTimeout(function () {
225
226 CheckAlerts(id);
227
228 }, 10000);
229 }
230
231 function GetStatDataFromAPI(firstTime, stat, id) {
232 if(process.env.gymbot === 'OFF')
233 return
234 request({
235 url: "https://api.torn.com/faction/?selections=contributors&stat=gym" + stat.GetStatName() + "&key=" + key,
236 json: true
237 }, function (error, response, body) {
238 //does this after 5 seconds
239 setTimeout(function () {
240
241 let data = Object.entries(body.contributors)[0][1]; //gets the right type of data from the data
242
243 newMembers = [];
244 newContributions = [];
245
246 for (i = 0; i < Object.keys(data).length; i++) { //cycles through all the data
247 if (Object.entries(data)[i][1].in_faction == 1) { //if the person is currently a member
248
249 if (firstTime) {
250
251 stat.AddData( //creates a stat entry and
252 Object.entries(data)[i][0], //adds the persons ID
253 Object.entries(data)[i][1].contributed //adds the persons contribution
254 ); //to the stat entry
255 //prints out so we know how many people we got in that stat to start with.
256
257 } else {
258
259 //adds them to our 2 new arrays
260 newMembers.push(Object.entries(data)[i][0]);
261 newContributions.push(Object.entries(data)[i][1].contributed);
262 }
263 }
264 }
265
266 if (firstTime) {
267 console.log("Found " + stat.GetStatData().length + " users who have contributed towards " + stat.GetStatName());
268 } else {
269 CheckForDifferences(stat, id);
270 }
271
272 }, 7000)
273
274 });
275 }
276
277 function CheckForDifferences(currentStat) {
278 if(process.env.gymbot === 'OFF')
279 return
280 updateOld = false; //we dont need to update the old at this point. We want this to only get set if we find differences in peoples contributions.
281
282 for (i = 0; i < newMembers.length; i++) { //cycle through our current users
283 for (x = 0; x < currentStat.GetStatData().length; x++) { //check our 'old users'
284 if (newMembers[i] == currentStat.GetStatData()[x].ID) { //find our 'new members' in our 'current stats' data
285 if (newContributions[i] > currentStat.GetStatData()[x].Contribution) { //check if they have spent energy
286 let eSpent = newContributions[i] - currentStat.GetStatData()[x].Contribution; //calculate Energy spent
287
288 //creates a new Alert within our list of alerts ready for use.
289 alertInfo.push(new Alert(
290 FindMembersName(newMembers[i]),
291 eSpent,
292 currentStat.GetStatName()
293 ));
294
295 //sets this to true because we need to update now cos we know that the old data is wrong.
296 updateOld = true;
297
298 }
299 }
300 }
301 }
302
303 if (updateOld) {
304
305 currentStat.ClearData() //sets the current stats Data to nothing.
306
307 //cycles through the new data (members and contributions) and writes them to the current stats data.
308 for (y = 0; y < newMembers.length; y++) {
309
310 currentStat.AddData(
311 newMembers[y],
312 newContributions[y]
313 );
314
315 }
316
317 }
318 }
319
320 function FindMembersName(who) {
321
322 //cycles through the member list to get the current users name.
323 for (i = 0; i < members.length; i++) {
324 if (who === members[i].GetID()) {
325 name = members[i].GetName();
326 break;
327 }
328 }
329 //returns the members name.
330 return name;
331 }
332 function FindMembersID(name) {
333
334 //cycles through the member list to get the current users name.
335 for (i = 0; i < members.length; i++) {
336 if (name === members[i].GetName()) {
337 name = members[i].GetID();
338 break;
339 }
340 }
341 //returns the members name.
342 return name;
343 }
344
345//call this when we want to see what Alerts there are.
346 function CheckAlerts(id) {
347 if(process.env.gymbot === 'OFF')
348 return
349
350 if (alertInfo.length >= 1) { //do we have at least 1 alert?
351 if (alertInfo.length < 3) { //do we have less than 3 alerts?
352 for (i = 0; i < alertInfo.length; i++) { //if so, cycle through them
353 console.log(alertInfo[i].GetInlineData());
354 let bruh = {
355 title: alertInfo[i].GetInlineData(),
356 };
357 id.send({embed: bruh});
358 //id.send(alertInfo[i].GetInlineData());//and print out the 'in line data'
359 }
360 } else {
361 let energySpent;
362 for (e = 0; e < alertInfo.length; e++) {
363 energySpent += alertInfo[e].GetEnergySpent();
364 } //otherwise
365 let report = alertInfo.length + " faction members have used " + energySpent + " Energy. \n"; //we create a report
366
367 let names = "", stats = "", statNames = "";
368 let meDie = ""
369
370 for (i = 0; i < alertInfo.length; i++) {//cycle through our alerts
371 //totalE[FindMembersID(alertInfo[i].GetMemberName())] += alertInfo[i].GetEnergySpent()
372 //meDie += alertInfo[i].GetMemberName() +" has trained " + totalE[FindMembersID(alertInfo[i].GetMemberName())] + " E in total." + "\n"
373 names += alertInfo[i].GetMemberName() + "\n";
374 stats += alertInfo[i].GetEnergySpent() + "\n"; //adding each variable to the report
375 statNames += alertInfo[i].GetStatName() + "\n";
376 }
377 console.log(report); //and printing the report out
378 let bruh = {
379 title: 'someone trained :(',
380 fields: [
381 {
382 name: 'Name',
383 value: names,
384 inline: true,
385 },
386 {
387 name: 'Energy Used',
388 value: stats,
389 inline: true,
390 },
391 {
392 name: "Stat",
393 value: statNames,
394 inline: true,
395 }
396 ]
397 };
398 id.send({embed: bruh});
399 }
400 console.log("Activity check complete"); //just so we know the alerts are ended
401
402 } else {
403 console.log("No new alerts. Check completed.") //and so we know there were no alerts
404 }
405
406 alertInfo = []; //clear alert info either way.
407 }
408
409 }
410}