homegames-common 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const https = require('https');
2
+ const http = require('http');
2
3
  const readline = require('readline');
3
4
  const WebSocket = require('ws');
4
- const http = require('http');
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
7
  const unzipper = require('unzipper');
@@ -10,10 +10,6 @@ const { Readable } = require('stream');
10
10
  const os = require('os');
11
11
  const process = require('process');
12
12
 
13
- const getUserHash = (username) => {
14
- return crypto.createHash('md5').update(username).digest('hex');
15
- };
16
-
17
13
  const DEFAULT_CONFIG = {
18
14
  "HTTPS_ENABLED": true,
19
15
  "LINK_ENABLED": true,
@@ -37,36 +33,19 @@ const DEFAULT_CONFIG = {
37
33
  "API_URL": "https://api.homegames.io",
38
34
  "LINK_PROXY_URL": "wss://public.homegames.link:81",
39
35
  "LINK_URL": "wss://homegames.link",
40
- "MAP_ENABLED": true
41
- }
42
-
43
- const getLocalIP = () => {
44
- const ifaces = os.networkInterfaces();
45
- let localIP;
46
-
47
- Object.keys(ifaces).forEach((ifname) => {
48
- ifaces[ifname].forEach((iface) => {
49
- if ('IPv4' !== iface.family || iface.internal) {
50
- return;
51
- }
52
- localIP = localIP || iface.address;
53
- });
54
- });
55
-
56
- return localIP;
36
+ "MAP_ENABLED": true
57
37
  };
58
38
 
39
+ // ---------------------------------------------------------------------------
40
+ // HTTP helpers
41
+ // ---------------------------------------------------------------------------
42
+
59
43
  const getUrl = (url, headers = {}) => new Promise((resolve, reject) => {
60
44
  const getModule = url.startsWith('https') ? https : http;
61
45
 
62
- let responseData = '';
63
-
64
- getModule.get(url, { headers } , (res) => {
46
+ getModule.get(url, { headers }, (res) => {
65
47
  const bufs = [];
66
- res.on('data', (chunk) => {
67
- bufs.push(chunk);
68
- });
69
-
48
+ res.on('data', (chunk) => { bufs.push(chunk); });
70
49
  res.on('end', () => {
71
50
  if (res.statusCode > 199 && res.statusCode < 300) {
72
51
  resolve(Buffer.concat(bufs));
@@ -74,17 +53,13 @@ const getUrl = (url, headers = {}) => new Promise((resolve, reject) => {
74
53
  reject(Buffer.concat(bufs));
75
54
  }
76
55
  });
77
- }).on('error', error => {
78
- reject(error);
79
- });
80
-
56
+ }).on('error', reject);
81
57
  });
82
58
 
83
- const postUrl = (url, path, _payload, headers = {}) => new Promise((resolve, reject) => {
59
+ const postUrl = (url, urlPath, _payload, headers = {}) => new Promise((resolve, reject) => {
84
60
  const payload = JSON.stringify(_payload);
85
61
 
86
62
  let module, hostname, port;
87
-
88
63
  if (url.startsWith('https')) {
89
64
  module = https;
90
65
  port = 443;
@@ -93,654 +68,151 @@ const postUrl = (url, path, _payload, headers = {}) => new Promise((resolve, rej
93
68
  module = http;
94
69
  port = 80;
95
70
  hostname = url.replace('http://', '');
96
- }
71
+ }
97
72
 
98
73
  Object.assign(headers, {
99
74
  'Content-Type': 'application/json',
100
75
  'Content-Length': payload.length
101
76
  });
102
77
 
103
- const options = {
104
- hostname,
105
- path,
106
- port,
107
- method: 'POST',
108
- headers
109
- };
110
-
111
78
  let responseData = '';
112
-
113
- const req = module.request(options, (res) => {
114
- res.on('data', (chunk) => {
115
- responseData += chunk;
116
- });
117
-
118
- res.on('end', () => {
119
- resolve(responseData);
120
- });
79
+ const req = module.request({ hostname, path: urlPath, port, method: 'POST', headers }, (res) => {
80
+ res.on('data', (chunk) => { responseData += chunk; });
81
+ res.on('end', () => { resolve(responseData); });
121
82
  });
122
-
83
+ req.on('error', reject);
123
84
  req.write(payload);
124
85
  req.end();
125
86
  });
126
87
 
127
- const guaranteeDir = (dir) => new Promise((resolve, reject) => {
128
- fs.exists(dir, (exists) => {
129
- if (exists) {
130
- resolve();
131
- } else {
132
- fs.mkdir(dir, (thing) => {
133
- resolve();
134
- });
135
- }
136
- });
137
- });
138
-
139
- const guaranteeCertFiles = (dir) => new Promise((resolve, reject) => {
140
-
141
- let certPath, keyPath;
142
-
143
- fs.readdir(dir, (err, files) => {
144
- files.forEach(file => {
145
- if (file === 'cert.pem') {
146
- certPath = path.join(dir, file);
147
- }
148
-
149
- if (file === 'key.pem') {
150
- keyPath = path.join(dir, file);
151
- }
152
- });
153
-
154
- if (!certPath) {
155
- reject('Could not find cert.pem');
156
- }
157
-
158
- if (!keyPath) {
159
- reject('Could not find key.pem');
160
- }
161
-
162
- resolve({
163
- certPath,
164
- keyPath
165
- });
166
- });
167
-
168
- });
169
-
170
- const validateCertData = (certPaths, username, accessToken) => new Promise((resolve, reject) => {
171
- // one day
172
- resolve(JSON.stringify({success: true}));
173
- // postUrl('https://certifier.homegames.io', '/verify', {
174
- // checksum: ''
175
- // },
176
- // {
177
- // 'hg-username': username,
178
- // 'hg-access-token': accessToken
179
- // }).then(data => {
180
- // resolve(data);
181
- // }).catch(err => {
182
- // reject({
183
- // message: err.toString()
184
- // });
185
- // });
88
+ // ---------------------------------------------------------------------------
89
+ // Filesystem helpers
90
+ // ---------------------------------------------------------------------------
186
91
 
187
- });
188
-
189
- const validateExistingCerts = (certPath, username, accessToken) => new Promise((resolve, reject) => {
190
- guaranteeDir(certPath).then(() => {
191
- guaranteeCertFiles(certPath).then((certPaths) => {
192
- validateCertData(certPath, username, accessToken).then((response) => {
193
- const data = JSON.parse(response);
194
- if (data.success) {
195
- resolve();
196
- } else {
197
- getCertData(username, accessToken).then(certData => {
198
- validateCertData(certPath, username, accessToken).then((response) => {
199
- const data = JSON.parse(response);
200
- if (data.success) {
201
- storeCertData(certData, certPath).then(() => {
202
- resolve();
203
- });
204
- } else {
205
- reject(data);
206
- }
207
- });
208
- });
209
- }
210
- }).catch(err => {
211
- console.log(err);
212
- reject(err);
213
- });
214
- }).catch(err => {
215
- console.log(err);
216
- getCertData(username, accessToken).then(certData => {
217
- validateCertData(certPath, username, accessToken).then((response) => {
218
- const data = JSON.parse(response);
219
- if (data.success) {
220
- storeCertData(certData, certPath).then(() => {
221
- resolve();
222
- });
223
- } else {
224
- reject(data);
225
- }
226
- });
227
- });
228
- });
229
- });
230
- });
231
-
232
- const guaranteeLoginFile = (loginPath) => new Promise((resolve, reject) => {
233
- fs.exists(path.join(loginPath, 'config'), (exists) => {
92
+ const guaranteeDir = (dir) => new Promise((resolve) => {
93
+ fs.exists(dir, (exists) => {
234
94
  if (exists) {
235
95
  resolve();
236
96
  } else {
237
- reject();
238
- }
239
- });
240
- });
241
-
242
- const validateLoginData = (loginPath) => new Promise((resolve, reject) => {
243
- guaranteeDir(loginPath).then(() => {
244
- guaranteeLoginFile(loginPath).then((loginData) => {
245
- resolve(loginData);
246
- }).catch(() => {
247
- reject('could not find login file');
248
- });
249
- });
250
- });
251
-
252
- const certInit = (certPath, loginPath) => new Promise((resolve, reject) => {
253
- validateExistingCerts(certPath).then((certData) => {
254
- }).catch(err => {
255
- validateLoginData(loginPath).then((loginData) => {
256
- getUrl('https://certifier.homegames.io/get-certs').then(data => {
257
- resolve(data);
258
- }).catch(err => {
259
- });
260
- }).catch(err => {
261
- reject(err);
262
- });
263
- });
264
- });
265
-
266
- const signup = (username, email, password) => new Promise((resolve, reject) => {
267
- postUrl('https://auth.homegames.io', '/', {
268
- email,
269
- username,
270
- password,
271
- type: 'signUp'
272
- }).then(data => {
273
- resolve(data);
274
- });
275
- });
276
-
277
- const confirmUser = (username, code) => new Promise((resolve, reject) => {
278
- postUrl('https://auth.homegames.io', '/', {
279
- username,
280
- code,
281
- type: 'confirmUser'
282
- }).then(data => {
283
- resolve(data);
284
- });
285
- });
286
-
287
- const login = (username, password) => new Promise((resolve, reject) => {
288
- postUrl('https://auth.homegames.io', '/', {
289
- type: 'login',
290
- username,
291
- password
292
- }).then(_data => {
293
- const data = JSON.parse(_data);
294
- if (data.errorType) {
295
- reject(data);
296
- } else {
297
- resolve(data);
298
- }
299
- });
300
- });
301
-
302
- const refreshAccessToken = (username, tokens) => new Promise((resolve, reject) => {
303
- postUrl('https://auth.homegames.io', '/', {
304
- type: 'refresh',
305
- username,
306
- accessToken: tokens.accessToken,
307
- refreshToken: tokens.refreshToken,
308
- idToken: tokens.idToken
309
- }).then(_data => {
310
- const data = JSON.parse(_data);
311
- if (data.accessToken && data.refreshToken) {
312
- resolve(data);
313
- } else {
314
- reject();
315
- }
316
- });
317
- });
318
-
319
- const verifyAccessToken = (username, accessToken) => new Promise((resolve, reject) => {
320
- postUrl('https://auth.homegames.io', '/', {
321
- type: 'verify',
322
- username,
323
- accessToken
324
- }).then(_data => {
325
- const data = JSON.parse(_data);
326
- if (data.errorType) {
327
- reject(data);
328
- } else {
329
- resolve(data);
330
- }
331
- });
332
- });
333
-
334
- const getLoginInfo = (authPath) => new Promise((resolve, reject) => {
335
- fs.exists(authPath, (exists) => {
336
- if (exists) {
337
- fs.readFile(authPath, (err, _data) => {
338
- let data;
339
-
340
- if (!_data) {
341
- reject({type: 'DATA_NOT_FOUND'});
342
- }
343
-
344
- try {
345
- data = JSON.parse(_data);
346
- if (!data.username || !data.tokens || data.errorType) {
347
- throw new Error();
348
- }
349
- } catch (err) {
350
- reject({
351
- type: 'DATA_READ_ERROR',
352
- message: err
353
- });
354
- }
355
-
356
- if (err) {
357
- reject({
358
- type: 'DATA_READ_ERROR',
359
- message: err
360
- });
361
- }
362
-
363
- resolve(data);
364
- });
365
- } else {
366
- reject({type: 'DATA_NOT_FOUND'});
367
- }
368
- });
369
- });
370
-
371
- const getCertData = (username, accessToken) => new Promise((resolve, reject) => {
372
-
373
- getUrl('https://certifier.homegames.io/get-cert', {
374
-
375
- 'hg-username': username,
376
- 'hg-token': accessToken
377
- }).then(data => {
378
- resolve(data);
379
- }).catch(err => {
380
- console.log(err.toString());
381
- console.log('that was an error');
382
- });
383
- });
384
-
385
- const bufToStream = (buf) => {
386
- return new Readable({
387
- read() {
388
- this.push(buf);
389
- this.push(null);
390
- }
391
- });
392
- };
393
-
394
- // unzip a cert bundle to the given path
395
- const storeCertData = (certBundle, path) => new Promise((resolve, reject) => {
396
- const certStream = bufToStream(certBundle);
397
-
398
- const unzip = unzipper.Extract({ path });
399
- certStream.pipe(unzip);
400
-
401
- unzip.on('close', resolve);
402
- });
403
-
404
- const storeTokens = (path, username, tokens) => new Promise((resolve, reject) => {
405
- const pathPieces = path.split('/');
406
- let pathParent = [];
407
- for (let x in pathPieces) {
408
- if (x == pathPieces.length - 1) {
409
- break
410
- } else {
411
- pathParent.push(pathPieces[x]);
97
+ fs.mkdir(dir, { recursive: true }, () => { resolve(); });
412
98
  }
413
- }
414
-
415
- guaranteeDir(pathParent.join('/')).then(() => {
416
- const authData = {
417
- username,
418
- tokens
419
- };
420
- fs.writeFile(path, JSON.stringify(authData), (err) => {
421
- if (err) {
422
- reject('Failed to store tokens');
423
- } else {
424
- resolve();
425
- }
426
- });
427
- });
428
- });
429
-
430
- const guaranteeCerts = (authPath, certPath) => new Promise((resolve, reject) => {
431
-
432
- authWorkflow(authPath).then(authInfo => {
433
- getCertData(authInfo.username, authInfo.tokens.accessToken).then(certData => {
434
- validateCertData(certPath, authInfo.username, authInfo.tokens.accessToken).then((response) => {
435
- const data = JSON.parse(response);
436
- if (data.success) {
437
- storeCertData(certData, certPath).then(() => {
438
- resolve({
439
- certPath: `${certPath}/cert.pem`,
440
- keyPath: `${certPath}/key.pem`,
441
- });
442
- });
443
- } else {
444
- reject(data);
445
- }
446
- });
447
- }).catch(err => {
448
- reject({message: err});
449
- });
450
- }).catch(err => {
451
- console.log(err);
452
- });
453
- });
454
-
455
- const linkInit = (authPath) => new Promise((resolve, reject) => {
456
-
457
- getLoginInfo(authPath).then((loginInfo) => {
458
- const client = new WebSocket('wss://homegames.link:7080');
459
-
460
- client.on('open', () => {
461
- console.log('opened connection to link');
462
- client.send(JSON.stringify({
463
- ip: getLocalIP(),
464
- username: loginInfo.username,
465
- accessToken: loginInfo.tokens.accessToken
466
- }));
467
- });
468
-
469
- client.on('error', (err) => {
470
- console.log('some error happened');
471
- console.log(err);
472
- });
473
99
  });
474
-
475
100
  });
476
101
 
477
- const promptLogin = () => new Promise((resolve, reject) => {
478
- const rl = readline.createInterface({
479
- input: process.stdin,
480
- output: process.stdout
481
- });
482
-
483
- rl.question('username:\n', (username) => {
484
- rl.question('password:\n', (password) => {
485
- resolve({
486
- username,
487
- password
488
- });
489
- });
490
- });
491
- });
102
+ const getAppDataPath = () => {
103
+ if (!process) return '';
492
104
 
493
- const lockFile = (path) => new Promise((resolve, reject) => {
494
-
495
- let _interval;
496
-
497
- const acquireLock = () => {
498
- const lockPath = `${path}.hglock`;
499
- fs.exists(lockPath, (exists) => {
500
- if (!exists) {
501
- const pathPieces = path.split('/');
502
- let pathParent = [];
503
- for (let x in pathPieces) {
504
- if (x == pathPieces.length - 1) {
505
- break
506
- } else {
507
- pathParent.push(pathPieces[x]);
508
- }
105
+ let _path;
106
+ switch (process.platform) {
107
+ case "darwin":
108
+ _path = process.env.HOME ? path.join(process.env.HOME, "Library", "Application Support", "homegames") : __dirname;
109
+ break;
110
+ case "win32":
111
+ _path = process.env.APPDATA ? path.join(process.env.APPDATA, "homegames") : __dirname;
112
+ break;
113
+ case "linux":
114
+ _path = process.env.HOME ? path.join(process.env.HOME, ".homegames") : __dirname;
115
+ break;
116
+ default:
117
+ console.log("Unsupported platform!");
118
+ process.exit(1);
509
119
  }
510
120
 
511
- guaranteeDir(pathParent.join('/')).then(() => {
512
- console.log("writing lock file");
513
- console.log(lockPath);
514
- fs.writeFile(lockPath, 'lock', 'utf-8', () => {
515
- clearInterval(_interval);
516
- fs.readFile(lockPath, (err, data) => {
517
- if (err) {
518
- console.log(err);
519
- reject(err);
520
- } else {
521
- resolve();
522
- }
523
- });
524
- });
525
- });
526
- } else {
527
- console.log('waiting for lock');
528
- const { birthtime } = fs.statSync(lockPath);
529
- const fiveMinsAgo = Date.now() - ( 1000 * 60 * 5 );
530
- console.log(birthtime);
531
- if (new Date(birthtime).getTime() < fiveMinsAgo) {
532
- fs.unlink(lockPath, (err) => {
533
- console.log(err);
534
- console.log('deleted');
535
- });
536
- }
537
- }
538
- });
539
-
540
- };
541
-
542
- _interval = setInterval(acquireLock, 1000);
543
- });
544
-
545
- const unlockFile = (path) => new Promise((resolve, reject) => {
546
- const lockPath = `${path}.hglock`;
547
-
548
- fs.readFile(lockPath, (err, data) => {
549
- fs.unlink(lockPath, (err) => {
550
- if (!err) {
551
- resolve();
552
- } else {
553
- reject('Could not delete lock');
554
- }
555
- });
556
- });
557
- });
558
-
559
- const authWorkflow = (authPath) => new Promise((resolve, reject) => {
560
- if (!authPath) {
561
- reject(`No authPath provided`);
121
+ if (!fs.existsSync(_path)) {
122
+ fs.mkdirSync(_path, { recursive: true });
562
123
  }
563
124
 
564
- const _doLogin = () => {
565
- promptLogin().then((loginInfo) => {
566
- login(loginInfo.username, loginInfo.password).then(tokens => {
567
- storeTokens(authPath, loginInfo.username, tokens).then(() => {
568
- verifyAccessToken(loginInfo.username, tokens.accessToken).then(() => {
569
- unlockFile(authPath).then(() => {
570
- resolve({
571
- username: loginInfo.username,
572
- tokens
573
- });
574
- });
575
-
576
- });
577
- }).catch(err => {
578
- console.log('Failed to store auth tokens');
579
- reject(err);
580
- });
581
- }).catch(err => {
582
- console.log('Failed to login');
583
- reject(err);
584
- });
585
- });
586
- };
587
-
588
- console.log('about to lock ' + authPath);
589
- lockFile(authPath).then(() => {
590
- getLoginInfo(authPath).then((loginInfo) => {
591
- verifyAccessToken(loginInfo.username, loginInfo.tokens.accessToken).then(() => {
592
- unlockFile(authPath).then(() => {
593
- resolve(loginInfo);
594
- });
595
- }).catch(err => {
596
- console.log('failed to verify access token');
597
- _doLogin();
598
- });
599
- }).catch((err) => {
600
- console.log(err);
601
- if (err.type === 'DATA_NOT_FOUND') {
602
- _doLogin();
603
- }
604
- });
605
- }).catch(err => {
606
- console.log(err);
607
- console.log("Failed to acquire lock");
608
- });
609
- });
610
-
611
- let electronLog = null;
612
- try {
613
- electronLog = require('electron-log');
614
- } catch (err) {
615
- console.log('not running with electron');
616
- }
125
+ return _path;
126
+ };
617
127
 
618
- const defaultLog = { info: (msg) => console.log(msg), error: (msg) => console.error(msg)};
128
+ const log = {
129
+ info: (msg) => console.log(msg),
130
+ error: (msg) => console.error(msg),
131
+ debug: (msg) => console.log(msg),
132
+ };
619
133
 
620
- const log = electronLog == null ?
621
- (
622
- process.env.LOGGER_LOCATION ?
623
- require(process.env.LOGGER_LOCATION) : defaultLog
624
- ) : electronLog;
625
-
626
- log.info('doing this');
134
+ // ---------------------------------------------------------------------------
135
+ // Config
136
+ // ---------------------------------------------------------------------------
627
137
 
628
138
  const getConfigValue = (key, _default = undefined) => {
629
139
  const config = getConfig();
630
140
 
631
141
  let envValue = process.env[key] && `${process.env[key]}`;
632
142
  if (envValue !== undefined) {
633
- if (envValue === 'true') {
634
- envValue = true;
635
- } else if (envValue === 'false') {
636
- envValue = false;
637
- }
143
+ if (envValue === 'true') envValue = true;
144
+ else if (envValue === 'false') envValue = false;
638
145
  log.info(`Using environment value: ${envValue} for key: ${key}`);
639
146
  return envValue;
640
147
  }
641
- if (config[key] === undefined && _default === undefined) {
642
- throw new Error(`No value for ${key} found in config`);
643
- } else if (config[key] === undefined && _default !== undefined) {
644
- log.info(`Using default value (${_default}) for ${key}`);
645
- return DEFAULT_CONFIG[key] || _default;
646
- }
647
- log.info(`Found value ${config[key]} for ${key} in config`);
648
- return config[key];
148
+
149
+ if (config[key] === undefined && _default === undefined) {
150
+ throw new Error(`No value for ${key} found in config`);
151
+ } else if (config[key] === undefined && _default !== undefined) {
152
+ log.info(`Using default value (${_default}) for ${key}`);
153
+ return DEFAULT_CONFIG[key] || _default;
154
+ }
155
+ log.info(`Found value ${config[key]} for ${key} in config`);
156
+ return config[key];
649
157
  };
650
158
 
651
159
  let cachedConfig = {};
652
160
 
653
161
  const getConfig = () => {
162
+ if (Object.keys(cachedConfig).length > 0) return cachedConfig;
654
163
 
655
- if (Object.keys(cachedConfig).length > 0) {
656
- return cachedConfig;
657
- }
164
+ const options = [getAppDataPath(), process.cwd()];
165
+ try { options.push(path.dirname(require.main.filename)); } catch (e) {}
166
+ try { options.push(path.dirname(process.mainModule.filename)); } catch (e) {}
167
+ options.push(__dirname);
658
168
 
659
- const options = [getAppDataPath(), process.cwd(), require.main.filename, process.mainModule.filename, __dirname]
660
169
  let _config = null;
661
- let configPath = null;
662
-
663
170
  for (let i = 0; i < options.length; i++) {
664
- if (fs.existsSync(`${options[i]}/config.json`)) {
665
- log.info(`Found config at ${options[i]}`);
666
- configPath = options[i];
667
- _config = JSON.parse(fs.readFileSync(`${options[i]}/config.json`));
668
- break;
669
- }
670
- }
671
-
672
- if (!_config) {
673
- _config = DEFAULT_CONFIG;
171
+ try {
172
+ if (fs.existsSync(`${options[i]}/config.json`)) {
173
+ log.info(`Found config at ${options[i]}`);
174
+ _config = JSON.parse(fs.readFileSync(`${options[i]}/config.json`));
175
+ break;
176
+ }
177
+ } catch (e) {}
674
178
  }
675
179
 
676
- log.info('Using config: ' + configPath);
677
- log.info(_config);
180
+ if (!_config) _config = DEFAULT_CONFIG;
678
181
 
679
182
  cachedConfig = _config;
680
-
681
183
  return _config;
682
- }
683
-
684
-
685
- const getLogLevel = (logLevel = null) => {
686
- const _logLevel = logLevel || getConfigValue('LOG_LEVEL', 'INFO');
687
- const levelList = ['DISABLED', 'INFO', 'DEBUG'];
688
-
689
- return levelList.indexOf(_logLevel);
690
184
  };
691
185
 
692
- const msgToString = (msg) => {
693
- return typeof msg === 'object' ? JSON.stringify(msg) : msg;
694
- };
186
+ // ---------------------------------------------------------------------------
187
+ // Shared modules
188
+ // ---------------------------------------------------------------------------
695
189
 
696
- const getAppDataPath = () => {
697
- if (!process) {
698
- // this shouldnt be called if running in browser
699
- return '';
700
- }
701
-
702
- let _path;
703
- switch (process.platform) {
704
- case "darwin": {
705
- _path = process.env.HOME ? path.join(process.env.HOME, "Library", "Application Support", "homegames") : __dirname;
706
- break;
707
- }
708
- case "win32": {
709
- _path = process.env.APPDATA ? path.join(process.env.APPDATA, "homegames") : __dirname;
710
- break;
711
- }
712
- case "linux": {
713
- _path = process.env.HOME ? path.join(process.env.HOME, ".homegames") : __dirname;
714
- break;
715
- }
716
- default: {
717
- console.log("Unsupported platform!");
718
- process.exit(1);
719
- }
720
- }
721
-
722
- if (!fs.existsSync(_path)) {
723
- fs.mkdirSync(_path);
724
- }
190
+ const gameLoader = require('./game-loader');
191
+ const dockerHelper = require('./docker-helper');
192
+ const GameSession = require('./game-session');
193
+ const GameSessionManager = require('./game-session-manager');
725
194
 
726
- return _path;
727
- }
195
+ // ---------------------------------------------------------------------------
196
+ // Exports
197
+ // ---------------------------------------------------------------------------
728
198
 
729
199
  module.exports = {
730
- signup,
731
- login,
732
- confirmUser,
733
- getLoginInfo,
734
- verifyAccessToken,
735
- refreshAccessToken,
736
- linkInit,
737
- getUserHash,
738
- authWorkflow,
200
+ // Utilities
739
201
  guaranteeDir,
740
202
  getUrl,
741
203
  getConfigValue,
742
204
  log,
743
- getAppDataPath
744
- };
205
+ getAppDataPath,
745
206
 
207
+ // Game loading
208
+ gameLoader,
209
+ squishMap: gameLoader.squishMap,
210
+ DEFAULT_SQUISH_VERSION: gameLoader.DEFAULT_SQUISH_VERSION,
746
211
 
212
+ // Docker
213
+ dockerHelper,
214
+
215
+ // Sessions
216
+ GameSession,
217
+ GameSessionManager,
218
+ };