1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _fs = require('fs');
|
8 |
|
9 | var _fs2 = _interopRequireDefault(_fs);
|
10 |
|
11 | var _path = require('path');
|
12 |
|
13 | var _path2 = _interopRequireDefault(_path);
|
14 |
|
15 | var _helperGetGradeLetter = require('@warriorjs/helper-get-grade-letter');
|
16 |
|
17 | var _helperGetGradeLetter2 = _interopRequireDefault(_helperGetGradeLetter);
|
18 |
|
19 | var _GameError = require('./GameError');
|
20 |
|
21 | var _GameError2 = _interopRequireDefault(_GameError);
|
22 |
|
23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
24 |
|
25 | function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
26 |
|
27 | const profileFile = '.profile';
|
28 | const playerCodeFile = 'Player.js';
|
29 | const readmeFile = 'README.md';
|
30 |
|
31 |
|
32 | class Profile {
|
33 | |
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | static load(profileDirectoryPath, towers) {
|
42 | if (!Profile.isProfileDirectory(profileDirectoryPath)) {
|
43 | return null;
|
44 | }
|
45 |
|
46 | const profileFilePath = _path2.default.join(profileDirectoryPath, profileFile);
|
47 | const encodedProfile = Profile.read(profileFilePath);
|
48 | if (!encodedProfile) {
|
49 | return null;
|
50 | }
|
51 |
|
52 | const decodedProfile = Profile.decode(encodedProfile);
|
53 | const {
|
54 | warriorName,
|
55 | towerId,
|
56 | towerName,
|
57 | directoryPath,
|
58 | currentEpicScore,
|
59 | currentEpicGrades } = decodedProfile,
|
60 | profileData = _objectWithoutProperties(decodedProfile, ['warriorName', 'towerId', 'towerName', 'directoryPath', 'currentEpicScore', 'currentEpicGrades']);
|
61 |
|
62 | const towerKey = towerId || towerName;
|
63 | const profileTower = towers.find(tower => tower.id === towerKey);
|
64 | if (!profileTower) {
|
65 | throw new _GameError2.default(`Unable to find tower '${towerKey}', make sure it is available.`);
|
66 | }
|
67 |
|
68 | const profile = new Profile(warriorName, profileTower, profileDirectoryPath);
|
69 | return Object.assign(profile, profileData);
|
70 | }
|
71 |
|
72 | |
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 | static isProfileDirectory(profileDirectoryPath) {
|
83 | const profileFilePath = _path2.default.join(profileDirectoryPath, profileFile);
|
84 | const playerCodeFilePath = _path2.default.join(profileDirectoryPath, playerCodeFile);
|
85 | try {
|
86 | return _fs2.default.statSync(profileFilePath).isFile() && _fs2.default.statSync(playerCodeFilePath).isFile();
|
87 | } catch (err) {
|
88 | if (err.code === 'ENOENT') {
|
89 | return false;
|
90 | }
|
91 |
|
92 | throw err;
|
93 | }
|
94 | }
|
95 |
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 | static read(profileFilePath) {
|
104 | try {
|
105 | return _fs2.default.readFileSync(profileFilePath, 'utf8');
|
106 | } catch (err) {
|
107 | if (err.code === 'ENOENT') {
|
108 | return null;
|
109 | }
|
110 |
|
111 | throw err;
|
112 | }
|
113 | }
|
114 |
|
115 | |
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | static decode(encodedProfile) {
|
123 | try {
|
124 | return JSON.parse(Buffer.from(encodedProfile, 'base64').toString());
|
125 | } catch (err) {
|
126 | if (err instanceof SyntaxError) {
|
127 | throw new _GameError2.default('Invalid .profile file. Try changing the directory under which you are running warriorjs.');
|
128 | }
|
129 |
|
130 | throw err;
|
131 | }
|
132 | }
|
133 |
|
134 | |
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | constructor(warriorName, tower, directoryPath) {
|
142 | this.warriorName = warriorName;
|
143 | this.tower = tower;
|
144 | this.directoryPath = directoryPath;
|
145 | this.levelNumber = 0;
|
146 | this.score = 0;
|
147 | this.clue = false;
|
148 | this.epic = false;
|
149 | this.epicScore = 0;
|
150 | this.averageGrade = null;
|
151 | this.currentEpicScore = 0;
|
152 | this.currentEpicGrades = {};
|
153 | }
|
154 |
|
155 | |
156 |
|
157 |
|
158 | makeProfileDirectory() {
|
159 | _fs2.default.mkdirSync(this.directoryPath);
|
160 | }
|
161 |
|
162 | |
163 |
|
164 |
|
165 |
|
166 |
|
167 | readPlayerCode() {
|
168 | try {
|
169 | return _fs2.default.readFileSync(this.getPlayerCodeFilePath(), 'utf8');
|
170 | } catch (err) {
|
171 | if (err.code === 'ENOENT') {
|
172 | return null;
|
173 | }
|
174 |
|
175 | throw err;
|
176 | }
|
177 | }
|
178 |
|
179 | |
180 |
|
181 |
|
182 |
|
183 |
|
184 | getPlayerCodeFilePath() {
|
185 | return _path2.default.join(this.directoryPath, playerCodeFile);
|
186 | }
|
187 |
|
188 | |
189 |
|
190 |
|
191 |
|
192 |
|
193 | getReadmeFilePath() {
|
194 | return _path2.default.join(this.directoryPath, readmeFile);
|
195 | }
|
196 |
|
197 | |
198 |
|
199 |
|
200 | goToNextLevel() {
|
201 | this.levelNumber += 1;
|
202 | this.clue = false;
|
203 | this.save();
|
204 | }
|
205 |
|
206 | |
207 |
|
208 |
|
209 | requestClue() {
|
210 | this.clue = true;
|
211 | this.save();
|
212 | }
|
213 |
|
214 | |
215 |
|
216 |
|
217 |
|
218 |
|
219 | isShowingClue() {
|
220 | return this.clue;
|
221 | }
|
222 |
|
223 | |
224 |
|
225 |
|
226 | enableEpicMode() {
|
227 | this.epic = true;
|
228 | this.save();
|
229 | }
|
230 |
|
231 | |
232 |
|
233 |
|
234 |
|
235 |
|
236 | isEpic() {
|
237 | return this.epic;
|
238 | }
|
239 |
|
240 | |
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 | tallyPoints(levelNumber, { total: totalScore, grade }) {
|
247 | if (this.isEpic()) {
|
248 | this.currentEpicGrades[levelNumber] = grade;
|
249 | this.currentEpicScore += totalScore;
|
250 | } else {
|
251 | this.score += totalScore;
|
252 | }
|
253 | }
|
254 |
|
255 | |
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 | getEpicScoreWithGrade() {
|
263 | if (this.averageGrade) {
|
264 | return `${this.epicScore} (${(0, _helperGetGradeLetter2.default)(this.averageGrade)})`;
|
265 | }
|
266 |
|
267 | return this.epicScore.toString();
|
268 | }
|
269 |
|
270 | |
271 |
|
272 |
|
273 | updateEpicScore() {
|
274 | if (this.currentEpicScore > this.epicScore) {
|
275 | this.epicScore = this.currentEpicScore;
|
276 | this.averageGrade = this.calculateAverageGrade();
|
277 | }
|
278 |
|
279 | this.save();
|
280 | }
|
281 |
|
282 | |
283 |
|
284 |
|
285 |
|
286 |
|
287 | calculateAverageGrade() {
|
288 | const grades = Object.values(this.currentEpicGrades);
|
289 | if (!grades.length) {
|
290 | return null;
|
291 | }
|
292 |
|
293 | return grades.reduce((sum, value) => sum + value) / grades.length;
|
294 | }
|
295 |
|
296 | |
297 |
|
298 |
|
299 | save() {
|
300 | _fs2.default.writeFileSync(this.getProfileFilePath(), this.encode());
|
301 | }
|
302 |
|
303 | |
304 |
|
305 |
|
306 |
|
307 |
|
308 | getProfileFilePath() {
|
309 | return _path2.default.join(this.directoryPath, profileFile);
|
310 | }
|
311 |
|
312 | |
313 |
|
314 |
|
315 |
|
316 |
|
317 | encode() {
|
318 | return Buffer.from(JSON.stringify(this)).toString('base64');
|
319 | }
|
320 |
|
321 | |
322 |
|
323 |
|
324 |
|
325 |
|
326 | toJSON() {
|
327 | return {
|
328 | warriorName: this.warriorName,
|
329 | towerId: this.tower.id,
|
330 | levelNumber: this.levelNumber,
|
331 | clue: this.clue,
|
332 | epic: this.epic,
|
333 | score: this.score,
|
334 | epicScore: this.epicScore,
|
335 | averageGrade: this.averageGrade
|
336 | };
|
337 | }
|
338 |
|
339 | |
340 |
|
341 |
|
342 |
|
343 |
|
344 | toString() {
|
345 | let result = `${this.warriorName} - ${this.tower}`;
|
346 | if (this.isEpic()) {
|
347 | result += ` - first score ${this.score} - epic score ${this.getEpicScoreWithGrade()}`;
|
348 | } else {
|
349 | result += ` - level ${this.levelNumber} - score ${this.score}`;
|
350 | }
|
351 |
|
352 | return result;
|
353 | }
|
354 | }
|
355 |
|
356 | exports.default = Profile;
|
357 | module.exports = exports.default; |
\ | No newline at end of file |