@swf2es/desktop 0.1.15 → 0.1.16
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/README.md +44 -11
- package/dist/launch/launch.js +4 -1
- package/dist/launch/launch.js.map +1 -1
- package/dist/main/main.js +66 -8
- package/dist/main/main.js.map +1 -1
- package/dist/main/netlog.d.ts +21 -0
- package/dist/main/netlog.d.ts.map +1 -0
- package/dist/main/netlog.js +90 -0
- package/dist/main/netlog.js.map +1 -0
- package/dist/main/sockets.d.ts +4 -2
- package/dist/main/sockets.d.ts.map +1 -1
- package/dist/main/sockets.js +15 -2
- package/dist/main/sockets.js.map +1 -1
- package/dist/main/websocket-connections.d.ts +62 -0
- package/dist/main/websocket-connections.d.ts.map +1 -0
- package/dist/main/websocket-connections.js +198 -0
- package/dist/main/websocket-connections.js.map +1 -0
- package/dist/main/websockets.d.ts +11 -0
- package/dist/main/websockets.d.ts.map +1 -0
- package/dist/main/websockets.js +93 -0
- package/dist/main/websockets.js.map +1 -0
- package/dist/preload/preload.cjs +20 -0
- package/dist/preload/preload.cjs.map +1 -1
- package/dist/renderer/air.d.ts.map +1 -1
- package/dist/renderer/air.js +1 -0
- package/dist/renderer/air.js.map +1 -1
- package/dist/renderer/full-screen.d.ts +4 -0
- package/dist/renderer/full-screen.d.ts.map +1 -0
- package/dist/renderer/full-screen.js +32 -0
- package/dist/renderer/full-screen.js.map +1 -0
- package/dist/renderer/index.d.ts.map +1 -1
- package/dist/renderer/index.js +4 -0
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/websockets.d.ts +4 -0
- package/dist/renderer/websockets.d.ts.map +1 -0
- package/dist/renderer/websockets.js +36 -0
- package/dist/renderer/websockets.js.map +1 -0
- package/dist/shared/api.d.ts +53 -0
- package/dist/shared/api.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/launch/launch.ts +5 -2
- package/src/main/main.ts +88 -9
- package/src/main/netlog.ts +108 -0
- package/src/main/sockets.ts +17 -1
- package/src/main/websocket-connections.ts +264 -0
- package/src/main/websockets.ts +115 -0
- package/src/preload/preload.cts +23 -0
- package/src/renderer/air.ts +1 -0
- package/src/renderer/full-screen.ts +44 -0
- package/src/renderer/index.ts +4 -0
- package/src/renderer/websockets.ts +43 -0
- package/src/shared/api.ts +40 -0
package/dist/renderer/index.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
import { configure } from "@swf2es/web";
|
|
5
5
|
import { airHosts, airPath } from "./air.js";
|
|
6
6
|
import { shellFiles } from "./files.js";
|
|
7
|
+
import { windowFullScreen } from "./full-screen.js";
|
|
7
8
|
import { shellFetch } from "./network.js";
|
|
8
9
|
import { shellSocketHost } from "./sockets.js";
|
|
10
|
+
import { shellWebSocketHost } from "./websockets.js";
|
|
9
11
|
const desktop = window.swf2esDesktop;
|
|
10
12
|
/** The AIR application playing, whose local URLs are read through the shell; null for a SWF. */
|
|
11
13
|
let airLaunch = null;
|
|
@@ -13,6 +15,7 @@ configure({
|
|
|
13
15
|
cache: true,
|
|
14
16
|
fileHost: shellFiles(desktop.files),
|
|
15
17
|
sockets: shellSocketHost(desktop.sockets),
|
|
18
|
+
webSockets: shellWebSocketHost(desktop.webSockets),
|
|
16
19
|
fetch: shellFetch(desktop.network, () => {
|
|
17
20
|
const launch = airLaunch;
|
|
18
21
|
return launch
|
|
@@ -23,6 +26,7 @@ configure({
|
|
|
23
26
|
: null;
|
|
24
27
|
}),
|
|
25
28
|
loadPolicyFile: (url) => desktop.network.loadPolicyFile(url),
|
|
29
|
+
fullScreen: windowFullScreen(desktop.fullScreen),
|
|
26
30
|
});
|
|
27
31
|
const byId = (id) => document.getElementById(id);
|
|
28
32
|
const player = byId("player");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,4BAA4B;AAC5B,0EAA0E;AAC1E,OAAO,EAAE,SAAS,EAA4B,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websockets.d.ts","sourceRoot":"","sources":["../../src/renderer/websockets.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,iBAAiB,GAAG,aAAa,CAoC/E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function shellWebSocketHost(webSockets) {
|
|
2
|
+
// Until its close, which the shell sends after a failure too.
|
|
3
|
+
const open = new Map();
|
|
4
|
+
webSockets.onEvent((id, event) => {
|
|
5
|
+
const events = open.get(id);
|
|
6
|
+
if (!events) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
switch (event.type) {
|
|
10
|
+
case "open":
|
|
11
|
+
events.open(event.protocol);
|
|
12
|
+
break;
|
|
13
|
+
case "message":
|
|
14
|
+
events.message(event.data);
|
|
15
|
+
break;
|
|
16
|
+
case "error":
|
|
17
|
+
events.error();
|
|
18
|
+
break;
|
|
19
|
+
case "close":
|
|
20
|
+
open.delete(id);
|
|
21
|
+
events.close(event.code);
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
connect(url, protocols, events) {
|
|
27
|
+
const id = webSockets.connect(url, protocols);
|
|
28
|
+
open.set(id, events);
|
|
29
|
+
return {
|
|
30
|
+
send: (data) => webSockets.send(id, data),
|
|
31
|
+
close: (code) => webSockets.close(id, code),
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=websockets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websockets.js","sourceRoot":"","sources":["../../src/renderer/websockets.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,kBAAkB,CAAC,UAA6B;IAC9D,8DAA8D;IAC9D,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;IAChD,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM;gBACT,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM;YACR,KAAK,SAAS;gBACZ,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3B,MAAM;YACR,KAAK,OAAO;gBACV,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzB,MAAM;QACV,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM;YAC5B,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC9C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACrB,OAAO;gBACL,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC;gBACzC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC;aAC5C,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/shared/api.d.ts
CHANGED
|
@@ -50,6 +50,23 @@ export interface AirWindowState {
|
|
|
50
50
|
active: boolean;
|
|
51
51
|
visible: boolean;
|
|
52
52
|
}
|
|
53
|
+
/** One of the system's displays as flash.display.Screen reads it: all of it, and what a window may fill. */
|
|
54
|
+
export interface AirScreenState {
|
|
55
|
+
bounds: {
|
|
56
|
+
x: number;
|
|
57
|
+
y: number;
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
};
|
|
61
|
+
visibleBounds: {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
width: number;
|
|
65
|
+
height: number;
|
|
66
|
+
};
|
|
67
|
+
colorDepth: number;
|
|
68
|
+
main: boolean;
|
|
69
|
+
}
|
|
53
70
|
/**
|
|
54
71
|
* An AIR application's own reach, only while one the user opened plays:
|
|
55
72
|
* the file system, read and written synchronously as File does, and the
|
|
@@ -72,6 +89,8 @@ export interface DesktopAir {
|
|
|
72
89
|
remove(path: string): boolean;
|
|
73
90
|
move(from: string, to: string): boolean;
|
|
74
91
|
window(): AirWindowState;
|
|
92
|
+
/** The displays as they are now; none where no application plays. */
|
|
93
|
+
screens(): AirScreenState[];
|
|
75
94
|
setBounds(bounds: {
|
|
76
95
|
x: number;
|
|
77
96
|
y: number;
|
|
@@ -136,6 +155,28 @@ export interface DesktopSockets {
|
|
|
136
155
|
close(id: number): void;
|
|
137
156
|
onEvent(listener: (id: number, event: SocketEvent) => void): void;
|
|
138
157
|
}
|
|
158
|
+
/** What befalls a WebSocket, as player's WebSocketEvents has it. */
|
|
159
|
+
export type WebSocketEvent = {
|
|
160
|
+
type: "open";
|
|
161
|
+
protocol: string;
|
|
162
|
+
} | {
|
|
163
|
+
type: "message";
|
|
164
|
+
data: string | Uint8Array;
|
|
165
|
+
} | {
|
|
166
|
+
type: "close";
|
|
167
|
+
code: number;
|
|
168
|
+
} | {
|
|
169
|
+
type: "error";
|
|
170
|
+
};
|
|
171
|
+
/** air.net.WebSocket's connections, opened by the shell, for an AIR application alone. */
|
|
172
|
+
export interface DesktopWebSockets {
|
|
173
|
+
/** A connection's id; its events follow, an "error" then a "close" if the shell refuses it. */
|
|
174
|
+
connect(url: string, protocols: string[]): number;
|
|
175
|
+
/** A text message for a string, a binary one for bytes. */
|
|
176
|
+
send(id: number, data: string | Uint8Array): void;
|
|
177
|
+
close(id: number, code?: number): void;
|
|
178
|
+
onEvent(listener: (id: number, event: WebSocketEvent) => void): void;
|
|
179
|
+
}
|
|
139
180
|
/** A request of a SWF's, as player's FetchRequest has it. */
|
|
140
181
|
export interface NetworkRequest {
|
|
141
182
|
url: string;
|
|
@@ -182,8 +223,19 @@ export interface DesktopFiles {
|
|
|
182
223
|
write(id: number, bytes: Uint8Array): Promise<void>;
|
|
183
224
|
release(id: number): void;
|
|
184
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* The window's full screen, which a SWF's Stage.displayState asks for
|
|
228
|
+
* while one the user opened plays, with no gesture, as AIR's and the
|
|
229
|
+
* projector's did.
|
|
230
|
+
*/
|
|
231
|
+
export interface DesktopFullScreen {
|
|
232
|
+
set(fullScreen: boolean): void;
|
|
233
|
+
/** The window has entered or left full screen, a SWF's doing or the user's (F11). */
|
|
234
|
+
onChange(listener: (fullScreen: boolean) => void): void;
|
|
235
|
+
}
|
|
185
236
|
export interface DesktopApi {
|
|
186
237
|
files: DesktopFiles;
|
|
238
|
+
fullScreen: DesktopFullScreen;
|
|
187
239
|
/** The page has loaded and listens: what it is to show. */
|
|
188
240
|
start(): Promise<StartState>;
|
|
189
241
|
/** The shell opened a SWF: play it in place of what plays. */
|
|
@@ -199,6 +251,7 @@ export interface DesktopApi {
|
|
|
199
251
|
/** Ask the user for a library; the page reloads once the shell has it. */
|
|
200
252
|
chooseLibrary(name: LibraryName): void;
|
|
201
253
|
sockets: DesktopSockets;
|
|
254
|
+
webSockets: DesktopWebSockets;
|
|
202
255
|
network: DesktopNetwork;
|
|
203
256
|
air: DesktopAir;
|
|
204
257
|
}
|
package/dist/shared/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/shared/api.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/shared/api.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swf2es/desktop",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "swf2es's desktop app: local and remote SWFs, and AIR applications, in an Electron window",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"swf",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"electron": "44.10.2",
|
|
38
|
-
"@swf2es/
|
|
39
|
-
"@swf2es/format": "0.1.
|
|
40
|
-
"@swf2es/
|
|
41
|
-
"@swf2es/player": "0.1.
|
|
42
|
-
"@swf2es/
|
|
43
|
-
"@swf2es/
|
|
38
|
+
"@swf2es/context3d": "0.1.16",
|
|
39
|
+
"@swf2es/format": "0.1.16",
|
|
40
|
+
"@swf2es/codegen": "0.1.16",
|
|
41
|
+
"@swf2es/player": "0.1.16",
|
|
42
|
+
"@swf2es/web": "0.1.16",
|
|
43
|
+
"@swf2es/player-hosts": "0.1.16"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"fetch-electron": "node node_modules/electron/install.js",
|
package/src/launch/launch.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// swf2es-desktop command of the package npm installs, and a checkout's
|
|
4
4
|
// `start`.
|
|
5
5
|
//
|
|
6
|
-
// npx @swf2es/desktop [--trace] [file.swf | https://host/movie.swf]
|
|
6
|
+
// npx @swf2es/desktop [--trace] [--log-network] [file.swf | https://host/movie.swf]
|
|
7
7
|
// npx @swf2es/desktop [--trace] app.xml [root-dir] [-- arguments...]
|
|
8
8
|
// pnpm --filter @swf2es/desktop start ... the same, in a checkout
|
|
9
9
|
//
|
|
@@ -64,7 +64,10 @@ if (!build || appRoot.includes(`${join("node_modules", "@swf2es")}`)) {
|
|
|
64
64
|
build = JSON.parse(readFileSync(join(appRoot, "package.json"), "utf8")).version;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const env = { ...process.env, SWF2ES_DESKTOP_BUILD: build };
|
|
67
|
+
const env: NodeJS.ProcessEnv = { ...process.env, SWF2ES_DESKTOP_BUILD: build };
|
|
68
|
+
// Set by tools that are Electron apps themselves, an editor's terminals and tasks among them,
|
|
69
|
+
// for the node they run: here it would make Electron run the app's main module as plain node.
|
|
70
|
+
delete env.ELECTRON_RUN_AS_NODE;
|
|
68
71
|
const child = spawn(electronBinary() as string, [appRoot, ...args], { stdio: "inherit", env });
|
|
69
72
|
child.on("exit", (code, signal) => process.exit(signal ? 1 : (code ?? 0)));
|
|
70
73
|
for (const signal of ["SIGINT", "SIGTERM"] as const) {
|
package/src/main/main.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// electron apps/desktop [--trace] [file.swf | http(s)://host/movie.swf]
|
|
6
6
|
// electron apps/desktop [--trace] app.xml [root-dir] [-- arguments...]
|
|
7
7
|
//
|
|
8
|
-
// --ignore-certificate-errors[=host,...] leaves HTTPS certificates unchecked.
|
|
8
|
+
// --ignore-certificate-errors[=host,...] leaves HTTPS and WSS certificates unchecked.
|
|
9
9
|
//
|
|
10
10
|
// The second runs an AIR application by its descriptor, as adl does.
|
|
11
11
|
import { statSync } from "node:fs";
|
|
@@ -23,11 +23,13 @@ import {
|
|
|
23
23
|
Menu,
|
|
24
24
|
type MenuItemConstructorOptions,
|
|
25
25
|
safeStorage,
|
|
26
|
+
screen,
|
|
26
27
|
session,
|
|
27
28
|
shell,
|
|
28
29
|
type WebContents,
|
|
29
30
|
} from "electron";
|
|
30
31
|
import type {
|
|
32
|
+
AirScreenState,
|
|
31
33
|
AirWindowState,
|
|
32
34
|
LibraryName,
|
|
33
35
|
NetworkResponse,
|
|
@@ -48,11 +50,14 @@ import {
|
|
|
48
50
|
writeOf,
|
|
49
51
|
} from "./air.ts";
|
|
50
52
|
import { bridgeFiles } from "./files.ts";
|
|
53
|
+
import { failureLine, requestLine } from "./netlog.ts";
|
|
51
54
|
import { type Movie, Network, Refused, unverifiedHosts } from "./network.ts";
|
|
52
55
|
import { APP_ORIGIN, registerScheme, serve } from "./protocol.ts";
|
|
53
56
|
import { Sandbox } from "./sandbox.ts";
|
|
54
57
|
import { SettingsFile } from "./settings.ts";
|
|
55
58
|
import { bridgeSockets } from "./sockets.ts";
|
|
59
|
+
import { hasWebSocket, unverifiedDispatcher, webSocketOpener } from "./websocket-connections.ts";
|
|
60
|
+
import { bridgeWebSockets } from "./websockets.ts";
|
|
56
61
|
|
|
57
62
|
const preload = fileURLToPath(new URL("../preload/preload.cjs", import.meta.url));
|
|
58
63
|
const promptPreload = fileURLToPath(new URL("../preload/prompt.cjs", import.meta.url));
|
|
@@ -77,6 +82,11 @@ app.enableSandbox();
|
|
|
77
82
|
|
|
78
83
|
/** --trace: what the page logs, a SWF's trace() among it, goes to the terminal. */
|
|
79
84
|
const trace = process.argv.includes("--trace");
|
|
85
|
+
// Each request and socket of the SWF's said on stderr: the page's DevTools show none of them.
|
|
86
|
+
// --log-sockets says what each socket sends and receives as well, and so the rest too.
|
|
87
|
+
const logSockets = process.argv.includes("--log-sockets");
|
|
88
|
+
const logNetwork = logSockets || process.argv.includes("--log-network");
|
|
89
|
+
const netLog = logNetwork ? (line: string) => process.stderr.write(`${line}\n`) : null;
|
|
80
90
|
const sandbox = new Sandbox();
|
|
81
91
|
/** The SWF's http and https requests, judged as Flash's sandboxes had them. */
|
|
82
92
|
/**
|
|
@@ -89,15 +99,23 @@ const unverified = unverifiedHosts(process.argv.slice(1));
|
|
|
89
99
|
if (unverified) {
|
|
90
100
|
process.stderr.write(
|
|
91
101
|
unverified.all
|
|
92
|
-
? "swf2es: --ignore-certificate-errors: no HTTPS server's certificate is verified\n"
|
|
102
|
+
? "swf2es: --ignore-certificate-errors: no HTTPS or WSS server's certificate is verified\n"
|
|
93
103
|
: `swf2es: --ignore-certificate-errors: certificates are not verified for ${unverified.hosts.join(", ") || "no host"}\n`,
|
|
94
104
|
);
|
|
95
105
|
}
|
|
96
106
|
|
|
97
|
-
const
|
|
98
|
-
unverified
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
const unverifiedHost = (host: string) =>
|
|
108
|
+
!!unverified && (unverified.all || unverified.hosts.includes(host.toLowerCase()));
|
|
109
|
+
const network = new Network({ unverified: unverifiedHost });
|
|
110
|
+
// What opens an AIR application's WebSockets: the global's client, a wss: server's certificate
|
|
111
|
+
// unchecked where the switch names its host.
|
|
112
|
+
const insecureWebSockets = unverified ? unverifiedDispatcher() : null;
|
|
113
|
+
if (unverified && !insecureWebSockets) {
|
|
114
|
+
process.stderr.write(
|
|
115
|
+
"swf2es: --ignore-certificate-errors: a WebSocket's certificate is verified all the same\n",
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
101
119
|
/** What the page's requests under way abort with, by the preload's number. */
|
|
102
120
|
const requests = new Map<number, AbortController>();
|
|
103
121
|
let settings: SettingsFile;
|
|
@@ -560,6 +578,23 @@ async function askForSocket(name: string, swf: string, endpoint: string): Promis
|
|
|
560
578
|
}
|
|
561
579
|
}
|
|
562
580
|
|
|
581
|
+
/**
|
|
582
|
+
* Whether what plays may open a WebSocket to `url`: an AIR application,
|
|
583
|
+
* unasked and anywhere, as AIR's application sandbox connects and as its
|
|
584
|
+
* sockets do here. air.net.WebSocket is AIR's alone, so nothing else has one.
|
|
585
|
+
*/
|
|
586
|
+
function permitWebSocket(url: string): boolean {
|
|
587
|
+
if (sandbox.application && hasWebSocket()) {
|
|
588
|
+
return true;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const why = sandbox.application
|
|
592
|
+
? "this Electron has no WebSocket client"
|
|
593
|
+
: "only an AIR application has one";
|
|
594
|
+
process.stderr.write(`swf2es: no WebSocket to ${url.slice(0, 2048)}: ${why}\n`);
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
|
|
563
598
|
async function showOpenDialog(): Promise<void> {
|
|
564
599
|
if (!window) {
|
|
565
600
|
return;
|
|
@@ -800,6 +835,9 @@ function createWindow(): void {
|
|
|
800
835
|
window.on("closed", () => {
|
|
801
836
|
window = null;
|
|
802
837
|
});
|
|
838
|
+
// The page hears of full screen however it came, a SWF's Stage.displayState or the menu's F11.
|
|
839
|
+
window.on("enter-full-screen", () => window?.webContents.send("desktop:full-screen", true));
|
|
840
|
+
window.on("leave-full-screen", () => window?.webContents.send("desktop:full-screen", false));
|
|
803
841
|
guard(window.webContents);
|
|
804
842
|
void window.loadURL(`${APP_ORIGIN}/`);
|
|
805
843
|
}
|
|
@@ -831,6 +869,12 @@ function listen(): void {
|
|
|
831
869
|
build,
|
|
832
870
|
};
|
|
833
871
|
});
|
|
872
|
+
// Stage.displayState of a SWF the user opened: the window's full screen, asked with no gesture.
|
|
873
|
+
ipcMain.on("desktop:full-screen", (event, fullScreen: unknown) => {
|
|
874
|
+
if (trusted(event) && current && window) {
|
|
875
|
+
window.setFullScreen(fullScreen === true);
|
|
876
|
+
}
|
|
877
|
+
});
|
|
834
878
|
ipcMain.on("desktop:open-dialog", (event) => {
|
|
835
879
|
if (trusted(event)) {
|
|
836
880
|
void showOpenDialog();
|
|
@@ -869,7 +913,14 @@ function listen(): void {
|
|
|
869
913
|
void chooseLibrary(name);
|
|
870
914
|
}
|
|
871
915
|
});
|
|
872
|
-
bridgeSockets(trusted, permitSocket);
|
|
916
|
+
bridgeSockets(trusted, permitSocket, netLog, logSockets);
|
|
917
|
+
bridgeWebSockets(
|
|
918
|
+
trusted,
|
|
919
|
+
permitWebSocket,
|
|
920
|
+
insecureWebSockets ? webSocketOpener(unverifiedHost, insecureWebSockets) : undefined,
|
|
921
|
+
netLog,
|
|
922
|
+
logSockets,
|
|
923
|
+
);
|
|
873
924
|
ipcMain.handle("net:fetch", (event, id: unknown, request: unknown) => {
|
|
874
925
|
if (!trusted(event) || typeof id !== "number") {
|
|
875
926
|
throw new Error("not the app's page");
|
|
@@ -917,6 +968,17 @@ function windowState(w: BrowserWindow): AirWindowState {
|
|
|
917
968
|
};
|
|
918
969
|
}
|
|
919
970
|
|
|
971
|
+
/** The displays as an AIR application's Screen reads them: the work area is past the system's bars. */
|
|
972
|
+
function screenStates(): AirScreenState[] {
|
|
973
|
+
const primary = screen.getPrimaryDisplay().id;
|
|
974
|
+
return screen.getAllDisplays().map((display) => ({
|
|
975
|
+
bounds: display.bounds,
|
|
976
|
+
visibleBounds: display.workArea,
|
|
977
|
+
colorDepth: display.colorDepth,
|
|
978
|
+
main: display.id === primary,
|
|
979
|
+
}));
|
|
980
|
+
}
|
|
981
|
+
|
|
920
982
|
/**
|
|
921
983
|
* An AIR application's reach, shared/api.ts DesktopAir: the file system
|
|
922
984
|
* and the window, only while one the user opened plays and only for its
|
|
@@ -999,6 +1061,9 @@ function listenForAir(): void {
|
|
|
999
1061
|
ipcMain.on("air:window", (event) => {
|
|
1000
1062
|
event.returnValue = playing(event) && window ? windowState(window) : null;
|
|
1001
1063
|
});
|
|
1064
|
+
ipcMain.on("air:screens", (event) => {
|
|
1065
|
+
event.returnValue = playing(event) ? screenStates() : [];
|
|
1066
|
+
});
|
|
1002
1067
|
ipcMain.on("air:set-bounds", (event, bounds: unknown) => {
|
|
1003
1068
|
const b = bounds as { x?: unknown; y?: unknown; width?: unknown; height?: unknown } | null;
|
|
1004
1069
|
const n = (v: unknown) => (typeof v === "number" && Number.isFinite(v) ? Math.round(v) : null);
|
|
@@ -1068,7 +1133,7 @@ async function fetchForPage(
|
|
|
1068
1133
|
request: unknown,
|
|
1069
1134
|
deliver: (response: NetworkResponse) => void,
|
|
1070
1135
|
): Promise<NetworkResponse> {
|
|
1071
|
-
const asked = request as { url?: unknown; purpose?: unknown } | null;
|
|
1136
|
+
const asked = request as { url?: unknown; purpose?: unknown; method?: unknown } | null;
|
|
1072
1137
|
const url = typeof asked?.url === "string" ? asked.url : "";
|
|
1073
1138
|
const shown = url.slice(0, 2048);
|
|
1074
1139
|
const movie = asked?.purpose === "movie" && sandbox.startRemote(url);
|
|
@@ -1079,13 +1144,27 @@ async function fetchForPage(
|
|
|
1079
1144
|
|
|
1080
1145
|
const controller = new AbortController();
|
|
1081
1146
|
requests.set(id, controller);
|
|
1147
|
+
const started = performance.now();
|
|
1148
|
+
const method = typeof asked?.method === "string" ? asked.method.slice(0, 16) : "GET";
|
|
1082
1149
|
try {
|
|
1083
|
-
|
|
1150
|
+
const response = await network.fetch(request, controller.signal, deliver);
|
|
1151
|
+
netLog?.(
|
|
1152
|
+
requestLine(
|
|
1153
|
+
method,
|
|
1154
|
+
url,
|
|
1155
|
+
response.status,
|
|
1156
|
+
response.bytes?.length ?? null,
|
|
1157
|
+
performance.now() - started,
|
|
1158
|
+
),
|
|
1159
|
+
);
|
|
1160
|
+
return response;
|
|
1084
1161
|
} catch (error) {
|
|
1085
1162
|
// A refusal says why; anything else, which should not happen, is said too.
|
|
1086
1163
|
if (!controller.signal.aborted) {
|
|
1087
1164
|
const why = error instanceof Refused ? error.message : `failed: ${error}`;
|
|
1088
1165
|
process.stderr.write(`swf2es: not loading ${shown}: ${why}\n`);
|
|
1166
|
+
} else {
|
|
1167
|
+
netLog?.(failureLine(method, url, "aborted", performance.now() - started));
|
|
1089
1168
|
}
|
|
1090
1169
|
|
|
1091
1170
|
throw error;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// --log-network's lines: what a SWF asked of the network, as the terminal
|
|
2
|
+
// shows it. The page has no network of its own, so its DevTools' Network
|
|
3
|
+
// tab shows none of this; the main process, which sends the requests, says
|
|
4
|
+
// them here instead. Apart from Electron, so that node tests it.
|
|
5
|
+
|
|
6
|
+
/** A size as a person reads it: bytes, then kB and MB to one decimal. */
|
|
7
|
+
function size(bytes: number): string {
|
|
8
|
+
if (bytes < 1024) {
|
|
9
|
+
return `${bytes} B`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return bytes < 1024 * 1024
|
|
13
|
+
? `${(bytes / 1024).toFixed(1)} kB`
|
|
14
|
+
: `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A URL short enough for a line, and with nothing a terminal would act on. */
|
|
18
|
+
function shown(url: string): string {
|
|
19
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is taken out
|
|
20
|
+
return url.slice(0, 2048).replace(/[\u0000-\u001f\u007f]/g, "?");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** A request answered: its method, URL, status, body's size and how long it took. */
|
|
24
|
+
export function requestLine(
|
|
25
|
+
method: string,
|
|
26
|
+
url: string,
|
|
27
|
+
status: number,
|
|
28
|
+
bytes: number | null,
|
|
29
|
+
ms: number,
|
|
30
|
+
): string {
|
|
31
|
+
const body = bytes === null ? "no body" : size(bytes);
|
|
32
|
+
return `swf2es: net ${method} ${shown(url)} ${status} ${body} ${Math.round(ms)} ms`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A request that got no answer: refused, failed or aborted, and why. */
|
|
36
|
+
export function failureLine(method: string, url: string, why: string, ms: number): string {
|
|
37
|
+
return `swf2es: net ${method} ${shown(url)} ${why} ${Math.round(ms)} ms`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** A socket's connection asked for, opened, refused or closed. */
|
|
41
|
+
export function socketLine(id: number, what: string): string {
|
|
42
|
+
return `swf2es: socket #${id} ${shown(what)}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** How much of a message --log-sockets shows. */
|
|
46
|
+
const PREVIEW = 512;
|
|
47
|
+
|
|
48
|
+
/** The start of `bytes`: as text where it is text, bytes that are no printable ASCII as dots, else in hex. */
|
|
49
|
+
function preview(bytes: Uint8Array): string {
|
|
50
|
+
const shownBytes = bytes.subarray(0, PREVIEW);
|
|
51
|
+
let printable = 0;
|
|
52
|
+
for (let i = 0; i < shownBytes.length; i++) {
|
|
53
|
+
const b = shownBytes[i];
|
|
54
|
+
if ((b >= 32 && b < 127) || b === 9 || b === 10 || b === 13 || b === 0) {
|
|
55
|
+
printable++;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let text = "";
|
|
60
|
+
// Mostly text, as a line protocol's messages are, a NUL ending each: shown as text.
|
|
61
|
+
if (printable * 10 >= shownBytes.length * 9) {
|
|
62
|
+
for (let i = 0; i < shownBytes.length; i++) {
|
|
63
|
+
const b = shownBytes[i];
|
|
64
|
+
text += b >= 32 && b < 127 ? String.fromCharCode(b) : ".";
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
for (let i = 0; i < shownBytes.length; i++) {
|
|
68
|
+
text += (i > 0 ? " " : "") + shownBytes[i].toString(16).padStart(2, "0");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return text + (bytes.length > PREVIEW ? "…" : "");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* What a socket sent (">") or received ("<"): its size and its start, as
|
|
77
|
+
* text where it is text, bytes that are no printable ASCII as dots, else
|
|
78
|
+
* in hex. A message past PREVIEW bytes ends in an ellipsis.
|
|
79
|
+
*/
|
|
80
|
+
export function socketDataLine(id: number, sent: boolean, bytes: Uint8Array): string {
|
|
81
|
+
return `swf2es: socket #${id} ${sent ? ">" : "<"} ${bytes.length} B ${preview(bytes)}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** A WebSocket's connection asked for, opened, refused, failed or closed. */
|
|
85
|
+
export function webSocketLine(id: number, what: string): string {
|
|
86
|
+
return `swf2es: websocket #${id} ${shown(what)}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* What a WebSocket sent (">") or received ("<"): a text message's size
|
|
91
|
+
* in UTF-8 and its first PREVIEW characters, control characters as dots;
|
|
92
|
+
* a binary one's as a socket's.
|
|
93
|
+
*/
|
|
94
|
+
export function webSocketDataLine(id: number, sent: boolean, data: string | Uint8Array): string {
|
|
95
|
+
const head = `swf2es: websocket #${id} ${sent ? ">" : "<"}`;
|
|
96
|
+
if (typeof data !== "string") {
|
|
97
|
+
return `${head} binary ${data.length} B ${preview(data)}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// By code point, so that no pair is cut in two.
|
|
101
|
+
const characters = Array.from(data.slice(0, PREVIEW * 2)).slice(0, PREVIEW);
|
|
102
|
+
const text = characters
|
|
103
|
+
.join("")
|
|
104
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are what is taken out
|
|
105
|
+
.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g, ".");
|
|
106
|
+
const more = text.length < data.length ? "…" : "";
|
|
107
|
+
return `${head} text ${Buffer.byteLength(data)} B ${text}${more}`;
|
|
108
|
+
}
|
package/src/main/sockets.ts
CHANGED
|
@@ -3,15 +3,20 @@
|
|
|
3
3
|
// connections (connections.ts) close as it navigates, reloads or goes.
|
|
4
4
|
import { type IpcMainEvent, ipcMain, type WebContents } from "electron";
|
|
5
5
|
import { Connections, validEndpoint } from "./connections.ts";
|
|
6
|
+
import { socketDataLine, socketLine } from "./netlog.ts";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Carry socket messages from pages that `trusted` accepts, each connection
|
|
9
10
|
* made only as `permit` allows it, to the address it gives where it gives
|
|
10
|
-
* one; null refuses it.
|
|
11
|
+
* one; null refuses it. `log`, where given, is told each connection asked
|
|
12
|
+
* for, opened, refused, failed and closed (--log-network), and with
|
|
13
|
+
* `data` what each sends and receives too (--log-sockets).
|
|
11
14
|
*/
|
|
12
15
|
export function bridgeSockets(
|
|
13
16
|
trusted: (event: IpcMainEvent) => boolean,
|
|
14
17
|
permit: (host: string, port: number) => Promise<{ address?: string } | null>,
|
|
18
|
+
log: ((line: string) => void) | null = null,
|
|
19
|
+
data = false,
|
|
15
20
|
): void {
|
|
16
21
|
const pages = new Map<WebContents, Connections>();
|
|
17
22
|
|
|
@@ -22,6 +27,12 @@ export function bridgeSockets(
|
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
const connections = new Connections((id, event) => {
|
|
30
|
+
if (log && event.type !== "data") {
|
|
31
|
+
log(socketLine(id, event.type === "error" ? `error: ${event.message}` : event.type));
|
|
32
|
+
} else if (log && data && event.type === "data") {
|
|
33
|
+
log(socketDataLine(id, false, event.bytes));
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
if (!contents.isDestroyed()) {
|
|
26
37
|
contents.send("socket:event", id, event);
|
|
27
38
|
}
|
|
@@ -59,6 +70,7 @@ export function bridgeSockets(
|
|
|
59
70
|
return;
|
|
60
71
|
}
|
|
61
72
|
|
|
73
|
+
log?.(socketLine(id, `${allowed ? "connecting to" : "refused"} ${host}:${port}`));
|
|
62
74
|
if (allowed) {
|
|
63
75
|
connections.connect(id, host, port, allowed.address);
|
|
64
76
|
} else {
|
|
@@ -69,6 +81,10 @@ export function bridgeSockets(
|
|
|
69
81
|
|
|
70
82
|
ipcMain.on("socket:send", (event, id: unknown, bytes: unknown) => {
|
|
71
83
|
if (trusted(event) && typeof id === "number" && bytes instanceof Uint8Array) {
|
|
84
|
+
if (log && data) {
|
|
85
|
+
log(socketDataLine(id, true, bytes));
|
|
86
|
+
}
|
|
87
|
+
|
|
72
88
|
pages.get(event.sender)?.send(id, bytes);
|
|
73
89
|
}
|
|
74
90
|
});
|