· 10 years ago · Aug 07, 2016, 04:57 PM
1ptc-act-gen
2index.js
3
4
5// Requires
6var Nightmare = require('nightmare');
7var nicknames = require('./nicknames.json');
8var fs = require('fs');
9
10// Settings
11var debug = false;
12var showWindow = false;
13
14var start = 0; // Start from x (NAMEx, EMAIL+x@domain.com)
15var end = 10;
16
17var useNicknamesFile = false; // Use nicknames file, or just append numbers to username?
18var useRandomPassword = false; // Generate a random password?
19var screenshotResult = true; // Saves a screenshot per account creation if set to true
20var screenshotOnFailure = true; // Saves a screenshot even if registration failed
21
22var outputFile = "output/accounts.txt"; // File which will contain the generated "username password" combinations.
23var outputFormat = "%NICK% %PASS%\r\n"; // Format used to save the account data in outputFile. Supports %NICK%, %PASS%.
24var screenshotFolder = "output/screenshots/";
25
26var country = "US"; // Country code (e.g. BE, FR, US, CA)
27var dob = "1984-03-03"; // Date of birth, yyyy-mm-dd
28var username = "username1"; // User- & display name. Make sure any "(username + number)@domain.com" is 100% unique.
29var password = "staticPassword"; // Static password for all accounts. Ignored if useRandomPassword is true.
30var email_user = "gmailemailaccount"; // If your email is email@domain.com, enter "email"
31var email_domain = "gmail.com"; // Domain of e-mail host
32
33// App data
34var url_ptc = "https://club.pokemon.com/us/pokemon-trainer-club/sign-up/";
35var useragent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36";
36var nightmare_opts = {
37 show: showWindow,
38 waitTimeout: 10000,
39 gotoTimeout: 5000,
40 loadTimeout: 5000
41};
42
43// Settings check
44if (!useNicknamesFile && (username + end).length > 16) {
45 console.log("Error: length of username + number can't be longer than 16 characters.");
46 console.log("Please use a shorter nickname.");
47 process.exit();
48}
49
50if ((email_user + '+' + username + end + '@' + email_domain).length > 75) {
51 console.log("Error: length of e-mail address including the + trick can't be longer than 75 characters.");
52 console.log("Please use a shorter e-mail address and/or nickname.");
53 process.exit();
54}
55
56if (!useRandomPassword && password.length > 15) {
57 console.log("Error: length of password can't be longer than 15 characters.");
58 console.log("Please use a shorter password.");
59 process.exit();
60}
61
62// LETSAHGO
63var nightmare = Nightmare(nightmare_opts);
64nightmare.useragent(useragent);
65
66createAccount(start);
67
68// Helpers
69
70function handleError(err) {
71 if(debug) {
72 console.log("[DEBUG] Error:" + JSON.stringify(err));
73 }
74
75 return err;
76}
77
78function randomPassword() {
79 return Math.random().toString(36).substr(2, 8);
80}
81
82function prepareNightmare(nightmare) {
83 nightmare.useragent(useragent);
84}
85
86function randomPassword() {
87 return Math.random().toString(36).substr(2, 8);
88}
89
90// Pages
91function createAccount(ctr) {
92 console.log("Creating account " + ctr + " of " + end);
93
94 // Launch instance
95 handleFirstPage(ctr);
96}
97
98// First page
99function handleFirstPage(ctr) {
100 if(debug) {
101 console.log("[DEBUG] Handle first page #" + ctr);
102 }
103
104 nightmare.goto(url_ptc)
105 .evaluate(evaluateDobPage)
106 .then(function(validated) {
107 if(!validated) {
108 // Missing form data, loop over itself
109 console.log("[" + ctr + "] Servers are acting up... Trying again.");
110 return function() { nightmare.wait(500).refresh().wait(); handleFirstPage(ctr); };
111 } else {
112 return function() { fillFirstPage(ctr); };
113 }
114 })
115 .then(function(next) {
116 // Handle next step: either a loop to first page in case of error, or form fill on success
117 return next();
118 })
119 .catch(handleError)
120 .then(function(err) {
121 if (typeof err !== "undefined") {
122 return handleFirstPage(ctr);
123 }
124 });
125}
126
127function fillFirstPage(ctr) {
128 if(debug) {
129 console.log("[DEBUG] Fill first page #" + ctr);
130 }
131
132 nightmare.evaluate(function(data) {
133 document.getElementById("id_dob").value = data.dob;
134
135 var els = document.getElementsByName("id_country");
136 for(var i = 0; i < els.length; i++) {
137 els[i].value = data.country;
138 }
139
140 return document.getElementById("id_dob").value;
141 }, { dob: dob, country: country })
142 .click("form[name='verify-age'] [type=submit]")
143 .wait("#id_username")
144 .then(function() {
145 handleSignupPage(ctr);
146 })
147 .catch(handleError)
148 .then(function(err) {
149 if (typeof err !== "undefined") {
150 return handleFirstPage(ctr);
151 }
152 });
153}
154
155// Signup page
156function handleSignupPage(ctr) {
157 if(debug) {
158 console.log("[DEBUG] Handle second page #" + ctr);
159 }
160
161 nightmare.evaluate(evaluateSignupPage)
162 .then(function(validated) {
163 if(!validated) {
164 // Missing form data, loop over itself
165 console.log("[" + ctr + "] Servers are acting up... Trying again.");
166 return function() { nightmare.wait(500).refresh().wait(); handleFirstPage(ctr); };
167 } else {
168 return function() { fillSignupPage(ctr); };
169 }
170 }).then(function(next) {
171 // Handle next step: either a loop to first page in case of error, or form fill on success
172 return next();
173 })
174 .catch(handleError)
175 .then(function(err) {
176 if (typeof err !== "undefined") {
177 return handleSignupPage(ctr);
178 }
179 });
180}
181
182function fillSignupPage(ctr) {
183 if(debug) {
184 console.log("[DEBUG] Fill signup page #" + ctr);
185 }
186
187 var _pass = password;
188 var _nick = username + ctr;
189
190 if(useRandomPassword) {
191 _pass = randomPassword();
192 }
193
194 // Use nicknames list, or (username + number) combo?
195 if(useNicknamesFile) {
196 // Make sure we have a nickname left
197 if(nicknames.length < 1) {
198 throw Error("We're out of nicknames to use!");
199 }
200
201 // Get the first nickname off the list & use it
202 _nick = nicknames.shift();
203 }
204
205 // Fill it all in
206 nightmare.evaluate(function(data) {
207 document.getElementById("id_password").value = data.pass;
208 document.getElementById("id_confirm_password").value = data.pass;
209 document.getElementById("id_email").value = data.email_user + "+" + data.nick + "@" + data.email_domain;
210 document.getElementById("id_confirm_email").value = data.email_user + "+" + data.nick + "@" + data.email_domain;
211 document.getElementById("id_screen_name").value = data.nick;
212 document.getElementById("id_username").value = data.nick;
213 }, { "pass": _pass, "nick": _nick, "email_user": email_user, "email_domain": email_domain })
214 .check("#id_terms")
215 .click("form[name='create-account'] [type=submit]")
216 .wait(function() {
217 return (document.getElementById("signup-signin") !== null || document.getElementById("btn-reset") !== null || document.body.textContent.indexOf("That username already exists") > -1);
218 })
219 .evaluate(function() {
220 return (document.body.textContent.indexOf("Hello! Thank you for creating an account!") > -1);
221 })
222 .then(function(success) {
223 if(success) {
224 // Log it in the file of used nicknames
225 var content = outputFormat.replace('%NICK%', _nick).replace('%PASS%', _pass);
226 fs.appendFile(outputFile, content, function(err) {
227 //
228 });
229 }
230
231 if((success && screenshotResult) || screenshotOnFailure) {
232 // Screenshot
233 nightmare.screenshot(screenshotFolder + _nick + ".png");
234 }
235
236 // Next one, or stop
237 if(ctr < end) {
238 return function() { createAccount(ctr + 1); };
239 } else {
240 return nightmare.end();
241 }
242 }).then(function(next) {
243 return next();
244 }).catch(handleError)
245 .then(function(err) {
246 if (typeof err !== "undefined") {
247 return handleSignupPage(ctr);
248 }
249 });
250}
251
252// Evaluations
253function evaluateDobPage() {
254 var dob_value = document.getElementById("id_dob");
255 return ((document.title === "The Official Pokémon Website | Pokemon.com") && (dob_value !== null));
256}
257
258function evaluateSignupPage() {
259 var username_field = document.getElementById("id_username");
260 return ((document.title === "The Official Pokémon Website | Pokemon.com") && (username_field !== null));
261}