stagelinq 1.0.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.
Files changed (45) hide show
  1. package/.gitattributes +2 -0
  2. package/.prettierignore +7 -0
  3. package/.prettierrc.js +10 -0
  4. package/.vscode/launch.json +40 -0
  5. package/.vscode/tasks.json +24 -0
  6. package/Databases/Databases.ts +69 -0
  7. package/Databases/DbConnection.ts +42 -0
  8. package/Databases/index.ts +2 -0
  9. package/LICENSE +674 -0
  10. package/LogEmitter/index.ts +51 -0
  11. package/README.md +83 -0
  12. package/StageLinq/index.ts +58 -0
  13. package/TODO.md +5 -0
  14. package/albumArt/index.ts +2 -0
  15. package/albumArt/maybeDownloadFiles.ts +34 -0
  16. package/cli/index.ts +142 -0
  17. package/devices/Player.ts +182 -0
  18. package/devices/PlayerMessageQueue.ts +62 -0
  19. package/index.ts +5 -0
  20. package/network/NetworkDevice.ts +287 -0
  21. package/network/StageLinqDevices.ts +215 -0
  22. package/network/StageLinqListener.ts +50 -0
  23. package/network/announce.ts +133 -0
  24. package/network/index.ts +4 -0
  25. package/package.json +31 -0
  26. package/services/FileTransfer.ts +298 -0
  27. package/services/Service.ts +144 -0
  28. package/services/StateMap.ts +170 -0
  29. package/services/index.ts +3 -0
  30. package/stagelinq.code-workspace +16 -0
  31. package/tsconfig.json +13 -0
  32. package/types/common.ts +240 -0
  33. package/types/database.ts +50 -0
  34. package/types/index.ts +53 -0
  35. package/types/player.ts +41 -0
  36. package/types/tokens.ts +39 -0
  37. package/utils/Context.ts +45 -0
  38. package/utils/ReadContext.ts +114 -0
  39. package/utils/WriteContext.ts +105 -0
  40. package/utils/getTempFilePath.ts +23 -0
  41. package/utils/hex.ts +62 -0
  42. package/utils/index.ts +6 -0
  43. package/utils/log.ts +0 -0
  44. package/utils/sleep.ts +3 -0
  45. package/utils/tcp.ts +17 -0
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+ const assert = require('assert');
3
+ import { Context } from './Context';
4
+
5
+ interface WriteContextConstructOptions {
6
+ size?: number;
7
+ autoGrow?: boolean;
8
+ littleEndian?: boolean;
9
+ }
10
+
11
+ export class WriteContext extends Context {
12
+ autoGrow: boolean;
13
+
14
+ constructor(p_options?: WriteContextConstructOptions) {
15
+ const buffer = new ArrayBuffer(p_options && p_options.size > 0 ? p_options.size : 128);
16
+ super(buffer, !p_options ? false : !!p_options.littleEndian);
17
+ this.autoGrow = !p_options || (p_options.autoGrow ? !!p_options.autoGrow : true);
18
+ }
19
+
20
+ getBuffer(): Buffer {
21
+ const newBuf = Buffer.from(this.buffer, 0, this.pos);
22
+ return newBuf;
23
+ }
24
+
25
+ sizeLeft(): number {
26
+ return this.buffer.byteLength - this.pos;
27
+ }
28
+
29
+ checkSize(p_size: number): void {
30
+ while (true) {
31
+ const diff = this.sizeLeft() - p_size;
32
+ if (diff >= 0) {
33
+ break;
34
+ }
35
+ if (this.autoGrow) {
36
+ this.resize();
37
+ continue;
38
+ }
39
+ assert.fail(`Writing ${-diff} bytes OOB of fixed size buffer`);
40
+ }
41
+ }
42
+
43
+ resize(): void {
44
+ assert(this.autoGrow);
45
+ const size = this.buffer.byteLength;
46
+ const newBuffer = new ArrayBuffer(size * 2);
47
+ new Uint8Array(newBuffer).set(new Uint8Array(this.buffer));
48
+ this.buffer = newBuffer;
49
+ }
50
+
51
+ write(p_buffer: Uint8Array, p_bytes: number = -1): number {
52
+ if (p_bytes <= 0) {
53
+ p_bytes = p_buffer.byteLength;
54
+ }
55
+
56
+ this.checkSize(p_bytes);
57
+
58
+ new Uint8Array(this.buffer).set(p_buffer, this.pos);
59
+ this.pos += p_bytes;
60
+ return p_bytes;
61
+ }
62
+
63
+ writeFixedSizedString(p_string: string): number {
64
+ for (let i = 0; i < p_string.length; ++i) {
65
+ this.writeUInt8(p_string.charCodeAt(i));
66
+ }
67
+ return p_string.length;
68
+ }
69
+
70
+ writeNetworkStringUTF16(p_string: string): number {
71
+ let written = this.writeUInt32(p_string.length * 2);
72
+ for (let i = 0; i < p_string.length; ++i) {
73
+ written += this.writeUInt16(p_string.charCodeAt(i));
74
+ }
75
+ return written;
76
+ }
77
+
78
+ writeUInt64(p_value: bigint): number {
79
+ this.checkSize(8);
80
+ new DataView(this.buffer).setBigUint64(this.pos, p_value, this.littleEndian);
81
+ this.pos += 8;
82
+ return 8;
83
+ }
84
+
85
+ writeUInt32(p_value: number): number {
86
+ this.checkSize(4);
87
+ new DataView(this.buffer).setUint32(this.pos, p_value, this.littleEndian);
88
+ this.pos += 4;
89
+ return 4;
90
+ }
91
+
92
+ writeUInt16(p_value: number): number {
93
+ this.checkSize(2);
94
+ new DataView(this.buffer).setUint16(this.pos, p_value, this.littleEndian);
95
+ this.pos += 2;
96
+ return 2;
97
+ }
98
+
99
+ writeUInt8(p_value: number): number {
100
+ this.checkSize(1);
101
+ new DataView(this.buffer).setUint8(this.pos, p_value);
102
+ this.pos += 1;
103
+ return 1;
104
+ }
105
+ }
@@ -0,0 +1,23 @@
1
+ import * as fs from 'fs';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+
5
+ /**
6
+ * Recursively create a directory under the OS's temp path.
7
+ *
8
+ * @param p_path Directory to create including filename
9
+ * @returns Absolute path
10
+ */
11
+ export function getTempFilePath(p_path: string) {
12
+ const tmpPath = `/${os.tmpdir()}/localdb/${p_path}`;
13
+ let paths = tmpPath.split(/[/\\]/).filter((e) => e.length > 0);
14
+ const isFolder = p_path.endsWith('/') || p_path.endsWith('\\');
15
+ let filename = '';
16
+ if (isFolder === false) {
17
+ filename = paths[paths.length - 1];
18
+ paths.pop();
19
+ }
20
+ const newPath = paths.join('/');
21
+ fs.mkdirSync(path.resolve('/', newPath), { recursive: true });
22
+ return path.resolve('/', newPath, filename);
23
+ }
package/utils/hex.ts ADDED
@@ -0,0 +1,62 @@
1
+ // Based on https://www.npmjs.com/package/hex
2
+ const zero = function (n: number, max: number) {
3
+ let str = n.toString(16).toUpperCase();
4
+ while (str.length < max) {
5
+ str = '0' + str;
6
+ }
7
+ return str;
8
+ };
9
+
10
+ export function hex(p_buffer: Uint8Array, p_columns: number = 16) {
11
+ const rows = Math.ceil(p_buffer.length / p_columns);
12
+ const last = p_buffer.length % p_columns || p_columns;
13
+ let offsetLength = p_buffer.length.toString(16).length;
14
+ if (offsetLength < 6) offsetLength = 6;
15
+
16
+ let str = 'Offset';
17
+ while (str.length < offsetLength) {
18
+ str += ' ';
19
+ }
20
+
21
+ str = '\u001b[36m' + str + ' ';
22
+
23
+ for (let i = 0; i < p_columns; i++) {
24
+ str += ' ' + zero(i, 2);
25
+ }
26
+
27
+ str += '\u001b[0m';
28
+ if (p_buffer.length) str += '\n';
29
+
30
+ let b = 0;
31
+ let lastBytes: number;
32
+ let lastSpaces: number;
33
+ let v: number;
34
+
35
+ for (let i = 0; i < rows; i++) {
36
+ str += '\u001b[36m' + zero(b, offsetLength) + '\u001b[0m ';
37
+ lastBytes = i === rows - 1 ? last : p_columns;
38
+ lastSpaces = p_columns - lastBytes;
39
+
40
+ for (let j = 0; j < lastBytes; j++) {
41
+ str += ' ' + zero(p_buffer[b], 2);
42
+ b++;
43
+ }
44
+
45
+ for (let j = 0; j < lastSpaces; j++) {
46
+ str += ' ';
47
+ }
48
+
49
+ b -= lastBytes;
50
+ str += ' ';
51
+
52
+ for (let j = 0; j < lastBytes; j++) {
53
+ v = p_buffer[b];
54
+ str += (v > 31 && v < 127) || v > 159 ? String.fromCharCode(v) : '.';
55
+ b++;
56
+ }
57
+
58
+ str += '\n';
59
+ }
60
+
61
+ process.stdout.write(str);
62
+ }
package/utils/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './Context';
2
+ export * from './hex';
3
+ export * from './ReadContext';
4
+ export * from './sleep';
5
+ export * from './tcp';
6
+ export * from './WriteContext';
package/utils/log.ts ADDED
File without changes
package/utils/sleep.ts ADDED
@@ -0,0 +1,3 @@
1
+ export function sleep(p_ms: number) {
2
+ return new Promise((resolve) => setTimeout(resolve, p_ms));
3
+ }
package/utils/tcp.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { Socket as TCPSocket } from 'net';
2
+ import { PromiseSocket } from 'promise-socket';
3
+ import { CONNECT_TIMEOUT } from '../types';
4
+ import { Logger } from '../LogEmitter';
5
+
6
+ export type Connection = PromiseSocket<TCPSocket>;
7
+
8
+ export async function connect(p_ip: string, p_port: number): Promise<Connection> {
9
+ const socket = new TCPSocket();
10
+ socket.setTimeout(CONNECT_TIMEOUT);
11
+ const promiseSocket = new PromiseSocket(socket);
12
+ await promiseSocket.connect(p_port, p_ip).catch((e) => {
13
+ throw new Error(`Failed to connect to '${p_ip}:${p_port}': ${e}`);
14
+ });
15
+ Logger.debug(`TCP connection to '${p_ip}:${p_port}' local port: ${promiseSocket.socket.localPort}`);
16
+ return promiseSocket;
17
+ }