@awayfl/awayfl-player 0.2.36 → 0.2.38

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 (39) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +36 -36
  3. package/awayfl.config.js +85 -85
  4. package/builtins/playerglobal.json +2752 -2752
  5. package/builtins/playerglobal_new.json +4169 -4169
  6. package/bundle/awayfl-player.umd.js +30 -161
  7. package/bundle/awayfl-player.umd.js.gz +0 -0
  8. package/bundle/awayfl-player.umd.js.map +1 -1
  9. package/dist/index.d.ts +8 -8
  10. package/dist/index.js +9 -9
  11. package/dist/lib/AVM1Player.d.ts +4 -4
  12. package/dist/lib/AVM1Player.js +13 -13
  13. package/dist/lib/AVM2Player.d.ts +4 -4
  14. package/dist/lib/AVM2Player.js +14 -14
  15. package/dist/lib/AVMDebugInterface.d.ts +21 -21
  16. package/dist/lib/AVMDebugInterface.js +279 -279
  17. package/dist/lib/AVMPlayer.d.ts +6 -6
  18. package/dist/lib/AVMPlayer.js +27 -27
  19. package/dist/src/Main.d.ts +1 -1
  20. package/dist/src/Main.js +19 -19
  21. package/index.ts +9 -9
  22. package/lib/AVM1Player.ts +9 -9
  23. package/lib/AVM2Player.ts +12 -12
  24. package/lib/AVMDebugInterface.ts +345 -345
  25. package/lib/AVMPlayer.ts +29 -29
  26. package/package.json +97 -97
  27. package/rollup.config.js +30 -30
  28. package/scripts/copyVersionToIndex.js +33 -33
  29. package/scripts/initAwayDev_mac.sh +177 -177
  30. package/scripts/initAwayDev_mac_pnpm.sh +177 -177
  31. package/scripts/initAwayDev_win.bat +198 -198
  32. package/scripts/unlinkAwayDev_mac.sh +140 -140
  33. package/scripts/unlinkAwayDev_mac_pnpm.sh +140 -140
  34. package/scripts/unlinkAwayDev_win.bat +140 -140
  35. package/scripts/updateAwayDev_mac.sh +86 -90
  36. package/scripts/updateAwayDev_win.bat +69 -69
  37. package/scripts/updateAway_any.bat +73 -73
  38. package/tsconfig.json +12 -12
  39. package/webpack.config.js +496 -450
package/webpack.config.js CHANGED
@@ -1,450 +1,496 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const webpack = require('webpack');
4
- const CopyWebPackPlugin = require('copy-webpack-plugin');
5
- const HTMLWebPackPlugin = require('html-webpack-plugin');
6
- const Terser = require('terser-webpack-plugin')
7
- const rimraf = require("rimraf");
8
- const tsloader = require.resolve('ts-loader');
9
- const merge = require("webpack-merge").merge;
10
- const config = require('./awayfl.config.js')
11
-
12
- module.exports = (env = {}) => {
13
-
14
- var isProd = !!env.prod;
15
-
16
- // force some configs dependant on prod and dev
17
- config.rt_debug = isProd ? false : config.rt_debug;
18
-
19
- config.rt_showFPS = isProd ? false : config.rt_showFPS;
20
-
21
- config.cacheBuster = isProd ? false : config.cacheBuster;
22
-
23
- config.allowURLSearchParams = isProd ? false : config.allowURLSearchParams;
24
-
25
- // split mode right now errors in watch mode
26
- config.split = isProd ? config.split : false;
27
-
28
- if (config.debugConfig) {
29
- console.log("global config used for webpack:");
30
- for (var key in config) {
31
- console.log(" - config." + key, config[key]);
32
- }
33
- }
34
-
35
- const entry = {};
36
- entry[config.entryName] = [config.entryPath];
37
-
38
- let plugins = processConfig(config, __dirname, CopyWebPackPlugin, HTMLWebPackPlugin, webpack.BannerPlugin, fs, rimraf, path);
39
-
40
- const common = {
41
-
42
- entry: entry,
43
-
44
- output: {
45
- pathinfo: false,
46
- path: path.join(__dirname, "bin"),
47
- filename: 'js/[name].js'
48
- },
49
- resolve: {
50
- // Add `.ts` and `.tsx` as a resolvable extension.
51
- extensions: ['.webpack.js', '.web.js', '.js', '.ts', '.tsx']
52
- },
53
- module: {
54
- rules: [
55
- // all files with a `.ts` or `.tsx` extension will be handled by `awesome-typescript-loader`
56
- { test: /\.ts(x?)/, exclude: /node_modules/, loader: tsloader, options: { experimentalWatchApi: true} },
57
-
58
- // all files with a `.js` or `.jsx` extension will be handled by `source-map-loader`
59
- //{ test: /\.js(x?)/, loader: require.resolve('source-map-loader') }
60
- ]
61
- },
62
- plugins: plugins,
63
-
64
- performance: {
65
- hints: false // wp4
66
- },
67
- stats: {
68
- cached: true, // wp4
69
- errorDetails: true, // wp4
70
- colors: true // wp4
71
- },
72
- devServer: {
73
- client: {
74
- progress: true,
75
- }
76
- },
77
-
78
-
79
- }
80
-
81
- const dev = {
82
- mode: "development",// wp4
83
- devtool: 'source-map',
84
- //devtool: 'cheap-module-eval-source-map',//use this option for recompiling libs
85
- devServer: {
86
- //contentBase: path.join(process.cwd(), "src"),
87
- static: {
88
- publicPath: "/",
89
- },
90
- open: false,
91
- client: {
92
- progress: true,
93
- }
94
- },
95
- optimization: {
96
- //minimize: false // wp4
97
- }
98
- }
99
-
100
- const prod = {
101
- mode: "production",// wp4
102
- bail: true
103
- };
104
-
105
- if(Terser) {
106
- prod.optimization = {
107
- minimize: true,
108
- minimizer: [
109
- new Terser({
110
- extractComments: {
111
- condition: /^\**!|@preserve|@license|@cc_on/i,
112
- filename: 'LICENSES.txt'
113
- },
114
- }),
115
- ],
116
- }
117
- } else {
118
- console.warn("TERSER IS REQUIRE FOR REMOVING COMMENTS!");
119
- }
120
-
121
- return merge(common, isProd ? prod : dev);
122
-
123
- }
124
-
125
- // process config
126
- // return a list of webpack-plugins
127
- const processConfig = (config, rootPath, CopyWebPackPlugin, HTMLWebPackPlugin, BannerPlugin, fs, rimraf, path) => {
128
-
129
- var plugins = [];
130
-
131
- // if no split, copy as3 buildins to asset folder
132
- // if split, we will copy them for each game-config individually
133
- if (config.buildinsPath && config.buildinsPath.length && !config.split) {
134
- plugins.push(new CopyWebPackPlugin({
135
- patterns: [
136
- { from: config.buildinsPath, to: 'assets/builtins' },
137
- ],
138
- }));
139
- }
140
-
141
- // copy loader.js to js-folder
142
- // if split, this will be copied to the subfolder together with webpack-bundel
143
- plugins.push(new CopyWebPackPlugin({
144
- patterns: [
145
- { from: config.loaderTemplate, to: 'js' },
146
- ],
147
- }));
148
-
149
- // collect all game-urls to create a index.html:
150
- let gameURLS = {};
151
-
152
- // map to collect copied resources, so we preent any redunant copies
153
- let copiedResources = {};
154
-
155
- var _loop_1 = function (i) {
156
-
157
- var fileConfig = config.fileconfigs[i];
158
- var folderName = fileConfig.rt_filename;
159
- var outputPath = config.split ? folderName + "/" : "";
160
-
161
- // if split, copy buildins to each output folder:
162
-
163
- if (config.buildinsPath && config.buildinsPath.length && config.split) {
164
- plugins.push(new CopyWebPackPlugin({
165
- patterns: [
166
- { from: config.buildinsPath, to: outputPath + 'assets/builtins' },
167
- ],
168
- }));
169
- }
170
-
171
- // get config for this file merged with default values from global config:
172
-
173
- var configForHTML = getConfig(fileConfig, config);
174
-
175
- // copy assets for this file-config:
176
-
177
- swfPath = path.join(rootPath, "src", "assets", configForHTML.filename + ".swf");
178
- if (!fs.existsSync(swfPath)) {
179
- throw ("invalid filename path for fileconfig " + configForHTML.filename);
180
- }
181
- stats = fs.statSync(swfPath);
182
- filesize = stats["size"];
183
- if (!fs.existsSync(path.join(rootPath, "src", "assets", configForHTML.splash))) {
184
- throw ("invalid splashscreen path for fileconfig " + configForHTML.splash);
185
- }
186
- plugins.push(new CopyWebPackPlugin({
187
- patterns: [
188
- { from: swfPath, to: outputPath + "assets" },
189
- ],
190
- }));
191
- plugins.push(new CopyWebPackPlugin({
192
- patterns: [
193
- { from: path.join(rootPath, "src", "assets", configForHTML.splash), to: outputPath + "assets" },
194
- ],
195
- }));
196
-
197
- // optional copy startscreen:
198
-
199
- if (configForHTML.start) {
200
- if (!fs.existsSync(path.join(rootPath, "src", "assets", configForHTML.start))) {
201
- throw ("invalid startscreen path for fileconfig " + configForHTML.start);
202
- }
203
- plugins.push(new CopyWebPackPlugin({
204
- patterns: [
205
- { from: path.join(rootPath, "src", "assets", configForHTML.start), to: outputPath + "assets" },
206
- ],
207
- }));
208
- }
209
-
210
- // create/prepare config props needed for runtime
211
-
212
- configForHTML.binary = [];
213
- // copy and prepare resources for html
214
- let resources = getConfigProp(fileConfig, config, "resources");
215
- if (resources && resources.length > 0) {
216
- for (let r = 0; r < resources.length; r++) {
217
- let res_path = path.join(rootPath, resources[r]);
218
- let res_name = path.basename(res_path);
219
- let res_outputPath = "assets/" + res_name;
220
- let res_unique_outputPath = outputPath + "assets/" + res_name;
221
- let res_filesize = copiedResources[res_unique_outputPath];
222
- if (!res_filesize) {
223
- // only need to copy if it has not yet been done
224
- if (!fs.existsSync(res_path)) {
225
- throw ("invalid filename path for resource " + res_path);
226
- }
227
- plugins.push(new CopyWebPackPlugin({
228
- patterns: [
229
- { from: res_path, to: outputPath + "assets" },
230
- ],
231
- }));
232
- stats = fs.statSync(res_path);
233
- res_filesize = stats["size"];
234
- copiedResources[res_unique_outputPath] = res_filesize;
235
- }
236
- configForHTML.binary.push({
237
- name: res_name,
238
- path: res_outputPath,
239
- size: res_filesize,
240
- });
241
- }
242
- }
243
- let assets = getConfigProp(fileConfig, config, "assets");
244
- if (assets && assets.length > 0) {
245
- for (let r = 0; r < assets.length; r++) {
246
- let res_path = path.join(rootPath, assets[r]);
247
-
248
- // extension is missing = is folder
249
- if (!fs.existsSync(res_path)) {
250
- throw ("invalid filename path for asset " + res_path);
251
- }
252
-
253
- let folder = fs.lstatSync(res_path).isDirectory();
254
- let name = path.basename(res_path);
255
-
256
- plugins.push(new CopyWebPackPlugin({
257
- patterns: [
258
- { from: res_path, to: outputPath + "assets" + (folder ? "/" + name : "") },
259
- ],
260
- }));
261
-
262
- }
263
- }
264
-
265
- configForHTML.binary.push({
266
- name: configForHTML.filename,
267
- path: "assets/" + configForHTML.filename + ".swf",
268
- size: filesize,
269
- resourceType: "GAME",
270
- });
271
-
272
- if (configForHTML.splash)
273
- configForHTML.splash = "assets/" + configForHTML.splash;
274
-
275
- if (configForHTML.start)
276
- configForHTML.start = "assets/" + configForHTML.start;
277
-
278
-
279
- var runtimePath = "js/" + config.entryName + ".js";
280
- configForHTML["runtime"] = runtimePath;
281
-
282
-
283
- // create string for html inject (incl hack to handle functions):
284
-
285
- var collectedFunctions = collectAndReplaceFunctions({}, configForHTML);
286
- var configStr = "\nconfig = " + JSON.stringify(configForHTML, null, 4) + ";\n";
287
- var jsStringForHTML = "";
288
- var allFunctions;
289
- if (Object.keys(collectedFunctions).length > 0) {
290
- jsStringForHTML = "\nlet allFunctions = {};\n";
291
- for (var key in collectedFunctions) {
292
- jsStringForHTML += "allFunctions['" + key + "'] = " + collectedFunctions[key].toString() + ";\n";
293
- }
294
- jsStringForHTML += configStr;
295
- jsStringForHTML += "\nlet connectConfigToFunctions =" + (function (obj) {
296
- for (var key in obj) {
297
- if (typeof obj[key] == "string" && obj[key].indexOf("___") === 0) {
298
- obj[key] = allFunctions[obj[key].replace("___", "")];
299
- }
300
- if (typeof obj[key] == "object")
301
- connectConfigToFunctions(obj[key]);
302
- }
303
- }).toString() + ";\n";
304
- jsStringForHTML += "\nconnectConfigToFunctions(config);\n";
305
- }
306
- else {
307
- jsStringForHTML += configStr;
308
- }
309
-
310
- // code to overwrite config by URLSearchParams
311
- if (config.allowURLSearchParams) {
312
- jsStringForHTML += "const q = new URLSearchParams(location.search);\n";
313
- jsStringForHTML += "for (let key of q.keys()){ config[key] = q.get(key);};\n";
314
- }
315
-
316
- // add cachebuster
317
- if (config.cacheBuster) {
318
- jsStringForHTML += "for (let key in config.binary){ config.binary[key].path = config.binary[key].path+'?v='+Math.random();};\n";
319
- }
320
-
321
-
322
- // copy and mod html:
323
-
324
- var htmlOutputPath = (config.split ? folderName + "/" : "") + (config.split ? "index.html" : folderName + ".html");
325
- gameURLS[fileConfig.rt_filename] = {
326
- path: htmlOutputPath,
327
- name: configForHTML.title
328
- };
329
-
330
- var htmlSourcePath = getConfigProp(fileConfig, config, "gameTemplate");
331
-
332
- if (config.debugConfig) {
333
- console.log("### " + configForHTML.title + " CONFIG THAT WILL BE INJECTED INTO HTML");
334
- for (var key in configForHTML) {
335
- console.log(" - config." + key, configForHTML[key]);
336
- }
337
- }
338
-
339
- plugins.push(new CopyWebPackPlugin({
340
- patterns: [
341
- {
342
- from: htmlSourcePath,
343
- to: htmlOutputPath,
344
- transform: function (content, src) {
345
- return content.toString()
346
- .replace(/INSERT_TITLE/g, configForHTML.title ? configForHTML.title : "UNTITLED")
347
- .replace(/INSERT_SPLASHSCREEN/g, configForHTML.splash)
348
- .replace(/INSERT_CODE/g, jsStringForHTML);
349
- }
350
- }
351
- ],
352
- }));
353
- };
354
-
355
- var swfPath, stats, filesize;
356
- for (var i = 0; i < config.fileconfigs.length; i++) {
357
- _loop_1(i);
358
- }
359
-
360
-
361
- // Generate a listing html that links to all game-htmls:
362
- plugins.push(new HTMLWebPackPlugin({
363
- title: config.rt_title,
364
- template: config.indexTemplate,
365
- filename: 'index.html',
366
- games: gameURLS,
367
- inject: false
368
- }));
369
-
370
- if (config.split) {
371
- // when webpack is finished, copy the js-folder to subfolders
372
- // this errors with dev-server, so we only use "split" in prod
373
-
374
- plugins.push({
375
- apply: function (compiler) {
376
- compiler.plugin('done', function (compilation) {
377
- console.log("copy build to game-folders");
378
- for (var i = 0; i < config.fileconfigs.length; i++) {
379
- copyRecursiveSync(fs, path, path.join(rootPath, "bin", "js"), path.join(rootPath, "bin", config.fileconfigs[i].rt_filename, "js"));
380
- }
381
- rimraf.sync(path.join(rootPath, "bin", "js"));
382
- });
383
- }
384
- });
385
-
386
- }
387
-
388
- return plugins;
389
- }
390
-
391
- // get config prop from file-config, or from global-config if it doesnt eists
392
- var getConfigProp = function (fileconfig, config, name) {
393
- return fileconfig[name] ? fileconfig[name] : config[name];
394
- };
395
-
396
- // get a config for a game-file.
397
- // also takes care that it uses props from global-config if file-config does not provide it
398
- // this can probably be done better and cleaner
399
- // but for now it should do the job
400
- var getConfig = function (fileconfig, config) {
401
- var newConfig = {};
402
- for (var key in fileconfig) {
403
- if (key.indexOf("rt_") == 0) {
404
- newConfig[key.replace("rt_", "")] = fileconfig[key];
405
- }
406
- }
407
- for (var key in config) {
408
- if (key.indexOf("rt_") == 0 && !newConfig.hasOwnProperty(key.replace("rt_", ""))) {
409
- newConfig[key.replace("rt_", "")] = config[key];
410
- }
411
- }
412
-
413
- return newConfig;
414
- };
415
-
416
- // collect all js-functions found in config obj and replace them with string-id
417
- // we will inject the functions sepperatly, so we can inject config as json string
418
- // we also inject a function that wires the collected functions back to the js-obj
419
- // this way we can support injecting simple js-function into the html (dont use "this" in functions)
420
- var collectAndReplaceFunctions = function (collectedFunctions, obj, path) {
421
- if (path === void 0) { path = ""; }
422
- if (path != "") { path += ""; }
423
- if (typeof obj === "object") {
424
- for (var key in obj) {
425
- if (typeof obj[key] === "function") {
426
- collectedFunctions[path + key] = obj[key];
427
- obj[key] = "___" + path + key;
428
- }
429
- else {
430
- collectedFunctions = collectAndReplaceFunctions(collectedFunctions, obj[key], path + key);
431
- }
432
- }
433
- }
434
- return collectedFunctions;
435
- };
436
- // used to copy the output to sub-folder when building in split mode
437
- var copyRecursiveSync = function (fs, path, src, dest) {
438
- var exists = fs.existsSync(src);
439
- var stats = exists && fs.statSync(src);
440
- var isDirectory = exists && stats.isDirectory();
441
- if (isDirectory) {
442
- fs.mkdirSync(dest);
443
- fs.readdirSync(src).forEach(function (childItemName) {
444
- copyRecursiveSync(fs, path, path.join(src, childItemName), path.join(dest, childItemName));
445
- });
446
- }
447
- else {
448
- fs.copyFileSync(src, dest);
449
- }
450
- };
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const webpack = require('webpack');
4
+ const CopyWebPackPlugin = require('copy-webpack-plugin');
5
+ const HTMLWebPackPlugin = require('html-webpack-plugin');
6
+ const Terser = require('terser-webpack-plugin')
7
+ const rimraf = require("rimraf");
8
+ const tsloader = require.resolve('ts-loader');
9
+ const merge = require("webpack-merge").merge;
10
+ const config = require('./awayfl.config.js')
11
+
12
+ module.exports = (env = {}) => {
13
+
14
+ var isProd = !!env.prod;
15
+
16
+ // force some configs dependant on prod and dev
17
+ config.rt_debug = isProd ? false : config.rt_debug;
18
+
19
+ config.rt_showFPS = isProd ? false : config.rt_showFPS;
20
+
21
+ config.cacheBuster = isProd ? false : config.cacheBuster;
22
+
23
+ config.allowURLSearchParams = isProd ? false : config.allowURLSearchParams;
24
+
25
+ // split mode right now errors in watch mode
26
+ config.split = isProd ? config.split : false;
27
+
28
+ if (config.debugConfig) {
29
+ console.log("global config used for webpack:");
30
+ for (var key in config) {
31
+ console.log(" - config." + key, config[key]);
32
+ }
33
+ }
34
+
35
+ const entry = {};
36
+ entry[config.entryName] = [config.entryPath];
37
+
38
+ let plugins = processConfig(config, __dirname, CopyWebPackPlugin, HTMLWebPackPlugin, webpack.BannerPlugin, fs, rimraf, path);
39
+
40
+ const common = {
41
+
42
+ entry: entry,
43
+
44
+ output: {
45
+ pathinfo: false,
46
+ path: path.join(__dirname, "bin"),
47
+ filename: 'js/[name].js'
48
+ },
49
+ resolve: {
50
+ alias: {},
51
+ // Add `.ts` and `.tsx` as a resolvable extension.
52
+ extensions: ['.webpack.js', '.web.js', '.js', '.ts', '.tsx']
53
+ },
54
+ module: {
55
+ rules: [
56
+ {
57
+ test: /\.ts(x?)/,
58
+ exclude: /node_modules/,
59
+ loader: tsloader,
60
+ options: {
61
+ experimentalWatchApi: true,
62
+ transpileOnly: true
63
+ }
64
+ },
65
+ ]
66
+ },
67
+ plugins: plugins,
68
+
69
+ performance: {
70
+ hints: false // wp4
71
+ },
72
+ stats: {
73
+ cached: true, // wp4
74
+ errorDetails: true, // wp4
75
+ colors: true // wp4
76
+ },
77
+ devServer: {
78
+ client: {
79
+ progress: true, // wp5
80
+ }
81
+ },
82
+ }
83
+
84
+ const dev = {
85
+ target: 'web',
86
+ mode: "development",// wp4
87
+ //devtool: 'source-map',
88
+ devtool: 'cheap-module-source-map',//use this option for recompiling libs
89
+ devServer: {
90
+ static: {
91
+ publicPath: "/",
92
+ },
93
+ open: false,
94
+ hot: false,
95
+ watchFiles: ['src/**/*.*'],
96
+ client: {
97
+ progress: true,
98
+ },
99
+ allowedHosts: "all",
100
+ port: 80,
101
+ },
102
+ optimization: {
103
+ //minimize: false // wp4
104
+ }
105
+ }
106
+
107
+ const prod = {
108
+ mode: "production",// wp4
109
+ bail: true
110
+ };
111
+
112
+ if(Terser) {
113
+ prod.optimization = {
114
+ minimize: true,
115
+ minimizer: [
116
+ new Terser({
117
+ extractComments: {
118
+ condition: /^\**!|@preserve|@license|@cc_on/i,
119
+ filename: 'LICENSES.txt'
120
+ },
121
+ }),
122
+ ],
123
+ }
124
+ } else {
125
+ console.warn("TERSER IS REQUIRE FOR REMOVING COMMENTS!");
126
+ }
127
+
128
+ return merge(common, isProd ? prod : dev);
129
+
130
+ }
131
+
132
+ // process config
133
+ // return a list of webpack-plugins
134
+ const processConfig = (config, rootPath, CopyWebPackPlugin, HTMLWebPackPlugin, BannerPlugin, fs, rimraf, path) => {
135
+
136
+ var plugins = [];
137
+
138
+ // if no split, copy as3 buildins to asset folder
139
+ // if split, we will copy them for each game-config individually
140
+ if (config.buildinsPath && config.buildinsPath.length && !config.split) {
141
+ plugins.push(new CopyWebPackPlugin({
142
+ patterns: [
143
+ { from: config.buildinsPath, to: 'assets/builtins' },
144
+ ],
145
+ }));
146
+ }
147
+
148
+ // copy loader.js to js-folder
149
+ // if split, this will be copied to the subfolder together with webpack-bundel
150
+ plugins.push(new CopyWebPackPlugin({
151
+ patterns: [
152
+ { from: config.loaderTemplate, to: 'js' },
153
+ ],
154
+ }));
155
+
156
+ // collect all game-urls to create a index.html:
157
+ let gameURLS = {};
158
+
159
+ // map to collect copied resources, so we preent any redunant copies
160
+ let copiedResources = {};
161
+
162
+ var _loop_1 = function (i) {
163
+
164
+ var fileConfig = config.fileconfigs[i];
165
+ var folderName = fileConfig.rt_filename;
166
+ var outputPath = config.split ? folderName + "/" : "";
167
+
168
+ // if split, copy buildins to each output folder:
169
+
170
+ if (config.buildinsPath && config.buildinsPath.length && config.split) {
171
+ plugins.push(new CopyWebPackPlugin({
172
+ patterns: [
173
+ { from: config.buildinsPath, to: outputPath + 'assets/builtins' },
174
+ ],
175
+ }));
176
+ }
177
+
178
+ // get config for this file merged with default values from global config:
179
+
180
+ var configForHTML = getConfig(fileConfig, config);
181
+
182
+ // copy assets for this file-config:
183
+
184
+ swfPath = path.join(rootPath, "src", "assets", configForHTML.filename + ".swf");
185
+ if (!fs.existsSync(swfPath)) {
186
+ throw new Error("invalid filename path for fileconfig " + configForHTML.filename);
187
+ }
188
+ stats = fs.statSync(swfPath);
189
+ filesize = stats["size"];
190
+ if (!fs.existsSync(path.join(rootPath, "src", "assets", configForHTML.splash))) {
191
+ throw new Error("invalid splashscreen path for fileconfig " + configForHTML.splash);
192
+ }
193
+
194
+ plugins.push(new CopyWebPackPlugin({
195
+ patterns: [
196
+ { from: swfPath, to: outputPath + "assets" },
197
+ ],
198
+ }));
199
+
200
+ plugins.push(new CopyWebPackPlugin({
201
+ patterns: [
202
+ { from: path.join(rootPath, "src", "assets", configForHTML.splash), to: outputPath + "assets" },
203
+ ],
204
+ }));
205
+
206
+ // optional copy loading image:
207
+
208
+ if (configForHTML.loading) {
209
+ if (!fs.existsSync(path.join(rootPath, "src", "assets", configForHTML.loading.image))) {
210
+ throw ("invalid loading image path for fileconfig " + configForHTML.loading.image);
211
+ }
212
+ plugins.push(new CopyWebPackPlugin({
213
+ patterns: [
214
+ { from: path.join(rootPath, "src", "assets", configForHTML.loading.image), to: outputPath + "assets" },
215
+ ],
216
+ }));
217
+ }
218
+
219
+
220
+ // optional copy start image:
221
+
222
+ if (configForHTML.start) {
223
+ if (!fs.existsSync(path.join(rootPath, "src", "assets", configForHTML.start.image))) {
224
+ throw ("invalid start image path for fileconfig " + configForHTML.start.image);
225
+ }
226
+ plugins.push(new CopyWebPackPlugin({
227
+ patterns: [
228
+ { from: path.join(rootPath, "src", "assets", configForHTML.start.image), to: outputPath + "assets" },
229
+ ],
230
+ }));
231
+ }
232
+
233
+ // create/prepare config props needed for runtime
234
+
235
+ configForHTML.binary = [];
236
+ // copy and prepare resources for html
237
+ let resources = getConfigProp(fileConfig, config, "resources");
238
+ if (resources && resources.length > 0) {
239
+ for (let r = 0; r < resources.length; r++) {
240
+ let res_path = path.join(rootPath, resources[r]);
241
+ let res_name = path.basename(res_path);
242
+ let res_outputPath = "assets/" + res_name;
243
+ let res_unique_outputPath = outputPath + "assets/" + res_name;
244
+ let res_filesize = copiedResources[res_unique_outputPath];
245
+ if (!res_filesize) {
246
+ // only need to copy if it has not yet been done
247
+ if (!fs.existsSync(res_path)) {
248
+ throw new Error("invalid filename path for resource " + res_path);
249
+ }
250
+ plugins.push(new CopyWebPackPlugin({
251
+ patterns: [
252
+ { from: res_path, to: outputPath + "assets" },
253
+ ],
254
+ }));
255
+ stats = fs.statSync(res_path);
256
+ res_filesize = stats["size"];
257
+ copiedResources[res_unique_outputPath] = res_filesize;
258
+ }
259
+ configForHTML.binary.push({
260
+ name: res_name,
261
+ path: res_outputPath,
262
+ size: res_filesize,
263
+ });
264
+ }
265
+ }
266
+ let assets = getConfigProp(fileConfig, config, "assets");
267
+ if (assets && assets.length > 0) {
268
+ for (let r = 0; r < assets.length; r++) {
269
+ let res_path = path.join(rootPath, assets[r]);
270
+
271
+ // extension is missing = is folder
272
+ if (!fs.existsSync(res_path)) {
273
+ throw new Error("invalid filename path for asset " + res_path);
274
+ }
275
+
276
+ let folder = fs.lstatSync(res_path).isDirectory();
277
+ let name = path.basename(res_path);
278
+
279
+ plugins.push(new CopyWebPackPlugin({
280
+ patterns: [
281
+ { from: res_path, to: outputPath + "assets" + (folder ? "/" + name : "") },
282
+ ],
283
+ }));
284
+
285
+ }
286
+ }
287
+
288
+ configForHTML.binary.push({
289
+ name: configForHTML.filename,
290
+ path: "assets/" + configForHTML.filename + ".swf",
291
+ size: filesize,
292
+ resourceType: "GAME",
293
+ });
294
+
295
+ if (configForHTML.splash)
296
+ configForHTML.splash = "assets/" + configForHTML.splash;
297
+
298
+ if (configForHTML.loading)
299
+ configForHTML.loading.image = "assets/" + configForHTML.loading.image;
300
+
301
+ if (configForHTML.start)
302
+ configForHTML.start.image = "assets/" + configForHTML.start.image;
303
+
304
+
305
+ var runtimePath = "js/" + config.entryName + ".js";
306
+ configForHTML["runtime"] = runtimePath;
307
+
308
+
309
+ // create string for html inject (incl hack to handle functions):
310
+
311
+ var collectedFunctions = collectAndReplaceFunctions({}, configForHTML);
312
+ var configStr = "\nconfig = " + JSON.stringify(configForHTML, null, 4) + ";\n";
313
+ var jsStringForHTML = "";
314
+ var allFunctions;
315
+ if (Object.keys(collectedFunctions).length > 0) {
316
+ jsStringForHTML = "\nlet allFunctions = {};\n";
317
+ for (var key in collectedFunctions) {
318
+ jsStringForHTML += "allFunctions['" + key + "'] = " + collectedFunctions[key].toString() + ";\n";
319
+ }
320
+ jsStringForHTML += configStr;
321
+ jsStringForHTML += "\nlet connectConfigToFunctions =" + (function (obj) {
322
+ for (var key in obj) {
323
+ if (typeof obj[key] == "string" && obj[key].indexOf("___") === 0) {
324
+ obj[key] = allFunctions[obj[key].replace("___", "")];
325
+ }
326
+ if (typeof obj[key] == "object")
327
+ connectConfigToFunctions(obj[key]);
328
+ }
329
+ }).toString() + ";\n";
330
+ jsStringForHTML += "\nconnectConfigToFunctions(config);\n";
331
+ }
332
+ else {
333
+ jsStringForHTML += configStr;
334
+ }
335
+
336
+ // code to overwrite config by URLSearchParams
337
+ if (config.allowURLSearchParams) {
338
+ jsStringForHTML += `const q = new URLSearchParams(location.search);
339
+
340
+ for (let key of q.keys()){
341
+ let value = q.get(key);
342
+
343
+ if (value.includes("<boolean>") || value.includes("<bool>")) {
344
+ let valueWithoutClass = value.replace(/<boolean>/g,'').replace(/<bool>/g,'').toLowerCase();
345
+ if (["true", "t", "1"].includes(valueWithoutClass)) config[key] = true;
346
+ else if (["false", "f", "0"].includes(valueWithoutClass)) config[key] = false;
347
+ else console.warn("Unable to cast URLSearchParam '" + key + "'='" + valueWithoutClass + "' as boolean");
348
+ } else if (value.includes("<int>") || value.includes("<integer>") || value.includes("<number>")) {
349
+ let valueWithoutClass = value.replace(/<int>/g,'').replace(/<integer>/g,'').replace(/<number>/g,'');
350
+ config[key] = parseInt(valueWithoutClass, 10);
351
+ } else {
352
+ // treat this as string
353
+ config[key] = q.get(key);
354
+ }
355
+
356
+ // console.log({key, value, result: config[key]});
357
+ };
358
+ `;
359
+ }
360
+
361
+ // add cachebuster
362
+ if (config.cacheBuster) {
363
+ jsStringForHTML += "for (let key in config.binary){ config.binary[key].path = config.binary[key].path+'?v='+Math.random();};\n";
364
+ }
365
+
366
+
367
+ // copy and mod html:
368
+
369
+ var htmlOutputPath = (config.split ? folderName + "/" : "") + (config.split ? "index.html" : folderName + ".html");
370
+ gameURLS[fileConfig.rt_filename] = {
371
+ path: htmlOutputPath,
372
+ name: configForHTML.title,
373
+ };
374
+
375
+ var htmlSourcePath = getConfigProp(fileConfig, config, "gameTemplate");
376
+
377
+ if (config.debugConfig) {
378
+ console.log("### " + configForHTML.title + " CONFIG THAT WILL BE INJECTED INTO HTML");
379
+ for (var key in configForHTML) {
380
+ console.log(" - config." + key, configForHTML[key]);
381
+ }
382
+ }
383
+
384
+ plugins.push(new CopyWebPackPlugin({
385
+ patterns: [
386
+ {
387
+ from: htmlSourcePath,
388
+ to: htmlOutputPath,
389
+ transform: function (content, src) {
390
+ return content.toString()
391
+ .replace(/INSERT_TITLE/g, configForHTML.title ? configForHTML.title : "UNTITLED")
392
+ .replace(/INSERT_SPLASHSCREEN/g, configForHTML.splash)
393
+ .replace(/INSERT_CODE/g, jsStringForHTML);
394
+ }
395
+ }
396
+ ],
397
+ }));
398
+ };
399
+
400
+ var swfPath, stats, filesize;
401
+ for (var i = 0; i < config.fileconfigs.length; i++) {
402
+ _loop_1(i);
403
+ }
404
+
405
+
406
+ // Generate a listing html that links to all game-htmls:
407
+ plugins.push(new HTMLWebPackPlugin({
408
+ title: config.rt_title,
409
+ template: config.indexTemplate,
410
+ filename: 'index.html',
411
+ games: gameURLS,
412
+ inject: false
413
+ }));
414
+
415
+ if (config.split) {
416
+ // when webpack is finished, copy the js-folder to subfolders
417
+ // this errors with dev-server, so we only use "split" in prod
418
+
419
+ plugins.push({
420
+ apply: function (compiler) {
421
+ compiler.hooks.afterEmit.tap('MyPlugin', function (compilation) {
422
+ console.log("copy build to game-folders");
423
+ for (var i = 0; i < config.fileconfigs.length; i++) {
424
+ copyRecursiveSync(fs, path, path.join(rootPath, "bin", "js"), path.join(rootPath, "bin", config.fileconfigs[i].rt_filename, "js"));
425
+ }
426
+ rimraf.sync(path.join(rootPath, "bin", "js"));
427
+ });
428
+ }
429
+ });
430
+
431
+ }
432
+
433
+ return plugins;
434
+ }
435
+
436
+ // get config prop from file-config, or from global-config if it doesnt eists
437
+ var getConfigProp = function (fileconfig, config, name) {
438
+ return fileconfig[name] ? fileconfig[name] : config[name];
439
+ };
440
+
441
+ // get a config for a game-file.
442
+ // this filters out all props that are not prefixed by "rt_"
443
+ // also takes care that it uses props from global-config if file-config does not provide it
444
+ // this can probably be done better and cleaner
445
+ // but for now it should do the job
446
+ var getConfig = function (fileconfig, config) {
447
+ var newConfig = {};
448
+ for (var key in fileconfig) {
449
+ if (key.indexOf("rt_") == 0) {
450
+ newConfig[key.replace("rt_", "")] = fileconfig[key];
451
+ }
452
+ }
453
+ for (var key in config) {
454
+ if (key.indexOf("rt_") == 0 && !newConfig.hasOwnProperty(key.replace("rt_", ""))) {
455
+ newConfig[key.replace("rt_", "")] = config[key];
456
+ }
457
+ }
458
+
459
+ return newConfig;
460
+ };
461
+
462
+ // collect all js-functions found in config obj and replace them with string-id
463
+ // we will inject the functions sepperatly, so we can inject config as json string
464
+ // we also inject a function that wires the collected functions back to the js-obj
465
+ // this way we can support injecting simple js-function into the html (dont use "this" in functions)
466
+ var collectAndReplaceFunctions = function (collectedFunctions, obj, path) {
467
+ if (path === void 0) { path = ""; }
468
+ if (path != "") { path += ""; }
469
+ if (typeof obj === "object") {
470
+ for (var key in obj) {
471
+ if (typeof obj[key] === "function") {
472
+ collectedFunctions[path + key] = obj[key];
473
+ obj[key] = "___" + path + key;
474
+ }
475
+ else {
476
+ collectedFunctions = collectAndReplaceFunctions(collectedFunctions, obj[key], path + key);
477
+ }
478
+ }
479
+ }
480
+ return collectedFunctions;
481
+ };
482
+ // used to copy the output to sub-folder when building in split mode
483
+ var copyRecursiveSync = function (fs, path, src, dest) {
484
+ var exists = fs.existsSync(src);
485
+ var stats = exists && fs.statSync(src);
486
+ var isDirectory = exists && stats.isDirectory();
487
+ if (isDirectory) {
488
+ fs.mkdirSync(dest);
489
+ fs.readdirSync(src).forEach(function (childItemName) {
490
+ copyRecursiveSync(fs, path, path.join(src, childItemName), path.join(dest, childItemName));
491
+ });
492
+ }
493
+ else {
494
+ fs.copyFileSync(src, dest);
495
+ }
496
+ };