@playcraft/build 0.0.13 → 0.0.15
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/dist/analyzers/scene-asset-collector.js +99 -9
- package/dist/base-builder.d.ts +15 -78
- package/dist/base-builder.js +34 -741
- package/dist/engines/engine-detector.d.ts +38 -0
- package/dist/engines/engine-detector.js +201 -0
- package/dist/engines/generic-adapter.d.ts +71 -0
- package/dist/engines/generic-adapter.js +378 -0
- package/dist/engines/index.d.ts +7 -0
- package/dist/engines/index.js +7 -0
- package/dist/engines/playcanvas-adapter.d.ts +85 -0
- package/dist/engines/playcanvas-adapter.js +813 -0
- package/dist/generators/config-generator.js +59 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/loaders/playcraft-loader.js +240 -5
- package/dist/platforms/adikteev.d.ts +1 -1
- package/dist/platforms/adikteev.js +30 -36
- package/dist/platforms/applovin.d.ts +1 -1
- package/dist/platforms/applovin.js +31 -36
- package/dist/platforms/base.d.ts +27 -5
- package/dist/platforms/base.js +79 -181
- package/dist/platforms/bigo.d.ts +1 -1
- package/dist/platforms/bigo.js +28 -28
- package/dist/platforms/facebook.d.ts +1 -1
- package/dist/platforms/facebook.js +21 -10
- package/dist/platforms/google.d.ts +1 -1
- package/dist/platforms/google.js +28 -21
- package/dist/platforms/index.d.ts +1 -0
- package/dist/platforms/index.js +4 -0
- package/dist/platforms/inmobi.d.ts +1 -1
- package/dist/platforms/inmobi.js +27 -34
- package/dist/platforms/ironsource.d.ts +1 -1
- package/dist/platforms/ironsource.js +37 -40
- package/dist/platforms/liftoff.d.ts +1 -1
- package/dist/platforms/liftoff.js +22 -30
- package/dist/platforms/mintegral.d.ts +10 -0
- package/dist/platforms/mintegral.js +65 -0
- package/dist/platforms/moloco.d.ts +1 -1
- package/dist/platforms/moloco.js +18 -20
- package/dist/platforms/playcraft.d.ts +1 -1
- package/dist/platforms/playcraft.js +2 -2
- package/dist/platforms/remerge.d.ts +1 -1
- package/dist/platforms/remerge.js +19 -20
- package/dist/platforms/snapchat.d.ts +1 -1
- package/dist/platforms/snapchat.js +32 -26
- package/dist/platforms/tiktok.d.ts +1 -1
- package/dist/platforms/tiktok.js +28 -24
- package/dist/platforms/unity.d.ts +1 -1
- package/dist/platforms/unity.js +30 -36
- package/dist/playable-builder.d.ts +1 -0
- package/dist/playable-builder.js +16 -2
- package/dist/types.d.ts +113 -1
- package/dist/types.js +77 -1
- package/dist/utils/ammo-detector.d.ts +9 -0
- package/dist/utils/ammo-detector.js +76 -0
- package/dist/utils/build-mode-detector.js +2 -0
- package/dist/utils/minify.d.ts +32 -0
- package/dist/utils/minify.js +82 -0
- package/dist/utils/obfuscate.d.ts +42 -0
- package/dist/utils/obfuscate.js +216 -0
- package/dist/vite/config-builder-generic.d.ts +70 -0
- package/dist/vite/config-builder-generic.js +251 -0
- package/dist/vite/config-builder.d.ts +8 -0
- package/dist/vite/config-builder.js +53 -16
- package/dist/vite/platform-configs.js +29 -1
- package/dist/vite/plugin-compress-js.d.ts +21 -0
- package/dist/vite/plugin-compress-js.js +213 -0
- package/dist/vite/plugin-esm-html-generator.js +5 -1
- package/dist/vite/plugin-obfuscate.d.ts +22 -0
- package/dist/vite/plugin-obfuscate.js +52 -0
- package/dist/vite/plugin-platform.d.ts +5 -0
- package/dist/vite/plugin-platform.js +499 -35
- package/dist/vite/plugin-playcanvas.js +21 -68
- package/dist/vite/plugin-source-builder.js +102 -21
- package/dist/vite-builder.d.ts +25 -7
- package/dist/vite-builder.js +141 -52
- package/package.json +4 -2
- package/physics/cannon-rigidbody-adapter.js +243 -22
- package/templates/__loading__.js +0 -12
- package/templates/index.esm.mjs +0 -11
- package/templates/patches/playcraft-cta-adapter.js +129 -31
- package/templates/patches/scene-physics-defaults.js +49 -0
|
@@ -10,50 +10,47 @@ export class IronSourceAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'html';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// ironSource 需要 MRAID 和 dapi API
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
</script>
|
|
48
|
-
<!--
|
|
49
|
-
注意:ironSource 要求预留四角约30x30px区域给平台UI
|
|
50
|
-
请确保游戏内容不会被遮挡
|
|
51
|
-
-->
|
|
15
|
+
const ironSourceScriptCode = `
|
|
16
|
+
window.mraid = window.mraid || {
|
|
17
|
+
getVersion: function() { return '2.0'; },
|
|
18
|
+
isReady: function() { return true; },
|
|
19
|
+
open: function(url) {
|
|
20
|
+
if (url) { window.open(url, '_blank'); return; }
|
|
21
|
+
var ua = navigator.userAgent || '';
|
|
22
|
+
var isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
23
|
+
var _s = window.__PLAYCRAFT_STORE_URLS__ || {};
|
|
24
|
+
window.open(isIOS ? (_s.ios || '') : (_s.android || ''), '_blank');
|
|
25
|
+
},
|
|
26
|
+
close: function() {
|
|
27
|
+
console.log('ironSource: close() handled by platform');
|
|
28
|
+
},
|
|
29
|
+
useCustomClose: function(useCustomClose) {
|
|
30
|
+
console.warn('ironSource: useCustomClose() not allowed');
|
|
31
|
+
},
|
|
32
|
+
addEventListener: function(event, listener) {},
|
|
33
|
+
removeEventListener: function(event, listener) {},
|
|
34
|
+
getState: function() { return 'default'; },
|
|
35
|
+
getPlacementType: function() { return 'interstitial'; },
|
|
36
|
+
getMaxSize: function() { return { width: window.innerWidth, height: window.innerHeight }; },
|
|
37
|
+
getCurrentPosition: function() { return { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight }; },
|
|
38
|
+
getScreenSize: function() { return { width: screen.width, height: screen.height }; }
|
|
39
|
+
};
|
|
40
|
+
window.dapi = window.dapi || {
|
|
41
|
+
isReady: function() { return true; },
|
|
42
|
+
addEventListener: function(event, callback) {
|
|
43
|
+
if (event === 'ready') setTimeout(callback, 0);
|
|
44
|
+
},
|
|
45
|
+
removeEventListener: function(event, callback) {}
|
|
46
|
+
};
|
|
52
47
|
`;
|
|
48
|
+
const ironSourceScript = await this.minifyPlatformScript(ironSourceScriptCode, 'ironsource-mraid-dapi');
|
|
49
|
+
const comment = `<!-- ironSource: 预留四角30x30px给平台UI -->`;
|
|
53
50
|
// 在 </head> 之前插入平台特定的 API
|
|
54
|
-
html = html.replace('</head>', `${ironSourceScript}</head>`);
|
|
51
|
+
html = html.replace('</head>', `${ironSourceScript}${comment}</head>`);
|
|
55
52
|
// 注入统一的 CTA 适配器
|
|
56
|
-
html = this.
|
|
53
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
57
54
|
return html;
|
|
58
55
|
}
|
|
59
56
|
getPlatformScript() {
|
|
@@ -4,7 +4,7 @@ export declare class LiftoffAdapter extends PlatformAdapter {
|
|
|
4
4
|
getName(): string;
|
|
5
5
|
getSizeLimit(): number;
|
|
6
6
|
getDefaultFormat(): 'html' | 'zip';
|
|
7
|
-
modifyHTML(html: string, assets: AssetInfo[]): string
|
|
7
|
+
modifyHTML(html: string, assets: AssetInfo[]): Promise<string>;
|
|
8
8
|
getPlatformScript(): string;
|
|
9
9
|
validateOptions(): void;
|
|
10
10
|
}
|
|
@@ -10,40 +10,32 @@ export class LiftoffAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'zip';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// Liftoff 支持 MRAID 或 window.open
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
<!--
|
|
33
|
-
注意:
|
|
34
|
-
- Liftoff 要求 ZIP 格式
|
|
35
|
-
- 文件名必须为 ASCII(禁止 UTF-8)
|
|
36
|
-
- 大小写敏感
|
|
37
|
-
- 跳转使用 mraid.open() 或 window.open(),禁止 window.location
|
|
38
|
-
- 需用户交互后才能跳转
|
|
39
|
-
- 支持标准尺寸:320x480, 480x320, 768x1024, 1024x768, 320x50, 728x90, 300x250
|
|
40
|
-
- 关闭按钮由平台处理,可能遮挡角落 50x50px
|
|
41
|
-
-->
|
|
15
|
+
const liftoffScriptCode = `
|
|
16
|
+
window.mraid = window.mraid || {
|
|
17
|
+
getVersion: function() { return '2.0'; },
|
|
18
|
+
isReady: function() { return true; },
|
|
19
|
+
open: function(url) {
|
|
20
|
+
console.log('Liftoff CTA: opening store');
|
|
21
|
+
if (url) { window.open(url, '_blank'); return; }
|
|
22
|
+
var ua = navigator.userAgent || '';
|
|
23
|
+
var isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
24
|
+
window.open(isIOS ? 'https://apps.apple.com/us/app/8-ball-pool/id543186831' : 'https://play.google.com/store/apps/details?id=com.miniclip.eightballpool', '_blank');
|
|
25
|
+
},
|
|
26
|
+
addEventListener: function(event, listener) {},
|
|
27
|
+
removeEventListener: function(event, listener) {},
|
|
28
|
+
getMaxSize: function() { return { width: window.innerWidth, height: window.innerHeight }; },
|
|
29
|
+
getCurrentPosition: function() { return { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight }; },
|
|
30
|
+
getScreenSize: function() { return { width: screen.width, height: screen.height }; }
|
|
31
|
+
};
|
|
42
32
|
`;
|
|
33
|
+
const liftoffScript = await this.minifyPlatformScript(liftoffScriptCode, 'liftoff-mraid');
|
|
34
|
+
const comment = `<!-- Liftoff: ZIP格式, ASCII文件名, 使用mraid.open()或window.open() -->`;
|
|
43
35
|
// 在 </head> 之前插入
|
|
44
|
-
html = html.replace('</head>', `${liftoffScript}</head>`);
|
|
36
|
+
html = html.replace('</head>', `${liftoffScript}${comment}</head>`);
|
|
45
37
|
// 注入统一的 CTA 适配器
|
|
46
|
-
html = this.
|
|
38
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
47
39
|
return html;
|
|
48
40
|
}
|
|
49
41
|
getPlatformScript() {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PlatformAdapter } from './base.js';
|
|
2
|
+
import type { AssetInfo } from '../types.js';
|
|
3
|
+
export declare class MintegralAdapter extends PlatformAdapter {
|
|
4
|
+
getName(): string;
|
|
5
|
+
getSizeLimit(): number;
|
|
6
|
+
getDefaultFormat(): 'html' | 'zip';
|
|
7
|
+
modifyHTML(html: string, assets: AssetInfo[]): Promise<string>;
|
|
8
|
+
getPlatformScript(): string;
|
|
9
|
+
validateOptions(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { PlatformAdapter } from './base.js';
|
|
2
|
+
export class MintegralAdapter extends PlatformAdapter {
|
|
3
|
+
getName() {
|
|
4
|
+
return 'Mintegral';
|
|
5
|
+
}
|
|
6
|
+
getSizeLimit() {
|
|
7
|
+
// Mintegral: 5MB (ZIP)
|
|
8
|
+
return 5 * 1024 * 1024;
|
|
9
|
+
}
|
|
10
|
+
getDefaultFormat() {
|
|
11
|
+
return 'zip';
|
|
12
|
+
}
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
|
+
// Mintegral 要求 charset 为 utf-8,确保存在
|
|
15
|
+
if (!html.includes('charset') && html.includes('<head>')) {
|
|
16
|
+
html = html.replace('<head>', '<head>\n<meta charset="utf-8">');
|
|
17
|
+
}
|
|
18
|
+
// Mintegral SDK polyfill(仅本地浏览器测试用的兜底)
|
|
19
|
+
// 真实 Mintegral 环境中 SDK 会注入 window.install 等函数,这些 polyfill 不会生效
|
|
20
|
+
const mintegralScriptCode = `
|
|
21
|
+
window.install = window.install || function() {
|
|
22
|
+
var ua = navigator.userAgent || '';
|
|
23
|
+
var isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
24
|
+
var _s = (typeof window !== 'undefined' && window.__PLAYCRAFT_STORE_URLS__) || {};
|
|
25
|
+
var url = isIOS ? (_s.ios || '') : (_s.android || '');
|
|
26
|
+
if (url) window.open(url, '_blank');
|
|
27
|
+
};
|
|
28
|
+
window.gameReady = window.gameReady || function() {};
|
|
29
|
+
window.gameEnd = window.gameEnd || function() {};
|
|
30
|
+
window.gameRetry = window.gameRetry || function() {};
|
|
31
|
+
if (typeof window.gameStart !== 'function') { window.gameStart = function() {}; }
|
|
32
|
+
if (typeof window.gameClose !== 'function') { window.gameClose = function() {}; }
|
|
33
|
+
window.HttpAPI = window.HttpAPI || { sendPoint: function() {} };
|
|
34
|
+
`;
|
|
35
|
+
const mintegralScript = await this.minifyPlatformScript(mintegralScriptCode, 'mintegral-sdk');
|
|
36
|
+
const comment = `<!-- Mintegral: ZIP格式, 5MB限制, 使用window.install()跳转, 支持横竖屏 -->`;
|
|
37
|
+
// 在 </head> 之前插入 polyfill 和注释,如果没有 </head> 则在文件开头插入
|
|
38
|
+
if (html.includes('</head>')) {
|
|
39
|
+
html = html.replace('</head>', `${mintegralScript}${comment}\n</head>`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
html = `${mintegralScript}${comment}\n${html}`;
|
|
43
|
+
}
|
|
44
|
+
// 注入统一的 CTA 适配器
|
|
45
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
46
|
+
return html;
|
|
47
|
+
}
|
|
48
|
+
getPlatformScript() {
|
|
49
|
+
return `
|
|
50
|
+
// Mintegral Playable Ad
|
|
51
|
+
// CTA: window.install && window.install();
|
|
52
|
+
// Lifecycle: gameReady -> gameStart -> gameEnd/gameRetry -> gameClose
|
|
53
|
+
|
|
54
|
+
// 资源加载完成后通知 SDK
|
|
55
|
+
if (typeof window.gameReady === 'function') {
|
|
56
|
+
window.gameReady();
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
validateOptions() {
|
|
61
|
+
if (this.options.format && this.options.format !== 'zip') {
|
|
62
|
+
console.warn('警告: Mintegral 要求 ZIP 格式,将自动使用 ZIP');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -4,7 +4,7 @@ export declare class MolocoAdapter extends PlatformAdapter {
|
|
|
4
4
|
getName(): string;
|
|
5
5
|
getSizeLimit(): number;
|
|
6
6
|
getDefaultFormat(): 'html' | 'zip';
|
|
7
|
-
modifyHTML(html: string, assets: AssetInfo[]): string
|
|
7
|
+
modifyHTML(html: string, assets: AssetInfo[]): Promise<string>;
|
|
8
8
|
getPlatformScript(): string;
|
|
9
9
|
validateOptions(): void;
|
|
10
10
|
}
|
package/dist/platforms/moloco.js
CHANGED
|
@@ -10,31 +10,29 @@ export class MolocoAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'html';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// Moloco 使用 FbPlayableAd API(与 Facebook 相同)
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
const molocoScriptCode = `
|
|
16
|
+
window.FbPlayableAd = window.FbPlayableAd || {
|
|
17
|
+
onCTAClick: function() {
|
|
18
|
+
console.log('Moloco CTA clicked');
|
|
19
|
+
function getOS(){
|
|
20
|
+
var ua = navigator.userAgent || '';
|
|
21
|
+
if (/iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) return 'ios';
|
|
22
|
+
if (/Android/i.test(ua)) return 'android';
|
|
23
|
+
return 'unknown';
|
|
22
24
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- Moloco 使用单文件 HTML 格式,<5MB
|
|
28
|
-
- CTA 必须以"无参数"方式调用 FbPlayableAd.onCTAClick()
|
|
29
|
-
- 不得包含 mraid.js
|
|
30
|
-
- 不允许任何外部引用或 HTTP 动态加载
|
|
31
|
-
- 禁止 XMLHttpRequest 和 JS 重定向
|
|
32
|
-
-->
|
|
25
|
+
var url = getOS() === 'ios' ? 'https://apps.apple.com/us/app/8-ball-pool/id543186831' : 'https://play.google.com/store/apps/details?id=com.miniclip.eightballpool';
|
|
26
|
+
window.open(url, '_blank');
|
|
27
|
+
}
|
|
28
|
+
};
|
|
33
29
|
`;
|
|
30
|
+
const molocoScript = await this.minifyPlatformScript(molocoScriptCode, 'moloco-api');
|
|
31
|
+
const comment = `<!-- Moloco: 单文件 HTML <5MB, CTA 无参数调用 FbPlayableAd.onCTAClick() -->`;
|
|
34
32
|
// 在 </head> 之前插入平台特定的 API
|
|
35
|
-
html = html.replace('</head>', `${molocoScript}</head>`);
|
|
33
|
+
html = html.replace('</head>', `${molocoScript}${comment}</head>`);
|
|
36
34
|
// 注入统一的 CTA 适配器
|
|
37
|
-
html = this.
|
|
35
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
38
36
|
return html;
|
|
39
37
|
}
|
|
40
38
|
getPlatformScript() {
|
|
@@ -24,7 +24,7 @@ export declare class PlayCraftAdapter extends PlatformAdapter {
|
|
|
24
24
|
* 应用平台特定的 HTML 修改
|
|
25
25
|
* PlayCraft 构建注入 CTA 适配器
|
|
26
26
|
*/
|
|
27
|
-
modifyHTML(html: string, _assets: AssetInfo[]): string
|
|
27
|
+
modifyHTML(html: string, _assets: AssetInfo[]): Promise<string>;
|
|
28
28
|
/**
|
|
29
29
|
* 获取平台特定的 JavaScript 代码
|
|
30
30
|
* PlayCraft 构建不需要额外的平台脚本
|
|
@@ -31,8 +31,8 @@ export class PlayCraftAdapter extends PlatformAdapter {
|
|
|
31
31
|
* 应用平台特定的 HTML 修改
|
|
32
32
|
* PlayCraft 构建注入 CTA 适配器
|
|
33
33
|
*/
|
|
34
|
-
modifyHTML(html, _assets) {
|
|
35
|
-
return this.
|
|
34
|
+
async modifyHTML(html, _assets) {
|
|
35
|
+
return await this.injectCTAAdapterAsync(html);
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* 获取平台特定的 JavaScript 代码
|
|
@@ -4,7 +4,7 @@ export declare class RemergeAdapter extends PlatformAdapter {
|
|
|
4
4
|
getName(): string;
|
|
5
5
|
getSizeLimit(): number;
|
|
6
6
|
getDefaultFormat(): 'html' | 'zip';
|
|
7
|
-
modifyHTML(html: string, assets: AssetInfo[]): string
|
|
7
|
+
modifyHTML(html: string, assets: AssetInfo[]): Promise<string>;
|
|
8
8
|
getPlatformScript(): string;
|
|
9
9
|
validateOptions(): void;
|
|
10
10
|
}
|
|
@@ -10,31 +10,30 @@ export class RemergeAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'html';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// Remerge 使用 FbPlayableAd API(与 Facebook/Moloco 相同)
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
const remergeScriptCode = `
|
|
16
|
+
window.FbPlayableAd = window.FbPlayableAd || {
|
|
17
|
+
onCTAClick: function() {
|
|
18
|
+
console.log('Remerge CTA clicked');
|
|
19
|
+
function getOS(){
|
|
20
|
+
var ua = navigator.userAgent || '';
|
|
21
|
+
if (/iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) return 'ios';
|
|
22
|
+
if (/Android/i.test(ua)) return 'android';
|
|
23
|
+
return 'unknown';
|
|
22
24
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- Remerge 使用单文件 HTML 格式,<5MB
|
|
28
|
-
- CTA 必须以"无参数"方式调用 FbPlayableAd.onCTAClick()
|
|
29
|
-
- 不允许任何外部引用或 HTTP 动态加载
|
|
30
|
-
- 禁止 XMLHttpRequest 和 JS 重定向
|
|
31
|
-
-->
|
|
32
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
25
|
+
var url = getOS() === 'ios' ? 'https://apps.apple.com/us/app/8-ball-pool/id543186831' : 'https://play.google.com/store/apps/details?id=com.miniclip.eightballpool';
|
|
26
|
+
window.open(url, '_blank');
|
|
27
|
+
}
|
|
28
|
+
};
|
|
33
29
|
`;
|
|
30
|
+
const remergeScript = await this.minifyPlatformScript(remergeScriptCode, 'remerge-api');
|
|
31
|
+
const meta = `<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">`;
|
|
32
|
+
const comment = `<!-- Remerge: 单文件 HTML <5MB, CTA 无参数调用 -->`;
|
|
34
33
|
// 在 </head> 之前插入平台特定的 API
|
|
35
|
-
html = html.replace('</head>', `${remergeScript}</head>`);
|
|
34
|
+
html = html.replace('</head>', `${remergeScript}${comment}${meta}</head>`);
|
|
36
35
|
// 注入统一的 CTA 适配器
|
|
37
|
-
html = this.
|
|
36
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
38
37
|
return html;
|
|
39
38
|
}
|
|
40
39
|
getPlatformScript() {
|
|
@@ -4,7 +4,7 @@ export declare class SnapchatAdapter extends PlatformAdapter {
|
|
|
4
4
|
getName(): string;
|
|
5
5
|
getSizeLimit(): number;
|
|
6
6
|
getDefaultFormat(): 'html' | 'zip';
|
|
7
|
-
modifyHTML(html: string, assets: AssetInfo[]): string
|
|
7
|
+
modifyHTML(html: string, assets: AssetInfo[]): Promise<string>;
|
|
8
8
|
getPlatformScript(): string;
|
|
9
9
|
validateOptions(): void;
|
|
10
10
|
}
|
|
@@ -10,36 +10,42 @@ export class SnapchatAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'zip';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// Snapchat 需要 MRAID 2.0 和 snapchatCta 函数
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
15
|
+
const mraidScriptCode = `
|
|
16
|
+
window.mraid = window.mraid || {
|
|
17
|
+
getVersion: function() { return '2.0'; },
|
|
18
|
+
isReady: function() { return true; },
|
|
19
|
+
open: function(url) {
|
|
20
|
+
if (url) { window.open(url, '_blank'); return; }
|
|
21
|
+
var ua = navigator.userAgent || '';
|
|
22
|
+
var isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
23
|
+
var _s = window.__PLAYCRAFT_STORE_URLS__ || {};
|
|
24
|
+
window.open(isIOS ? (_s.ios || '') : (_s.android || ''), '_blank');
|
|
25
|
+
},
|
|
26
|
+
close: function() { window.close(); },
|
|
27
|
+
addEventListener: function(event, listener) {},
|
|
28
|
+
removeEventListener: function(event, listener) {},
|
|
29
|
+
getState: function() { return 'ready'; },
|
|
30
|
+
getPlacementType: function() { return 'interstitial'; },
|
|
31
|
+
getMaxSize: function() { return { width: window.innerWidth, height: window.innerHeight }; },
|
|
32
|
+
getCurrentPosition: function() { return { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight }; },
|
|
33
|
+
getScreenSize: function() { return { width: screen.width, height: screen.height }; }
|
|
34
|
+
};
|
|
35
|
+
window.snapchatCta = function() {
|
|
36
|
+
if (window.mraid && window.mraid.open) {
|
|
37
|
+
var _s = window.__PLAYCRAFT_STORE_URLS__ || {};
|
|
38
|
+
var ua = navigator.userAgent || '';
|
|
39
|
+
var isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
40
|
+
var url = isIOS ? (_s.ios || '') : (_s.android || '');
|
|
41
|
+
window.mraid.open(url);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
39
44
|
`;
|
|
45
|
+
const mraidScript = await this.minifyPlatformScript(mraidScriptCode, 'snapchat-mraid');
|
|
40
46
|
html = html.replace('</head>', `${mraidScript}</head>`);
|
|
41
47
|
// 注入统一的 CTA 适配器
|
|
42
|
-
html = this.
|
|
48
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
43
49
|
return html;
|
|
44
50
|
}
|
|
45
51
|
getPlatformScript() {
|
|
@@ -4,7 +4,7 @@ export declare class TikTokAdapter extends PlatformAdapter {
|
|
|
4
4
|
getName(): string;
|
|
5
5
|
getSizeLimit(): number;
|
|
6
6
|
getDefaultFormat(): 'html' | 'zip';
|
|
7
|
-
modifyHTML(html: string, assets: AssetInfo[]): string
|
|
7
|
+
modifyHTML(html: string, assets: AssetInfo[]): Promise<string>;
|
|
8
8
|
getPlatformScript(): string;
|
|
9
9
|
/**
|
|
10
10
|
* 生成 config.json(TikTok/Pangle 要求)
|
package/dist/platforms/tiktok.js
CHANGED
|
@@ -10,33 +10,37 @@ export class TikTokAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'zip';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// TikTok/Pangle 需要 Pangle JS-SDK
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-->
|
|
15
|
+
const pangleScriptCode = `
|
|
16
|
+
window.Pangle = window.Pangle || {
|
|
17
|
+
open: function(url) {
|
|
18
|
+
console.log('Pangle CTA: opening store');
|
|
19
|
+
},
|
|
20
|
+
ready: function() {
|
|
21
|
+
console.log('Pangle SDK ready');
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
window.openAppStore = window.openAppStore || function() {
|
|
25
|
+
console.log('TikTok CTA: openAppStore');
|
|
26
|
+
function getOS(){
|
|
27
|
+
var ua = navigator.userAgent || '';
|
|
28
|
+
if (/iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) return 'ios';
|
|
29
|
+
if (/Android/i.test(ua)) return 'android';
|
|
30
|
+
return 'unknown';
|
|
31
|
+
}
|
|
32
|
+
var _s = (typeof window !== 'undefined' && window.__PLAYCRAFT_STORE_URLS__) || {};
|
|
33
|
+
var url = getOS() === 'ios' ? (_s.ios || '') : (_s.android || '');
|
|
34
|
+
if (url) window.open(url, '_blank');
|
|
35
|
+
};
|
|
37
36
|
`;
|
|
37
|
+
const pangleScript = await this.minifyPlatformScript(pangleScriptCode, 'pangle-sdk');
|
|
38
|
+
const comment = `<!-- TikTok/Pangle: ZIP格式, config.json含playable_orientation, 禁止mraid.js -->`;
|
|
38
39
|
// 在 </head> 之前插入
|
|
39
|
-
|
|
40
|
+
html = html.replace('</head>', `${pangleScript}${comment}</head>`);
|
|
41
|
+
// 注入统一的 CTA 适配器
|
|
42
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
43
|
+
return html;
|
|
40
44
|
}
|
|
41
45
|
getPlatformScript() {
|
|
42
46
|
return `
|
|
@@ -4,7 +4,7 @@ export declare class UnityAdapter extends PlatformAdapter {
|
|
|
4
4
|
getName(): string;
|
|
5
5
|
getSizeLimit(): number;
|
|
6
6
|
getDefaultFormat(): 'html' | 'zip';
|
|
7
|
-
modifyHTML(html: string, assets: AssetInfo[]): string
|
|
7
|
+
modifyHTML(html: string, assets: AssetInfo[]): Promise<string>;
|
|
8
8
|
getPlatformScript(): string;
|
|
9
9
|
validateOptions(): void;
|
|
10
10
|
}
|
package/dist/platforms/unity.js
CHANGED
|
@@ -10,46 +10,40 @@ export class UnityAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'html';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// Unity Ads 需要 MRAID 3.0 支持
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
<!--
|
|
41
|
-
注意:
|
|
42
|
-
- Unity Ads 要求 MRAID 3.0
|
|
43
|
-
- 需等待 mraid.viewableChange 事件后再启动游戏
|
|
44
|
-
- 使用 mraid.open() 跳转应用商店
|
|
45
|
-
- 不允许自动重定向
|
|
46
|
-
- 支持 Android ≥4.4, iOS ≥9.0
|
|
47
|
-
-->
|
|
15
|
+
const unityScriptCode = `
|
|
16
|
+
window.mraid = window.mraid || {
|
|
17
|
+
getVersion: function() { return '3.0'; },
|
|
18
|
+
isReady: function() { return true; },
|
|
19
|
+
open: function(url) {
|
|
20
|
+
console.log('Unity Ads CTA: opening store');
|
|
21
|
+
if (url) { window.open(url, '_blank'); return; }
|
|
22
|
+
var ua = navigator.userAgent || '';
|
|
23
|
+
var isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
|
24
|
+
window.open(isIOS ? 'https://apps.apple.com/us/app/8-ball-pool/id543186831' : 'https://play.google.com/store/apps/details?id=com.miniclip.eightballpool', '_blank');
|
|
25
|
+
},
|
|
26
|
+
close: function() { window.close(); },
|
|
27
|
+
addEventListener: function(event, listener) {
|
|
28
|
+
if (event === 'ready' || event === 'viewableChange') {
|
|
29
|
+
setTimeout(function() { listener({ viewable: true }); }, 0);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
removeEventListener: function(event, listener) {},
|
|
33
|
+
getState: function() { return 'default'; },
|
|
34
|
+
getPlacementType: function() { return 'interstitial'; },
|
|
35
|
+
isViewable: function() { return true; },
|
|
36
|
+
getMaxSize: function() { return { width: window.innerWidth, height: window.innerHeight }; },
|
|
37
|
+
getCurrentPosition: function() { return { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight }; },
|
|
38
|
+
getScreenSize: function() { return { width: screen.width, height: screen.height }; }
|
|
39
|
+
};
|
|
48
40
|
`;
|
|
41
|
+
const unityScript = await this.minifyPlatformScript(unityScriptCode, 'unity-mraid');
|
|
42
|
+
const comment = `<!-- Unity Ads: MRAID 3.0, 等待viewableChange, 使用mraid.open() -->`;
|
|
49
43
|
// 在 </head> 之前插入
|
|
50
|
-
html = html.replace('</head>', `${unityScript}</head>`);
|
|
44
|
+
html = html.replace('</head>', `${unityScript}${comment}</head>`);
|
|
51
45
|
// 注入统一的 CTA 适配器
|
|
52
|
-
html = this.
|
|
46
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
53
47
|
return html;
|
|
54
48
|
}
|
|
55
49
|
getPlatformScript() {
|