@epicgames-ps/lib-pixelstreamingsignalling-ue5.8 0.1.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 (112) hide show
  1. package/.lintstagedrc.mjs +7 -0
  2. package/.prettierignore +0 -0
  3. package/CHANGELOG.md +21 -0
  4. package/README.md +32 -0
  5. package/dist/cjs/Logger.js +148 -0
  6. package/dist/cjs/Logger.js.map +1 -0
  7. package/dist/cjs/LoggingUtils.js +64 -0
  8. package/dist/cjs/LoggingUtils.js.map +1 -0
  9. package/dist/cjs/PlayerConnection.js +220 -0
  10. package/dist/cjs/PlayerConnection.js.map +1 -0
  11. package/dist/cjs/PlayerRegistry.js +77 -0
  12. package/dist/cjs/PlayerRegistry.js.map +1 -0
  13. package/dist/cjs/SFUConnection.js +264 -0
  14. package/dist/cjs/SFUConnection.js.map +1 -0
  15. package/dist/cjs/SignallingServer.js +149 -0
  16. package/dist/cjs/SignallingServer.js.map +1 -0
  17. package/dist/cjs/StreamerConnection.js +172 -0
  18. package/dist/cjs/StreamerConnection.js.map +1 -0
  19. package/dist/cjs/StreamerRegistry.js +149 -0
  20. package/dist/cjs/StreamerRegistry.js.map +1 -0
  21. package/dist/cjs/Utils.js +19 -0
  22. package/dist/cjs/Utils.js.map +1 -0
  23. package/dist/cjs/WebServer.js +124 -0
  24. package/dist/cjs/WebServer.js.map +1 -0
  25. package/dist/cjs/pixelstreamingsignalling.js +28 -0
  26. package/dist/cjs/pixelstreamingsignalling.js.map +1 -0
  27. package/dist/esm/Logger.js +141 -0
  28. package/dist/esm/Logger.js.map +1 -0
  29. package/dist/esm/LoggingUtils.js +58 -0
  30. package/dist/esm/LoggingUtils.js.map +1 -0
  31. package/dist/esm/PlayerConnection.js +183 -0
  32. package/dist/esm/PlayerConnection.js.map +1 -0
  33. package/dist/esm/PlayerRegistry.js +73 -0
  34. package/dist/esm/PlayerRegistry.js.map +1 -0
  35. package/dist/esm/SFUConnection.js +227 -0
  36. package/dist/esm/SFUConnection.js.map +1 -0
  37. package/dist/esm/SignallingServer.js +112 -0
  38. package/dist/esm/SignallingServer.js.map +1 -0
  39. package/dist/esm/StreamerConnection.js +135 -0
  40. package/dist/esm/StreamerConnection.js.map +1 -0
  41. package/dist/esm/StreamerRegistry.js +145 -0
  42. package/dist/esm/StreamerRegistry.js.map +1 -0
  43. package/dist/esm/Utils.js +15 -0
  44. package/dist/esm/Utils.js.map +1 -0
  45. package/dist/esm/WebServer.js +117 -0
  46. package/dist/esm/WebServer.js.map +1 -0
  47. package/dist/esm/pixelstreamingsignalling.js +12 -0
  48. package/dist/esm/pixelstreamingsignalling.js.map +1 -0
  49. package/dist/types/Logger.d.ts +20 -0
  50. package/dist/types/LoggingUtils.d.ts +44 -0
  51. package/dist/types/PlayerConnection.d.ts +66 -0
  52. package/dist/types/PlayerRegistry.d.ts +66 -0
  53. package/dist/types/SFUConnection.d.ts +85 -0
  54. package/dist/types/SignallingServer.d.ts +48 -0
  55. package/dist/types/StreamerConnection.d.ts +61 -0
  56. package/dist/types/StreamerRegistry.d.ts +96 -0
  57. package/dist/types/Utils.d.ts +8 -0
  58. package/dist/types/WebServer.d.ts +42 -0
  59. package/dist/types/pixelstreamingsignalling.d.ts +9 -0
  60. package/docs/Logger/README.md +19 -0
  61. package/docs/Logger/functions/InitLogging.md +26 -0
  62. package/docs/Logger/interfaces/IConfig.md +41 -0
  63. package/docs/Logger/variables/Logger.md +15 -0
  64. package/docs/LoggingUtils/README.md +19 -0
  65. package/docs/LoggingUtils/functions/createHandlerListener.md +42 -0
  66. package/docs/LoggingUtils/functions/logForward.md +36 -0
  67. package/docs/LoggingUtils/functions/logIncoming.md +30 -0
  68. package/docs/LoggingUtils/functions/logOutgoing.md +30 -0
  69. package/docs/LoggingUtils/interfaces/IMessageLogger.md +29 -0
  70. package/docs/LoggingUtils/interfaces/IProtoLogObj.md +57 -0
  71. package/docs/PlayerConnection/README.md +11 -0
  72. package/docs/PlayerConnection/classes/PlayerConnection.md +177 -0
  73. package/docs/PlayerRegistry/README.md +16 -0
  74. package/docs/PlayerRegistry/classes/PlayerRegistry.md +423 -0
  75. package/docs/PlayerRegistry/interfaces/IPlayer.md +86 -0
  76. package/docs/PlayerRegistry/interfaces/IPlayerInfo.md +43 -0
  77. package/docs/README.md +19 -0
  78. package/docs/SFUConnection/README.md +11 -0
  79. package/docs/SFUConnection/classes/SFUConnection.md +554 -0
  80. package/docs/SignallingServer/README.md +19 -0
  81. package/docs/SignallingServer/classes/SignallingServer.md +76 -0
  82. package/docs/SignallingServer/interfaces/IServerConfig.md +92 -0
  83. package/docs/SignallingServer/type-aliases/ProtocolConfig.md +15 -0
  84. package/docs/StreamerConnection/README.md +11 -0
  85. package/docs/StreamerConnection/classes/StreamerConnection.md +507 -0
  86. package/docs/StreamerRegistry/README.md +16 -0
  87. package/docs/StreamerRegistry/classes/StreamerRegistry.md +431 -0
  88. package/docs/StreamerRegistry/interfaces/IStreamer.md +375 -0
  89. package/docs/StreamerRegistry/interfaces/IStreamerInfo.md +51 -0
  90. package/docs/Utils/README.md +12 -0
  91. package/docs/Utils/functions/beautify.md +23 -0
  92. package/docs/Utils/functions/stringify.md +23 -0
  93. package/docs/WebServer/README.md +15 -0
  94. package/docs/WebServer/classes/WebServer.md +50 -0
  95. package/docs/WebServer/interfaces/IWebServerConfig.md +76 -0
  96. package/docs/pixelstreamingsignalling/README.md +145 -0
  97. package/eslint.config.mjs +39 -0
  98. package/package.json +58 -0
  99. package/src/Logger.ts +189 -0
  100. package/src/LoggingUtils.ts +80 -0
  101. package/src/PlayerConnection.ts +257 -0
  102. package/src/PlayerRegistry.ts +116 -0
  103. package/src/SFUConnection.ts +329 -0
  104. package/src/SignallingServer.ts +214 -0
  105. package/src/StreamerConnection.ts +194 -0
  106. package/src/StreamerRegistry.ts +252 -0
  107. package/src/Utils.ts +16 -0
  108. package/src/WebServer.ts +213 -0
  109. package/src/pixelstreamingsignalling.ts +11 -0
  110. package/tsconfig.cjs.json +8 -0
  111. package/tsconfig.esm.json +8 -0
  112. package/tsconfig.json +29 -0
@@ -0,0 +1,213 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+ import express from 'express';
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ import http from 'http';
6
+ import https from 'https';
7
+ import helmet from 'helmet';
8
+ import cors from 'cors';
9
+ import { Logger } from './Logger';
10
+ import RateLimit from 'express-rate-limit';
11
+
12
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
13
+ const hsts = require('hsts');
14
+
15
+ /**
16
+ * Options for configuring CORS on the Express app. When `enabled` is true the
17
+ * `cors` middleware is registered so that browser-based clients hosted on a
18
+ * different origin (e.g. a custom frontend) can call the REST API or other
19
+ * routes mounted on the app. Use `allowedOrigins` to restrict which origins
20
+ * are accepted; an empty / unset list means "allow all origins" (`*`).
21
+ */
22
+ export interface ICorsConfig {
23
+ // If false (or unset) no CORS headers are added. Defaults to false.
24
+ enabled?: boolean;
25
+
26
+ // List of origins to allow. If empty/unset, all origins are allowed.
27
+ allowedOrigins?: string[];
28
+
29
+ // List of HTTP methods to allow. Defaults to the `cors` package default
30
+ // (`GET,HEAD,PUT,PATCH,POST,DELETE`).
31
+ allowedMethods?: string[];
32
+
33
+ // List of request headers to allow. If unset, the `cors` package mirrors
34
+ // the request's `Access-Control-Request-Headers` header.
35
+ allowedHeaders?: string[];
36
+
37
+ // Whether the request can include credentials (cookies, auth headers).
38
+ // Defaults to false.
39
+ credentials?: boolean;
40
+ }
41
+
42
+ /**
43
+ * An interface that describes the possible options to pass to
44
+ * WebServer.
45
+ */
46
+ export interface IWebServerConfig {
47
+ // The port to run the webserver on. 80 by default.
48
+ httpPort: number;
49
+
50
+ // The root of the serve directory. Current working directory by default.
51
+ root: string;
52
+
53
+ // The filename to direct connections to if none suppllied in the url. player.html by default.
54
+ homepageFile: string;
55
+
56
+ // An optional rate limit to prevent overloading.
57
+ perMinuteRateLimit?: number;
58
+
59
+ // When set an https server will be created
60
+ httpsPort?: number;
61
+
62
+ // The ssl key data for https
63
+ ssl_key?: Buffer;
64
+
65
+ // The ssl cert data for https
66
+ ssl_cert?: Buffer;
67
+
68
+ // If true, connections to http will be redirected to https.
69
+ https_redirect?: boolean;
70
+
71
+ // If true, serve static content from `root` and a homepage handler at `/`.
72
+ // Defaults to false. When false, the HTTP listener still runs (so routes
73
+ // registered by other subsystems, such as a REST API, remain reachable),
74
+ // but no static files are served.
75
+ serveStatic?: boolean;
76
+
77
+ // Optional CORS configuration. When `cors.enabled` is true the cors
78
+ // middleware is registered before the rate limiter and any route handlers,
79
+ // so that all routes mounted on the app respond with CORS headers.
80
+ cors?: ICorsConfig;
81
+ }
82
+
83
+ /**
84
+ * An object to manage the initialization of a web server. Used to serve the
85
+ * pixel streaming frontend.
86
+ */
87
+ export class WebServer {
88
+ httpServer: http.Server | undefined;
89
+ httpsServer: https.Server | undefined;
90
+
91
+ constructor(app: express.Express, config: IWebServerConfig) {
92
+ Logger.debug('Starting WebServer with config: %s', config);
93
+
94
+ // only listen on the http port if we're not using https or if we want to redirect
95
+ if (!config.httpsPort || config.https_redirect) {
96
+ this.httpServer = http.createServer(app);
97
+ this.httpServer.listen(config.httpPort, () => {
98
+ Logger.info(`Http server listening on port ${config.httpPort}`);
99
+ });
100
+ }
101
+
102
+ /* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access */
103
+
104
+ // if using https listen on the given ports and setup some details
105
+ if (config.httpsPort) {
106
+ const options = { key: config.ssl_key, cert: config.ssl_cert };
107
+ this.httpsServer = https.createServer(options, app);
108
+ this.httpsServer.listen(config.httpsPort, () => {
109
+ Logger.info(`Https server listening on port ${config.httpsPort}`);
110
+ });
111
+
112
+ app.use(
113
+ helmet({
114
+ contentSecurityPolicy: {
115
+ directives: {
116
+ 'connect-src': ['*', "'self'"]
117
+ }
118
+ }
119
+ })
120
+ );
121
+
122
+ app.use(
123
+ hsts({
124
+ maxAge: 15552000 // 180 days in seconds
125
+ })
126
+ );
127
+
128
+ // Setup http -> https redirect if requested
129
+ if (config.https_redirect) {
130
+ app.use((req: any, res: any, next: any) => {
131
+ if (!req.secure) {
132
+ if (req.get('Host')) {
133
+ const hostAddressParts: string[] = req.get('Host').split(':') as string[];
134
+ let hostAddress = hostAddressParts[0];
135
+ if (config.httpsPort != 443) {
136
+ hostAddress = `${hostAddress}:${config.httpsPort}`;
137
+ }
138
+
139
+ return res.redirect(['https://', hostAddress, req.originalUrl].join(''));
140
+ } else {
141
+ Logger.error(
142
+ `Unable to get host name from header. Requestor ${req.ip}, url path: '${req.originalUrl}', available headers ${JSON.stringify(req.headers)}`
143
+ );
144
+
145
+ return res.status(400).send('Bad Request');
146
+ }
147
+ }
148
+ next();
149
+ });
150
+ }
151
+ }
152
+
153
+ if (config.cors?.enabled) {
154
+ const corsOptions: cors.CorsOptions = {};
155
+
156
+ if (config.cors.allowedOrigins && config.cors.allowedOrigins.length > 0) {
157
+ corsOptions.origin = config.cors.allowedOrigins;
158
+ }
159
+ if (config.cors.allowedMethods && config.cors.allowedMethods.length > 0) {
160
+ corsOptions.methods = config.cors.allowedMethods;
161
+ }
162
+ if (config.cors.allowedHeaders && config.cors.allowedHeaders.length > 0) {
163
+ corsOptions.allowedHeaders = config.cors.allowedHeaders;
164
+ }
165
+ if (config.cors.credentials) {
166
+ corsOptions.credentials = true;
167
+ }
168
+
169
+ // Register cors before the rate limiter so that preflight (OPTIONS)
170
+ // requests are answered with CORS headers even when an origin is
171
+ // close to the rate limit, and before any route handlers so the
172
+ // homepage, static files, and the REST API all respond uniformly.
173
+ app.use(cors(corsOptions));
174
+
175
+ Logger.info(
176
+ `CORS enabled. Allowed origins: ${corsOptions.origin ? JSON.stringify(corsOptions.origin) : '*'}`
177
+ );
178
+ }
179
+
180
+ const limiter = RateLimit({
181
+ windowMs: 60 * 1000, // 1 minute
182
+ max: config.perMinuteRateLimit ? config.perMinuteRateLimit : 3000
183
+ });
184
+
185
+ // apply rate limiter to all requests. Registered before any route
186
+ // handler so that static files, the homepage route, and any routes
187
+ // registered on `app` by downstream code are all subject to it.
188
+ app.use(limiter);
189
+
190
+ if (config.serveStatic) {
191
+ app.use(express.static(config.root));
192
+
193
+ // Request has been sent to site root, send the homepage file
194
+ app.get('/', function (req: any, res: any) {
195
+ // Try a few paths, see if any resolve to a homepage file the user has set
196
+ const p = path.resolve(path.join(config.root, config.homepageFile));
197
+ if (fs.existsSync(p)) {
198
+ // Send the file for browser to display it
199
+ res.sendFile(p);
200
+ return;
201
+ }
202
+
203
+ // Catch file doesn't exist, and send back 404 if not
204
+ const error = 'Unable to locate file ' + config.homepageFile;
205
+ Logger.error(error);
206
+ res.status(404).send(error);
207
+ return;
208
+ });
209
+ }
210
+
211
+ /* eslint-enable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access */
212
+ }
213
+ }
@@ -0,0 +1,11 @@
1
+ // Copyright Epic Games, Inc. All Rights Reserved.
2
+ export * from './Logger';
3
+ export * from './LoggingUtils';
4
+ export * from './PlayerConnection';
5
+ export * from './PlayerRegistry';
6
+ export * from './SFUConnection';
7
+ export * from './SignallingServer';
8
+ export * from './StreamerConnection';
9
+ export * from './StreamerRegistry';
10
+ export * from './WebServer';
11
+ // keep Utils internal for now
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist/cjs",
5
+ "module": "node16",
6
+ "moduleResolution": "node16"
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist/esm",
5
+ "module": "es6",
6
+ "moduleResolution": "bundler"
7
+ }
8
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "noImplicitAny": true,
4
+ "esModuleInterop": true,
5
+ "target": "ES6",
6
+ "sourceMap": true,
7
+ "allowJs": true,
8
+ "strict": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "noImplicitOverride": true,
11
+ "noFallthroughCasesInSwitch": true,
12
+ "noImplicitReturns": true,
13
+ "noPropertyAccessFromIndexSignature": true,
14
+ "declaration": true,
15
+ "declarationDir": "./dist/types",
16
+ "moduleResolution": "bundler" // helps IDEs
17
+ },
18
+ "include": ["./src/*.ts"],
19
+ "typedocOptions": {
20
+ "entryPoints": ["src/**/*.ts"],
21
+ "out": "docs",
22
+ "excludeExternals": true,
23
+ "excludePrivate": true,
24
+ "excludeInternal": true,
25
+ "cleanOutputDir": false,
26
+ "plugin": "typedoc-plugin-markdown",
27
+ "readme": "none"
28
+ }
29
+ }