@playcraft/build 0.0.11 → 0.0.14
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/__tests__/optimization-analyzer.test.d.ts +1 -0
- package/dist/analyzers/__tests__/optimization-analyzer.test.js +169 -0
- package/dist/analyzers/playable-analyzer.js +3 -2
- package/dist/analyzers/scene-asset-collector.js +99 -9
- package/dist/base-builder.d.ts +15 -78
- package/dist/base-builder.js +34 -735
- 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 -34
- package/dist/platforms/applovin.d.ts +1 -1
- package/dist/platforms/applovin.js +34 -33
- 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 -32
- package/dist/platforms/ironsource.d.ts +1 -1
- package/dist/platforms/ironsource.js +37 -37
- package/dist/platforms/liftoff.d.ts +1 -1
- package/dist/platforms/liftoff.js +24 -27
- 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 +35 -23
- 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 +32 -32
- package/dist/playable-builder.d.ts +1 -0
- package/dist/playable-builder.js +19 -3
- package/dist/templates/__loading__.js +100 -0
- package/dist/templates/__modules__.js +47 -0
- package/dist/templates/__settings__.template.js +20 -0
- package/dist/templates/__start__.js +332 -0
- package/dist/templates/index.html +18 -0
- package/dist/templates/logo.png +0 -0
- package/dist/templates/manifest.json +1 -0
- package/dist/templates/patches/cannon.min.js +28 -0
- package/dist/templates/patches/lz4.js +10 -0
- package/dist/templates/patches/one-page-http-get.js +20 -0
- package/dist/templates/patches/one-page-inline-game-scripts.js +52 -0
- package/dist/templates/patches/one-page-mraid-resize-canvas.js +46 -0
- package/dist/templates/patches/p2.min.js +27 -0
- package/dist/templates/patches/playcraft-no-xhr.js +76 -0
- package/dist/templates/playcanvas-stable.min.js +16363 -0
- package/dist/templates/styles.css +43 -0
- package/dist/types.d.ts +114 -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/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 +56 -16
- package/dist/vite/platform-configs.d.ts +1 -0
- package/dist/vite/platform-configs.js +30 -1
- package/dist/vite/plugin-build-state.d.ts +2 -0
- package/dist/vite/plugin-build-state.js +5 -3
- 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 +15 -2
- package/dist/vite/plugin-platform.d.ts +5 -0
- package/dist/vite/plugin-platform.js +502 -36
- package/dist/vite/plugin-playcanvas.d.ts +1 -0
- package/dist/vite/plugin-playcanvas.js +181 -88
- 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/one-page-mraid-resize-canvas.js +18 -4
- package/templates/patches/playcraft-cta-adapter.js +129 -31
- package/templates/patches/scene-physics-defaults.js +49 -0
package/dist/platforms/base.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
+
import { minifyPatchCode } from '../utils/minify.js';
|
|
5
|
+
// 缓存压缩后的 CTA 适配器代码
|
|
6
|
+
let cachedMinifiedCTAAdapter = null;
|
|
7
|
+
// 缓存压缩后的平台脚本
|
|
8
|
+
const platformScriptCache = new Map();
|
|
4
9
|
export class PlatformAdapter {
|
|
5
10
|
constructor(options) {
|
|
6
11
|
this.options = options;
|
|
@@ -20,200 +25,93 @@ export class PlatformAdapter {
|
|
|
20
25
|
return await fs.readFile(templatePath, 'utf-8');
|
|
21
26
|
}
|
|
22
27
|
/**
|
|
23
|
-
*
|
|
28
|
+
* 压缩平台脚本代码
|
|
29
|
+
* @param scriptCode - 原始 JavaScript 代码
|
|
30
|
+
* @param cacheKey - 缓存键(通常是平台名称)
|
|
31
|
+
* @returns 压缩后的 <script> 标签
|
|
32
|
+
*/
|
|
33
|
+
async minifyPlatformScript(scriptCode, cacheKey) {
|
|
34
|
+
const key = cacheKey || this.getName();
|
|
35
|
+
if (platformScriptCache.has(key)) {
|
|
36
|
+
return `<script>${platformScriptCache.get(key)}</script>`;
|
|
37
|
+
}
|
|
38
|
+
const minified = await minifyPatchCode(scriptCode, key);
|
|
39
|
+
platformScriptCache.set(key, minified);
|
|
40
|
+
return `<script>${minified}</script>`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 获取 CTA 适配器脚本(异步版本,带压缩)
|
|
44
|
+
*/
|
|
45
|
+
async getCTAAdapterScriptAsync() {
|
|
46
|
+
if (cachedMinifiedCTAAdapter) {
|
|
47
|
+
return `<script>${cachedMinifiedCTAAdapter}</script>`;
|
|
48
|
+
}
|
|
49
|
+
const ctaCode = await this.readTemplateFile('playcraft-cta-adapter.js');
|
|
50
|
+
const minified = await minifyPatchCode(ctaCode, 'playcraft-cta-adapter.js');
|
|
51
|
+
cachedMinifiedCTAAdapter = minified;
|
|
52
|
+
return `<script>${minified}</script>`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 生成 Store URLs 注入脚本
|
|
56
|
+
* 将 storeUrls 以全局变量写入 HTML,供 CTA 适配器读取
|
|
57
|
+
*/
|
|
58
|
+
getStoreUrlsScript() {
|
|
59
|
+
const urls = this.options.storeUrls || {};
|
|
60
|
+
// 只有存在有效 URL 时才注入
|
|
61
|
+
if (!urls.ios && !urls.android) {
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
const safeUrls = {
|
|
65
|
+
...(urls.ios ? { ios: urls.ios } : {}),
|
|
66
|
+
...(urls.android ? { android: urls.android } : {}),
|
|
67
|
+
};
|
|
68
|
+
return `<script>window.__PLAYCRAFT_STORE_URLS__=${JSON.stringify(safeUrls)};</script>`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 获取 CTA 适配器脚本(同步版本,使用预压缩代码)
|
|
72
|
+
* @deprecated 推荐使用 getCTAAdapterScriptAsync
|
|
24
73
|
*/
|
|
25
74
|
getCTAAdapterScript() {
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.platform = 'dapi';
|
|
49
|
-
} else if (typeof ExitApi !== 'undefined') {
|
|
50
|
-
this.platform = 'google';
|
|
51
|
-
} else if (typeof window.BGY_MRAID !== 'undefined') {
|
|
52
|
-
this.platform = 'bigo';
|
|
53
|
-
} else if (typeof snapchatCta === 'function') {
|
|
54
|
-
this.platform = 'snapchat';
|
|
55
|
-
} else {
|
|
56
|
-
this.platform = 'unknown';
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
CTAAdapter.prototype.initialize = function() {
|
|
61
|
-
var self = this;
|
|
62
|
-
switch (this.platform) {
|
|
63
|
-
case 'facebook':
|
|
64
|
-
case 'google':
|
|
65
|
-
case 'bigo':
|
|
66
|
-
case 'snapchat':
|
|
67
|
-
this.isReady = true;
|
|
68
|
-
this.notifyReady();
|
|
69
|
-
break;
|
|
70
|
-
case 'mraid':
|
|
71
|
-
if (mraid.isReady && mraid.isReady()) {
|
|
72
|
-
this.isReady = true;
|
|
73
|
-
this.notifyReady();
|
|
74
|
-
} else if (mraid.addEventListener) {
|
|
75
|
-
mraid.addEventListener('ready', function() {
|
|
76
|
-
self.isReady = true;
|
|
77
|
-
self.notifyReady();
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
break;
|
|
81
|
-
case 'dapi':
|
|
82
|
-
if (dapi.isReady && dapi.isReady()) {
|
|
83
|
-
this.isReady = true;
|
|
84
|
-
this.notifyReady();
|
|
85
|
-
} else if (dapi.addEventListener) {
|
|
86
|
-
dapi.addEventListener('ready', function() {
|
|
87
|
-
self.isReady = true;
|
|
88
|
-
self.notifyReady();
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
break;
|
|
92
|
-
default:
|
|
93
|
-
this.isReady = true;
|
|
94
|
-
this.notifyReady();
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
CTAAdapter.prototype.notifyReady = function() {
|
|
100
|
-
for (var i = 0; i < this.readyCallbacks.length; i++) {
|
|
101
|
-
try {
|
|
102
|
-
this.readyCallbacks[i]();
|
|
103
|
-
} catch (e) {
|
|
104
|
-
console.error('[PlayCraft CTA] Ready callback error:', e);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
this.readyCallbacks = [];
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
CTAAdapter.prototype.onReady = function(callback) {
|
|
111
|
-
if (this.isReady) {
|
|
112
|
-
setTimeout(callback, 0);
|
|
113
|
-
} else {
|
|
114
|
-
this.readyCallbacks.push(callback);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
CTAAdapter.prototype.jump = function(options) {
|
|
119
|
-
options = options || {};
|
|
120
|
-
try {
|
|
121
|
-
switch (this.platform) {
|
|
122
|
-
case 'facebook':
|
|
123
|
-
if (typeof FbPlayableAd !== 'undefined' && FbPlayableAd.onCTAClick) {
|
|
124
|
-
FbPlayableAd.onCTAClick();
|
|
125
|
-
}
|
|
126
|
-
break;
|
|
127
|
-
case 'mraid':
|
|
128
|
-
if (typeof mraid !== 'undefined' && mraid.open) {
|
|
129
|
-
mraid.open(options.url || '');
|
|
130
|
-
}
|
|
131
|
-
break;
|
|
132
|
-
case 'dapi':
|
|
133
|
-
if (typeof dapi !== 'undefined' && dapi.openStoreUrl) {
|
|
134
|
-
dapi.openStoreUrl();
|
|
135
|
-
}
|
|
136
|
-
break;
|
|
137
|
-
case 'google':
|
|
138
|
-
if (typeof ExitApi !== 'undefined' && ExitApi.exit) {
|
|
139
|
-
ExitApi.exit();
|
|
140
|
-
}
|
|
141
|
-
break;
|
|
142
|
-
case 'bigo':
|
|
143
|
-
if (typeof window.BGY_MRAID !== 'undefined' && window.BGY_MRAID.open) {
|
|
144
|
-
window.BGY_MRAID.open();
|
|
145
|
-
}
|
|
146
|
-
break;
|
|
147
|
-
case 'snapchat':
|
|
148
|
-
if (typeof snapchatCta === 'function') {
|
|
149
|
-
snapchatCta();
|
|
150
|
-
}
|
|
151
|
-
break;
|
|
152
|
-
default:
|
|
153
|
-
this.fallbackJump(options.url);
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
} catch (e) {
|
|
157
|
-
console.error('[PlayCraft CTA] Jump failed:', e);
|
|
158
|
-
this.fallbackJump(options.url);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
CTAAdapter.prototype.fallbackJump = function(url) {
|
|
163
|
-
if (typeof FbPlayableAd !== 'undefined' && FbPlayableAd.onCTAClick) {
|
|
164
|
-
FbPlayableAd.onCTAClick();
|
|
165
|
-
} else if (typeof mraid !== 'undefined' && mraid.open) {
|
|
166
|
-
mraid.open(url || '');
|
|
167
|
-
} else if (typeof dapi !== 'undefined' && dapi.openStoreUrl) {
|
|
168
|
-
dapi.openStoreUrl();
|
|
169
|
-
} else if (typeof ExitApi !== 'undefined' && ExitApi.exit) {
|
|
170
|
-
ExitApi.exit();
|
|
171
|
-
} else if (typeof window.BGY_MRAID !== 'undefined' && window.BGY_MRAID.open) {
|
|
172
|
-
window.BGY_MRAID.open();
|
|
173
|
-
} else if (typeof snapchatCta === 'function') {
|
|
174
|
-
snapchatCta();
|
|
175
|
-
} else if (url) {
|
|
176
|
-
window.open(url, '_blank');
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
CTAAdapter.prototype.getPlatform = function() {
|
|
181
|
-
return this.platform;
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
CTAAdapter.prototype.checkReady = function() {
|
|
185
|
-
return this.isReady;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
var ctaAdapter = new CTAAdapter();
|
|
189
|
-
|
|
190
|
-
window.PlayCraftCTA = {
|
|
191
|
-
jump: function(options) { ctaAdapter.jump(options); },
|
|
192
|
-
jump2AppStore: function(options) { ctaAdapter.jump(options); },
|
|
193
|
-
onReady: function(callback) { ctaAdapter.onReady(callback); },
|
|
194
|
-
getPlatform: function() { return ctaAdapter.getPlatform(); },
|
|
195
|
-
isReady: function() { return ctaAdapter.checkReady(); }
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
window.jump2AppStore = window.PlayCraftCTA.jump2AppStore;
|
|
199
|
-
})();
|
|
200
|
-
</script>
|
|
201
|
-
`;
|
|
75
|
+
// 预压缩的 CTA 适配器代码(由 terser 压缩生成)
|
|
76
|
+
// 注意:此版本已移除硬编码地址,改为读取 window.__PLAYCRAFT_STORE_URLS__
|
|
77
|
+
const minifiedCode = `!function(){"use strict";var _s=(typeof window!=="undefined"&&window.__PLAYCRAFT_STORE_URLS__)||{};var IOS_STORE_URL=_s.ios||"";var ANDROID_STORE_URL=_s.android||"";function i(){var ua=navigator.userAgent||"";return(/iPad|iPhone|iPod/.test(ua)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1?"ios":/Android/i.test(ua)?"android":"unknown")==="ios"?IOS_STORE_URL:ANDROID_STORE_URL}function e(){this.platform=null,this.isReady=!1,this.readyCallbacks=[],this.detectPlatform(),this.initialize()}e.prototype.detectPlatform=function(){"undefined"!=typeof FbPlayableAd?this.platform="facebook":"undefined"!=typeof mraid?this.platform="mraid":"undefined"!=typeof dapi?this.platform="dapi":"undefined"!=typeof ExitApi?this.platform="google":void 0!==window.BGY_MRAID?this.platform="bigo":"function"==typeof snapchatCta?this.platform="snapchat":"function"==typeof window.openAppStore?this.platform="tiktok":"function"==typeof window.install?this.platform="mintegral":void 0!==window.TJ_API&&"function"==typeof window.TJ_API.click?this.platform="tapjoy":void 0!==window.NUC&&window.NUC.trigger&&"function"==typeof window.NUC.trigger.convert?this.platform="nucleo":void 0!==window.smxTracking&&"function"==typeof window.smxTracking.redirect?this.platform="smadex":(this.platform="unknown",console.warn("[PlayCraft CTA] Unknown platform")),console.log("[PlayCraft CTA] Platform:",this.platform)},e.prototype.initialize=function(){var i=this;switch(this.platform){case"facebook":case"google":case"bigo":case"snapchat":case"tiktok":case"mintegral":case"tapjoy":case"nucleo":case"smadex":default:this.isReady=!0,this.notifyReady();break;case"mraid":mraid.isReady&&mraid.isReady()?(this.isReady=!0,this.notifyReady()):mraid.addEventListener&&mraid.addEventListener("ready",function(){i.isReady=!0,i.notifyReady()});break;case"dapi":dapi.isReady&&dapi.isReady()?(this.isReady=!0,this.notifyReady()):dapi.addEventListener&&dapi.addEventListener("ready",function(){i.isReady=!0,i.notifyReady()})}},e.prototype.notifyReady=function(){for(var i=0;i<this.readyCallbacks.length;i++)try{this.readyCallbacks[i]()}catch(i){console.error("[PlayCraft CTA] Ready callback error:",i)}this.readyCallbacks=[]},e.prototype.onReady=function(i){this.isReady?setTimeout(i,0):this.readyCallbacks.push(i)},e.prototype.jump=function(e){e=e||{},this.isReady||console.warn("[PlayCraft CTA] Not ready"),console.log("[PlayCraft CTA] Jump - platform:",this.platform);try{switch(this.platform){case"facebook":"undefined"!=typeof FbPlayableAd&&FbPlayableAd.onCTAClick&&FbPlayableAd.onCTAClick();break;case"mraid":"undefined"!=typeof mraid&&mraid.open&&mraid.open(e.url||i());break;case"dapi":"undefined"!=typeof dapi&&dapi.openStoreUrl&&dapi.openStoreUrl();break;case"google":"undefined"!=typeof ExitApi&&ExitApi.exit&&ExitApi.exit();break;case"bigo":void 0!==window.BGY_MRAID&&window.BGY_MRAID.open&&window.BGY_MRAID.open();break;case"snapchat":"function"==typeof snapchatCta&&snapchatCta();break;case"tiktok":"function"==typeof window.openAppStore&&window.openAppStore();break;case"mintegral":"function"==typeof window.install&&window.install();break;case"tapjoy":void 0!==window.TJ_API&&window.TJ_API.click&&window.TJ_API.click();break;case"nucleo":void 0!==window.NUC&&window.NUC.trigger&&window.NUC.trigger.convert&&window.NUC.trigger.convert(e.url||i());break;case"smadex":void 0!==window.smxTracking&&window.smxTracking.redirect&&window.smxTracking.redirect();break;default:this.fallbackJump(e.url)}}catch(i){console.error("[PlayCraft CTA] Jump failed:",i),this.fallbackJump(e.url)}},e.prototype.fallbackJump=function(e){var o=e||i();if("undefined"!=typeof FbPlayableAd&&FbPlayableAd.onCTAClick)FbPlayableAd.onCTAClick();else if("undefined"!=typeof mraid&&mraid.open)mraid.open(o);else if("undefined"!=typeof dapi&&dapi.openStoreUrl)dapi.openStoreUrl();else if("undefined"!=typeof ExitApi&&ExitApi.exit)ExitApi.exit();else if(void 0!==window.BGY_MRAID&&window.BGY_MRAID.open)window.BGY_MRAID.open();else if("function"==typeof snapchatCta)snapchatCta();else if("function"==typeof window.openAppStore)window.openAppStore();else if("function"==typeof window.install)window.install();else if(void 0!==window.TJ_API&&window.TJ_API.click)window.TJ_API.click();else if(void 0!==window.NUC&&window.NUC.trigger&&window.NUC.trigger.convert)window.NUC.trigger.convert(o);else if(void 0!==window.smxTracking&&window.smxTracking.redirect)window.smxTracking.redirect();else{try{parent.postMessage("download","*")}catch(i){}o&&window.open(o,"_blank")}},e.prototype.getPlatform=function(){return this.platform},e.prototype.checkReady=function(){return this.isReady};var o=new e;window.PlayCraftCTA={jump:function(i){o.jump(i)},jump2AppStore:function(i){o.jump(i)},onReady:function(i){o.onReady(i)},getPlatform:function(){return o.getPlatform()},isReady:function(){return o.checkReady()}},window.jump2AppStore=window.PlayCraftCTA.jump2AppStore}();`;
|
|
78
|
+
return `<script>${minifiedCode}</script>`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 在 HTML 中注入 CTA 适配器(异步版本)
|
|
82
|
+
*/
|
|
83
|
+
async injectCTAAdapterAsync(html) {
|
|
84
|
+
const storeUrlsScript = this.getStoreUrlsScript();
|
|
85
|
+
const ctaScript = await this.getCTAAdapterScriptAsync();
|
|
86
|
+
const combined = storeUrlsScript + ctaScript;
|
|
87
|
+
// 在 </head> 之前或 </body> 之前注入
|
|
88
|
+
if (html.includes('</head>')) {
|
|
89
|
+
return html.replace('</head>', `${combined}\n</head>`);
|
|
90
|
+
}
|
|
91
|
+
else if (html.includes('</body>')) {
|
|
92
|
+
return html.replace('</body>', `${combined}\n</body>`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return combined + '\n' + html;
|
|
96
|
+
}
|
|
202
97
|
}
|
|
203
98
|
/**
|
|
204
|
-
* 在 HTML 中注入 CTA
|
|
99
|
+
* 在 HTML 中注入 CTA 适配器(同步版本)
|
|
100
|
+
* @deprecated 推荐使用 injectCTAAdapterAsync
|
|
205
101
|
*/
|
|
206
102
|
injectCTAAdapter(html) {
|
|
103
|
+
const storeUrlsScript = this.getStoreUrlsScript();
|
|
207
104
|
const ctaScript = this.getCTAAdapterScript();
|
|
105
|
+
const combined = storeUrlsScript + ctaScript;
|
|
208
106
|
// 在 </head> 之前或 </body> 之前注入
|
|
209
107
|
if (html.includes('</head>')) {
|
|
210
|
-
return html.replace('</head>', `${
|
|
108
|
+
return html.replace('</head>', `${combined}\n</head>`);
|
|
211
109
|
}
|
|
212
110
|
else if (html.includes('</body>')) {
|
|
213
|
-
return html.replace('</body>', `${
|
|
111
|
+
return html.replace('</body>', `${combined}\n</body>`);
|
|
214
112
|
}
|
|
215
113
|
else {
|
|
216
|
-
return
|
|
114
|
+
return combined + '\n' + html;
|
|
217
115
|
}
|
|
218
116
|
}
|
|
219
117
|
}
|
package/dist/platforms/bigo.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare class BigoAdapter 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(BIGO 要求)
|
package/dist/platforms/bigo.js
CHANGED
|
@@ -10,38 +10,38 @@ export class BigoAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'zip';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// BIGO Ads 需要 BIGO JS-SDK
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
gameReady: function() {
|
|
25
|
-
console.log('BIGO: game ready');
|
|
26
|
-
},
|
|
27
|
-
gameEnd: function() {
|
|
28
|
-
console.log('BIGO: game end');
|
|
15
|
+
const bigoScriptCode = `
|
|
16
|
+
window.BGY_MRAID = window.BGY_MRAID || {
|
|
17
|
+
open: function(url) {
|
|
18
|
+
console.log('BIGO CTA: opening store');
|
|
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';
|
|
29
24
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-->
|
|
25
|
+
var _s = (typeof window !== 'undefined' && window.__PLAYCRAFT_STORE_URLS__) || {};
|
|
26
|
+
var storeUrl = url || (getOS() === 'ios' ? (_s.ios || '') : (_s.android || ''));
|
|
27
|
+
window.open(storeUrl, '_blank');
|
|
28
|
+
},
|
|
29
|
+
gameReady: function() {
|
|
30
|
+
console.log('BIGO: game ready');
|
|
31
|
+
},
|
|
32
|
+
gameEnd: function() {
|
|
33
|
+
console.log('BIGO: game end');
|
|
34
|
+
}
|
|
35
|
+
};
|
|
42
36
|
`;
|
|
37
|
+
const sdkScript = `<script src="https://static-web.likeevideo.com/oss/material-ad/playable-ad-demo/bgy-mraid-sdk.js"></script>`;
|
|
38
|
+
const fallbackScript = await this.minifyPlatformScript(bigoScriptCode, 'bigo-sdk');
|
|
39
|
+
const comment = `<!-- BIGO: ZIP格式, config.json含orientation, 使用BGY_MRAID.open() -->`;
|
|
43
40
|
// 在 </head> 之前插入
|
|
44
|
-
|
|
41
|
+
html = html.replace('</head>', `${sdkScript}${fallbackScript}${comment}</head>`);
|
|
42
|
+
// 注入统一的 CTA 适配器
|
|
43
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
44
|
+
return html;
|
|
45
45
|
}
|
|
46
46
|
getPlatformScript() {
|
|
47
47
|
return `
|
|
@@ -4,6 +4,6 @@ export declare class FacebookAdapter 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,22 +10,33 @@ export class FacebookAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'html';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// Facebook 需要 FbPlayableAd API
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const fbScriptCode = `
|
|
16
|
+
window.FbPlayableAd = window.FbPlayableAd || {
|
|
17
|
+
onCTAClick: function() {
|
|
18
|
+
console.log('Facebook CTA clicked');
|
|
19
|
+
function getOS(){
|
|
20
|
+
var ua = navigator.userAgent || '';
|
|
21
|
+
if (/iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) {
|
|
22
|
+
return 'ios';
|
|
23
|
+
} else if (/Android/i.test(ua)) {
|
|
24
|
+
return 'android';
|
|
25
|
+
}
|
|
26
|
+
return 'unknown';
|
|
21
27
|
}
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
var _s = window.__PLAYCRAFT_STORE_URLS__ || {};
|
|
29
|
+
var url = getOS() === 'ios' ? (_s.ios || '') : (_s.android || '');
|
|
30
|
+
window.open(url, '_blank');
|
|
31
|
+
}
|
|
32
|
+
};
|
|
24
33
|
`;
|
|
34
|
+
// 压缩平台脚本
|
|
35
|
+
const fbScript = await this.minifyPlatformScript(fbScriptCode, 'facebook-api');
|
|
25
36
|
// 在 </head> 之前插入平台特定的 API
|
|
26
37
|
html = html.replace('</head>', `${fbScript}</head>`);
|
|
27
38
|
// 注入统一的 CTA 适配器
|
|
28
|
-
html = this.
|
|
39
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
29
40
|
return html;
|
|
30
41
|
}
|
|
31
42
|
getPlatformScript() {
|
|
@@ -4,7 +4,7 @@ export declare class GoogleAdapter 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/google.js
CHANGED
|
@@ -10,30 +10,37 @@ export class GoogleAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'zip';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// Google Ads 需要 exitapi.js
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
const googleScriptCode = `
|
|
16
|
+
window.ExitApi = window.ExitApi || {
|
|
17
|
+
exit: function() {
|
|
18
|
+
console.log('Google Ads CTA: opening store');
|
|
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';
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- 必须包含 <!DOCTYPE html> 和完整的 html/head/body 结构
|
|
30
|
-
- 使用 <meta name="ad.orientation" content="portrait|landscape"> 声明方向
|
|
31
|
-
- 支持 Google 托管库:Fonts/jQuery/Greensock/CreateJS
|
|
32
|
-
-->
|
|
33
|
-
<meta name="ad.size" content="320x480,480x320,768x1024,1024x768">
|
|
25
|
+
var _s = window.__PLAYCRAFT_STORE_URLS__ || {};
|
|
26
|
+
var url = getOS() === 'ios' ? (_s.ios || '') : (_s.android || '');
|
|
27
|
+
window.open(url, '_blank');
|
|
28
|
+
}
|
|
29
|
+
};
|
|
34
30
|
`;
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
const googleScript = await this.minifyPlatformScript(googleScriptCode, 'google-exitapi');
|
|
32
|
+
const meta = `<meta name="ad.size" content="320x480,480x320,768x1024,1024x768">`;
|
|
33
|
+
const mobileMeta = `<meta name="mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-capable" content="yes">`;
|
|
34
|
+
const orientationMeta = `<meta name="screen-orientation" content="landscape"><meta name="orientation" content="landscape">`;
|
|
35
|
+
const comment = `<!-- Google Ads: ZIP 最大 5MB, 512 文件, 使用 ExitApi.exit() -->`;
|
|
36
|
+
// 替换模板中已有的 viewport meta,增加 Google 所需的属性
|
|
37
|
+
const googleViewport = `<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, viewport-fit=cover">`;
|
|
38
|
+
html = html.replace(/<meta\s+name=['"]viewport['"][^>]*>/i, googleViewport);
|
|
39
|
+
// 在 </head> 之前插入 Google 特有标签(横屏锁定、mobile-web-app、ad.size 等)
|
|
40
|
+
html = html.replace('</head>', `${googleScript}${comment}${mobileMeta}${orientationMeta}${meta}</head>`);
|
|
41
|
+
// 注入统一的 CTA 适配器
|
|
42
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
43
|
+
return html;
|
|
37
44
|
}
|
|
38
45
|
getPlatformScript() {
|
|
39
46
|
return `
|
package/dist/platforms/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { BigoAdapter } from './bigo.js';
|
|
|
12
12
|
import { InMobiAdapter } from './inmobi.js';
|
|
13
13
|
import { AdikteevAdapter } from './adikteev.js';
|
|
14
14
|
import { RemergeAdapter } from './remerge.js';
|
|
15
|
+
import { MintegralAdapter } from './mintegral.js';
|
|
15
16
|
export function createPlatformAdapter(options) {
|
|
16
17
|
switch (options.platform) {
|
|
17
18
|
case 'playcraft':
|
|
@@ -42,6 +43,8 @@ export function createPlatformAdapter(options) {
|
|
|
42
43
|
return new AdikteevAdapter(options);
|
|
43
44
|
case 'remerge':
|
|
44
45
|
return new RemergeAdapter(options);
|
|
46
|
+
case 'mintegral':
|
|
47
|
+
return new MintegralAdapter(options);
|
|
45
48
|
default:
|
|
46
49
|
throw new Error(`Unsupported platform: ${options.platform}`);
|
|
47
50
|
}
|
|
@@ -61,3 +64,4 @@ export { BigoAdapter } from './bigo.js';
|
|
|
61
64
|
export { InMobiAdapter } from './inmobi.js';
|
|
62
65
|
export { AdikteevAdapter } from './adikteev.js';
|
|
63
66
|
export { RemergeAdapter } from './remerge.js';
|
|
67
|
+
export { MintegralAdapter } from './mintegral.js';
|
|
@@ -4,7 +4,7 @@ export declare class InMobiAdapter 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/inmobi.js
CHANGED
|
@@ -10,42 +10,37 @@ export class InMobiAdapter extends PlatformAdapter {
|
|
|
10
10
|
getDefaultFormat() {
|
|
11
11
|
return 'zip';
|
|
12
12
|
}
|
|
13
|
-
modifyHTML(html, assets) {
|
|
13
|
+
async modifyHTML(html, assets) {
|
|
14
14
|
// InMobi 需要 MRAID 支持
|
|
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
|
-
- InMobi 要求 ZIP 格式
|
|
39
|
-
- 使用 MRAID API 跳转应用商店
|
|
40
|
-
- 使用 mraid.open() 跳转
|
|
41
|
-
- 不允许自动重定向
|
|
42
|
-
-->
|
|
43
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
15
|
+
const inmobiScriptCode = `
|
|
16
|
+
window.mraid = window.mraid || {
|
|
17
|
+
getVersion: function() { return '2.0'; },
|
|
18
|
+
isReady: function() { return true; },
|
|
19
|
+
open: function(url) {
|
|
20
|
+
console.log('InMobi 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') setTimeout(listener, 0);
|
|
29
|
+
},
|
|
30
|
+
removeEventListener: function(event, listener) {},
|
|
31
|
+
getState: function() { return 'default'; },
|
|
32
|
+
getPlacementType: function() { return 'interstitial'; },
|
|
33
|
+
getMaxSize: function() { return { width: window.innerWidth, height: window.innerHeight }; },
|
|
34
|
+
getCurrentPosition: function() { return { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight }; },
|
|
35
|
+
getScreenSize: function() { return { width: screen.width, height: screen.height }; }
|
|
36
|
+
};
|
|
44
37
|
`;
|
|
38
|
+
const inmobiScript = await this.minifyPlatformScript(inmobiScriptCode, 'inmobi-mraid');
|
|
39
|
+
const comment = `<!-- InMobi: ZIP格式, 使用mraid.open() -->`;
|
|
45
40
|
// 在 </head> 之前插入平台特定的 API
|
|
46
|
-
html = html.replace('</head>', `${inmobiScript}</head>`);
|
|
41
|
+
html = html.replace('</head>', `${inmobiScript}${comment}</head>`);
|
|
47
42
|
// 注入统一的 CTA 适配器
|
|
48
|
-
html = this.
|
|
43
|
+
html = await this.injectCTAAdapterAsync(html);
|
|
49
44
|
return html;
|
|
50
45
|
}
|
|
51
46
|
getPlatformScript() {
|
|
@@ -4,7 +4,7 @@ export declare class IronSourceAdapter 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
|
}
|