提交 46f4450d 作者: yanfuxing

增加小游戏导出目录,进Unity工程

上级 c806cde6
......@@ -14,7 +14,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
tag: 0
wasmResourceUrl: http://
OutputDir: E:\UnityProject\UnityTrunckPro_SDK\tt_miniGame
OutputDir: E:\UnitySDKTrunck_Comm\UnityTrunckPro_SDK\MiniGameExport\Tiktok
useByteAudioAPI: 0
wasmMemorySize: 128
isWebGL2: 0
......@@ -52,7 +52,7 @@ MonoBehaviour:
_appId: ttb5fdc3402aff253307
version:
autoVersion: 0
_webglPackagePath: E:\UnityProject\UnityTrunckPro_SDK\tt_miniGame\webgl_package-20251125_113539.zip
_webglPackagePath: E:\UnitySDKTrunck_Comm\UnityTrunckPro_SDK\MiniGameExport\Tiktok\webgl_package-20251125_151148.zip
_orientation: 0
_iOSPerformancePlus: 0
_menuButtonStyle: 0
......
......@@ -19,8 +19,8 @@ MonoBehaviour:
assetLoadType: 1
compressDataPackage: 0
VideoUrl:
relativeDST: E:/MiniGame/WeChatDaoChu
DST: E:/MiniGame/WeChatDaoChu
relativeDST: E:/UnitySDKTrunck_Comm/UnityTrunckPro_SDK/MiniGameExport/WeChat
DST: E:/UnitySDKTrunck_Comm/UnityTrunckPro_SDK/MiniGameExport/WeChat
StreamCDN:
bundleHashLength: 32
bundlePathIdentifier: StreamingAssets;
......
/* eslint-disable no-multi-assign */
/* eslint-disable @typescript-eslint/naming-convention */
const { version, SDKVersion } = wx.getAppBaseInfo ? wx.getAppBaseInfo() : wx.getSystemInfoSync();
const { platform, system } = wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync();
const accountInfo = wx.getAccountInfoSync();
const envVersion = accountInfo?.miniProgram?.envVersion;
function compareVersion(v1, v2) {
if (!v1 || !v2) {
return false;
}
return (v1
.split('.')
.map(v => v.padStart(2, '0'))
.join('')
>= v2
.split('.')
.map(v => v.padStart(2, '0'))
.join(''));
}
export const isDebug = false;
export const isPc = platform === 'windows' || platform === 'mac';
export const isIOS = platform === 'ios';
export const isAndroid = platform === 'android';
export const isDevtools = platform === 'devtools';
export const isMobile = !isPc && !isDevtools;
export const isDevelop = envVersion === 'develop';
// 是否禁止**开通了高性能模式**的小游戏在不支持的iOS设备上回退成普通模式,回退可能导致无法正常体验游戏
// @ts-ignore
const disableHighPerformanceFallback = false && isIOS;
// 是否iOS高性能模式
export const isH5Renderer = GameGlobal.isIOSHighPerformanceMode;
// 操作系统版本号
const systemVersionArr = system ? system.split(' ') : [];
const systemVersion = systemVersionArr.length ? systemVersionArr[systemVersionArr.length - 1] : '';
// pc微信版本号不一致,需要>=3.3
const isPcWeChatVersionValid = compareVersion(version, '3.3');
// 支持unity小游戏,需要基础库>=2.14.0,但低版本基础库iOS存在诸多问题,将版本最低版本提高到2.17.0
const isLibVersionValid = compareVersion(SDKVersion, '2.17.0');
// 如果是iOS高性能模式,基础库需要>=2.23.1
const isH5LibVersionValid = compareVersion(SDKVersion, '2.23.1');
// 压缩纹理需要iOS系统版本>=14.0,检测到不支持压缩纹理时会提示升级系统
const isIOSH5SystemVersionValid = compareVersion(systemVersion, '14.0');
// iOS系统版本>=15支持webgl2,高性能模式+无此系统要求
const isIOSWebgl2SystemVersionValid = compareVersion(systemVersion, '15.0') || GameGlobal.isIOSHighPerformanceModePlus;
// Android客户端版本>=8.0.19支持webgl2
const isAndroidWebGL2ClientVersionValid = compareVersion(version, '8.0.19');
// 是否用了webgl2
const isWebgl2 = () => GameGlobal.managerConfig.contextConfig.contextType === 2;
// 是否支持BufferURL
export const isSupportBufferURL = !isPc
&& (isH5Renderer
? compareVersion(SDKVersion, '2.29.1') && compareVersion(version, '8.0.30')
: typeof wx.createBufferURL === 'function');
// 安卓innerAudio支持playbackRate
export const isSupportPlayBackRate = !isAndroid || compareVersion(version, '8.0.23');
// IOS innerAudio支持复用时再次触发onCanplay
export const isSupportCacheAudio = !isIOS || compareVersion(version, '8.0.31');
// // 安卓旧客户端版本innerAudio偶现会导致闪退,大于等于8.0.38才使用innerAudio减少内存
export const isSupportInnerAudio = compareVersion(version, '8.0.38');
// 检查是否支持brotli压缩,pc基础库>=2.29.2,真机基础库>=2.21.1
// @ts-ignore
const isPcBrotliInvalid = isPc && !compareVersion(SDKVersion, true ? '2.29.2' : '2.32.3');
const isMobileBrotliInvalid = isMobile && !compareVersion(SDKVersion, '2.21.1');
// @ts-ignore
const isBrotliInvalid = false && (isPcBrotliInvalid || isMobileBrotliInvalid);
// iOS系统版本>=17.5时,小游戏退后台会导致异常
export const isIOS175 = compareVersion(systemVersion, '17.5') && isH5Renderer;
// 是否支持开放数据域渲染模式,使用ScreenCanvas模式可以优化ToTempFilePath的使用,PC 上 ScreenCanvas 模式事件处理有问题,PC 先禁止这个模式
export const isSupportSharedCanvasMode = compareVersion(SDKVersion, '3.6.6') && !isPc;
// 是否能以iOS高性能模式运行
// 请勿修改GameGlobal.canUseH5Renderer赋值!!!
GameGlobal.canUseH5Renderer = isH5Renderer && isH5LibVersionValid;
// iOS高性能模式定期GC
GameGlobal.canUseiOSAutoGC = isH5Renderer && compareVersion(SDKVersion, '2.32.1');
// pc微信版本不满足要求
const isPcInvalid = isPc && !isPcWeChatVersionValid;
// 移动设备基础库版本或客户端版本不支持运行unity小游戏
const isMobileInvalid = isMobile && !isLibVersionValid;
// 基础库/客户端不支持iOS高性能模式
const isIOSH5Invalid = (isH5Renderer && !isH5LibVersionValid) || (!isH5Renderer && disableHighPerformanceFallback);
// 是否支持VideoPlayer组件,注意:开发者工具需要1.06.2310312以上版本
export const isSupportVideoPlayer = (isIOS && compareVersion(SDKVersion, '3.1.1')) || (isAndroid && compareVersion(SDKVersion, '3.0.0')) || ((isPc || isDevtools) && compareVersion(SDKVersion, '3.2.1'));
// 视情况添加,没用到对应能力就不需要判断
// 是否支持webgl2
const isWebgl2SystemVersionInvalid = () => isWebgl2() && ((!isIOSWebgl2SystemVersionValid && isIOS) || (isAndroid && !isAndroidWebGL2ClientVersionValid));
// IOS高性能模式2.25.3以上基础库需要手动启动webAudio
export const webAudioNeedResume = compareVersion(SDKVersion, '2.25.3') && isH5Renderer;
// 满足iOS高性能条件,但未开通高性能模式
const needToastEnableHpMode = isDevelop && isIOS && isH5LibVersionValid && isIOSH5SystemVersionValid && !isH5Renderer;
/**
* 判断环境是否可使用coverview
* coverview实际需要基础库版本>=2.16.1,但因为移动端要>=2.17.0才能运行,所以移动端基本都支持coverview
*
* @export
* @returns
*/
export function canUseCoverview() {
return isMobile || isDevtools;
}
if (needToastEnableHpMode) {
console.error('此AppID未开通高性能模式\n请前往mp后台-能力地图-开发提效包-高性能模式开通\n可大幅提升游戏运行性能');
// setTimeout(() => {
// wx.showModal({
// title: '[开发版提示]建议',
// content: '此AppID未开通高性能模式\n请前往mp后台-能力地图-开发提效包-高性能模式开通\n可大幅提升游戏运行性能',
// showCancel: false,
// })
// }, 10000);
}
// @ts-ignore
if (isIOS && typeof 0 === 'number' && 0 > 0) {
// @ts-ignore
window.devicePixelRatio = 0;
}
else if (isPc) {
try {
if (window.devicePixelRatio < 2) {
window.devicePixelRatio = 2;
}
}
catch (e) {
console.warn(e);
}
}
export default () => new Promise((resolve) => {
if (!isDevtools) {
if (isPcInvalid
|| isMobileInvalid
|| isIOSH5Invalid
|| isWebgl2SystemVersionInvalid()
|| isBrotliInvalid) {
let updateWechat = true;
let content = '当前微信版本过低\n请更新微信后进行游戏';
if (isIOS) {
if (!isIOSH5SystemVersionValid || (isWebgl2SystemVersionInvalid() && isIOS)) {
content = '当前操作系统版本过低\n请更新iOS系统后进行游戏';
updateWechat = false;
}
}
wx.showModal({
title: '提示',
content,
showCancel: false,
confirmText: updateWechat ? '更新微信' : '确定',
success(res) {
if (res.confirm) {
const showUpdateWechat = updateWechat && typeof wx.createBufferURL === 'function';
if (showUpdateWechat) {
wx.updateWeChatApp();
}
else {
wx.exitMiniProgram({
success: () => { },
});
}
}
},
});
return resolve(false);
}
}
return resolve(true);
});
const events = [];
const EventsManager = {
/**
* 注册一个事件并持续监听
* @param eventName 事件名称
* @param callback 事件的触发函数
*/
on(eventName, callback) {
events.push({
eventName,
callback,
once: false,
});
},
/**
* 注册一个事件并最多只触发一次
* @param eventName 事件名称
* @param callback 事件的触发函数
*/
once(eventName, callback) {
events.push({
eventName,
callback,
once: true,
});
},
/**
* 卸载一个事件
* @param eventName 事件名称
* @param callback 事件句柄,若缺省将卸载所有同名事件
*/
off(eventName, callback) {
events.forEach((item, index) => {
if (item.eventName === eventName) {
if (!callback || item.callback === callback) {
events.splice(index, 1);
}
}
});
},
emit(eventName, ...args) {
const res = [];
const indexs = [];
events.forEach((item, index) => {
if (item.eventName === eventName) {
res.push(item.callback(...args));
if (item.once) {
indexs.unshift(index);
}
}
});
indexs.forEach((value) => {
events.splice(value, 1);
});
return res;
},
};
GameGlobal.events = EventsManager;
// @ts-nocheck
import './wxSdkBridge'
import './weapp-adapter';
import './events';
import './texture-config';
import unityNamespace from './unity-namespace';
import './webgl.wasm.framework.unityweb';
import './unity-sdk/index';
import checkVersion from './check-version';
import {
launchEventType,
scaleMode
} from './plugin-config';
import {
preloadWxCommonFont
} from './unity-sdk/font/index';
const managerConfig = {
DATA_FILE_MD5: 'd5b2de52b4fa5ee7',
CODE_FILE_MD5: '0a580504c5172fc9',
GAME_NAME: 'webgl',
APPID: 'wx8533d0cf626f6059',
DATA_FILE_SIZE: '4799297',
OPT_DATA_FILE_SIZE: '$OPT_DATA_FILE_SIZE',
DATA_CDN: '',
// 资源包是否作为小游戏分包加载
loadDataPackageFromSubpackage: true,
// 资源包放小游戏分包加载时,是否br压缩
compressDataPackage: false,
// 需要在网络空闲时预加载的资源,支持如下形式的路径
preloadDataList: [
// 'DATA_CDN/StreamingAssets/WebGL/textures_8d265a9dfd6cb7669cdb8b726f0afb1e',
// '/WebGL/sounds_97cd953f8494c3375312e75a29c34fc2'
,
],
contextConfig: {
contextType: 1,
contextExt: {
enableGLX: false,
enableMetal: false,
}
},
PROFILER_UPLOAD_URL: '',
};
GameGlobal.managerConfig = managerConfig;
// 版本检查
checkVersion().then((enable) => {
if (enable) {
// eslint-disable-next-line @typescript-eslint/naming-convention
let UnityManager;
try {
// @ts-ignore
UnityManager = requirePlugin('UnityPlugin', {
enableRequireHostModule: true,
customEnv: {
wx,
unityNamespace,
document,
canvas,
events: GameGlobal.events,
WXWASMSDK: GameGlobal.WXWASMSDK,
},
}).default;
} catch (error) {
GameGlobal.realtimeLogManager.error(error);
// logManager不支持自动处理错误对象
GameGlobal.logmanager.warn(error.stack);
console.error('requirePlugin:', error);
if (error.message.indexOf('not defined') !== -1) {
console.error('!!!插件需要申请才可使用\n请勿使用测试AppID,并登录 https://mp.weixin.qq.com/ 并前往:能力地图-开发提效包-快适配 开通\n阅读文档获取详情:https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/Transform.md');
}
}
// JS堆栈能显示更完整
Error.stackTraceLimit = Infinity;
Object.assign(managerConfig, {
// callmain结束后立即隐藏封面视频
hideAfterCallmain: true,
loadingPageConfig: {
// 以下是默认值
totalLaunchTime: 7000,
animationDuration: 100,
/**
* !!注意:修改设计宽高和缩放模式后,需要修改文字和进度条样式。默认设计尺寸为667*375
*/
designWidth: 0,
designHeight: 0,
scaleMode: scaleMode.default,
// 以下配置的样式,尺寸相对设计宽高
textConfig: {
firstStartText: '首次加载请耐心等待',
downloadingText: ['正在加载资源'],
compilingText: '编译中',
initText: '初始化中',
completeText: '开始游戏',
textDuration: 1500,
// 文字样式
style: {
bottom: 64,
height: 24,
width: 240,
lineHeight: 24,
color: '#ffffff',
fontSize: 12,
},
},
// 进度条样式
barConfig: {
style: {
width: 240,
height: 24,
padding: 2,
bottom: 64,
backgroundColor: '#07C160',
},
},
// 一般不修改,控制icon样式
iconConfig: {
visible: true,
style: {
width: 64,
height: 23,
bottom: 20,
},
},
// 加载页的素材配置
materialConfig: {
// 背景图或背景视频,两者都填时,先展示背景图,视频可播放后,播放视频
backgroundImage: 'images/background.jpg',
backgroundVideo: '',
iconImage: 'images/unity_logo.png', // icon图片,一般不更换
},
},
});
GameGlobal.managerConfig = managerConfig;
// 显示启动封面
const gameManager = new UnityManager(managerConfig);
gameManager.onLaunchProgress((e) => {
// interface LaunchEvent {
// type: LaunchEventType;
// data: {
// costTimeMs: number; // 阶段耗时
// runTimeMs: number; // 总耗时
// loadDataPackageFromSubpackage: boolean; // 首包资源是否通过小游戏分包加载
// isVisible: boolean; // 当前是否处于前台,onShow/onHide
// useCodeSplit: boolean; // 是否使用代码分包
// isHighPerformance: boolean; // 是否iOS高性能模式
// needDownloadDataPackage: boolean; // 本次启动是否需要下载资源包
// };
// }
if (e.type === launchEventType.launchPlugin) {}
if (e.type === launchEventType.loadWasm) {}
if (e.type === launchEventType.compileWasm) {}
if (e.type === launchEventType.loadAssets) {}
if (e.type === launchEventType.readAssets) {}
if (e.type === launchEventType.prepareGame) {}
});
gameManager.onModulePrepared(() => {
// eslint-disable-next-line no-restricted-syntax
for (const key in unityNamespace) {
// 动态修改DATA_CDN后,同步修改全局对象
if (!GameGlobal.hasOwnProperty(key) || key === 'DATA_CDN') {
GameGlobal[key] = unityNamespace[key];
} else {}
}
managerConfig.DATA_CDN = GameGlobal.DATA_CDN;
gameManager.assetPath = `${(managerConfig.DATA_CDN || '').replace(/\/$/, '')}/Assets`;
preloadWxCommonFont();
});
// 插件捕获到引擎错误后,会通过此事件抛给游戏
gameManager.onLogError = function(err) {
GameGlobal.realtimeLogManager.error(err);
const isErrorObj = err && err.stack;
GameGlobal.logmanager.warn(isErrorObj ? err.stack : err);
};
// iOS高性能模式定期GC
if (GameGlobal.canUseiOSAutoGC && unityNamespace.iOSAutoGCInterval !== 0) {
setInterval(() => {
wx.triggerGC();
}, unityNamespace.iOSAutoGCInterval);
}
// 开始执行游戏启动流程
gameManager.startGame();
GameGlobal.manager = gameManager;
GameGlobal.events.on('launchOperaPushMsgToWasm', (callback, args) => GameGlobal.WXWASMSDK.WXLaunchOperaBridgeToC(callback, args));
// eslint-disable-next-line @typescript-eslint/no-unused-vars
GameGlobal.events.on('createWorker', (worker) => {
// worker created
});
}
});
\ No newline at end of file
{
"deviceOrientation" : "portrait",
"iOSHighPerformance" : true,
"iOSHighPerformance+" : false,
"subpackages" : [
{
"name" : "wasmcode",
"root" : "wasmcode/"
},
{
"name" : "data-package",
"root" : "data-package/"
}
],
"parallelPreloadSubpackages" : [
{
"name" : "wasmcode"
},
{
"name" : "data-package"
}
],
"plugins" : {
"UnityPlugin" : {
"version" : "1.2.84",
"provider" : "wxe5a48f1ed5f544b7",
"contexts" : [
{
"type" : "isolatedContext"
}
]
}
},
"workers" : "workers"
}
\ No newline at end of file
export const launchEventType = {
launchPlugin: 0,
loadWasm: 1,
compileWasm: 2,
loadAssets: 3,
readAssets: 5,
prepareGame: 6, // 初始化引擎
};
// https://docs.egret.com/engine/docs/screenAdaptation/zoomMode
export const scaleMode = {
default: '',
noBorder: 'NO_BORDER',
exactFit: 'EXACT_FIT',
fixedHeight: 'FIXED_HEIGHT',
fixedWidth: 'FIXED_WIDTH',
showAll: 'SHOW_ALL',
fixedNarrow: 'FIXED_NARROW',
fixedWide: 'FIXED_WIDE',
};
{
"description": "项目配置文件",
"setting": {
"urlCheck": false,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": true,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"useMultiFrameRuntime": true,
"useApiHook": false,
"disableUseStrict": false,
"babelSetting": {
"ignore": [
"webgl.wasm.framework.unityweb.js"
],
"disablePlugins": [],
"outputPath": ""
},
"useIsolateContext": true,
"useCompilerModule": true,
"userConfirmedUseCompilerModuleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"compileWorklet": false,
"minifyWXSS": true,
"minifyWXML": true,
"localPlugins": false,
"useCompilerPlugins": false,
"condition": false,
"swc": false,
"disableSWC": true
},
"compileType": "game",
"libVersion": "latest",
"appid": "wx8533d0cf626f6059",
"projectname": "wxSdk",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"packOptions": {
"ignore": [
{
"value": ".plugincache",
"type": "folder"
},
{
"value": ".symbols.unityweb",
"type": "suffix"
},
{
"value": ".symbols.unityweb.br",
"type": "suffix"
}
],
"include": []
},
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
},
"isGameTourist": false,
"editorSetting": {}
}
\ No newline at end of file
{
"libVersion": "3.11.2",
"projectname": "wxSdk",
"condition": {},
"setting": {
"urlCheck": false,
"coverView": true,
"lazyloadPlaceholderEnable": false,
"skylineRenderEnable": false,
"preloadBackgroundData": false,
"autoAudits": false,
"useApiHook": false,
"useApiHostProcess": true,
"showShadowRootInWxmlPanel": true,
"useStaticServer": false,
"useLanDebug": false,
"showES6CompileOption": false,
"compileHotReLoad": false,
"checkInvalidKey": true,
"ignoreDevUnusedFiles": true,
"bigPackageSizeSupport": false,
"useIsolateContext": true
}
}
\ No newline at end of file
GameGlobal.USED_TEXTURE_COMPRESSION = false;
GameGlobal.TEXTURE_PARALLEL_BUNDLE = false;
GameGlobal.TEXTURE_BUNDLES = '';
// @ts-nocheck
const unityNamespace = {
canvas: GameGlobal.canvas,
// cache width
canvas_width: GameGlobal.canvas.width,
// cache height
canvas_height: GameGlobal.canvas.height,
navigator: GameGlobal.navigator,
XMLHttpRequest: GameGlobal.XMLHttpRequest,
// 是否显示耗时的弹框,默认开发版时显示弹出耗时弹框
hideTimeLogModal: true,
// 是否打印详细日志
enableDebugLog: false,
// 自定义bundle中的hash长度
bundleHashLength: 32,
// 单位Bytes, 1MB = 1024 KB = 1024*1024Bytes
releaseMemorySize: 31457280,
unityVersion: '2022.3.62f2c1',
// Color Space: Gamma、Linear、Uninitialized(未初始化的颜色空间)
unityColorSpace: 'Gamma',
convertPluginVersion: '202511060320',
// 拼在StreamingAssets前面的path,DATA_CDN + streamingUrlPrefixPath + StreamingAssets
streamingUrlPrefixPath: '',
// DATA_CDN + dataFileSubPrefix + datafilename
dataFileSubPrefix: '',
// 当前appid扩容后,通过本字段告知插件本地存储最大容量,单位MB
maxStorage: 200,
// 纹理中的hash长度
texturesHashLength: 8,
// 纹理存放路径
texturesPath: 'Assets/Textures',
// 是否需要缓存纹理,
needCacheTextures: true,
// AssetBundle在内存中的存活时间
ttlAssetBundle: 5,
// 是否显示性能面板
enableProfileStats: false,
// 是否预载微信系统字体
preloadWXFont: false,
// iOS高性能模式定期GC间隔
iOSAutoGCInterval: 10000,
// 是否使用微信压缩纹理
usedTextureCompression: GameGlobal.USED_TEXTURE_COMPRESSION,
// 是否使用autostreaming
usedAutoStreaming: false,
// 是否显示渲染日志(dev only)
enableRenderAnalysisLog: false,
// 是否dotnet runtime
useDotnetRuntime: false,
// 是否用了多线程brotli压缩
useBrotliMT: true,
// Boot config配置,包含例如wait-for-native-debugger、player-connection-ip等信息
bootConfig: 'player-connection-ip=192.168.55.194',
// 是否以Development Build构建
isDevelopmentBuild: false,
// 是否以Profiling Build导出
isProfilingBuild: false,
// 预留的堆内存
unityHeapReservedMemory: 256,
// 是否向Perfstream上报数据
sendData2PerfStream: false,
};
// 最佳实践检测配置
unityNamespace.monitorConfig = {
// 显示优化建议弹框
showSuggestModal: true,
// 是否开启检测(只影响开发版/体验版,线上版本不会检测)
enableMonitor: true,
// 帧率低于此值的帧会被记录,用于分析长耗时帧,做了限帧的游戏应该适当调低
fps: 10,
// 是否一直检测到游戏可交互完成
showResultAfterLaunch: true,
// 仅当showResultAfterLaunch=false时有效, 在引擎初始化完成(即callmain)后多长时间停止检测
monitorDuration: 30000,
};
// 判断是否需要自动缓存的文件,返回true自动缓存;false不自动缓存
unityNamespace.isCacheableFile = function (path) {
// 判定为下载bundle的路径标识符,此路径下的下载,会自动缓存
const cacheableFileIdentifier = ["StreamingAssets"];
// 命中路径标识符的情况下,并不是所有文件都有必要缓存,过滤下不需要缓存的文件
const excludeFileIdentifier = ["json"];
if (cacheableFileIdentifier.some(identifier => path.includes(identifier)
&& excludeFileIdentifier.every(excludeIdentifier => !path.includes(excludeIdentifier)))) {
return true;
}
return false;
};
// 是否上报此条网络异常, 返回true则上报, 返回false则忽略
unityNamespace.isReportableHttpError = function (_info) {
// const { url, error } = _info;
return true;
};
// 判断是否是AssetBundle
unityNamespace.isWXAssetBundle = function (path) {
return unityNamespace.WXAssetBundles.has(unityNamespace.PathInFileOS(path));
};
unityNamespace.PathInFileOS = function (path) {
return path.replace(`${wx.env.USER_DATA_PATH}/__GAME_FILE_CACHE`, '');
};
unityNamespace.WXAssetBundles = new Map();
// 清理缓存时是否可被自动清理;返回true可自动清理;返回false不可自动清理
unityNamespace.isErasableFile = function (info) {
// 用于特定AssetBundle的缓存保持
if (unityNamespace.WXAssetBundles.has(info.path)) {
return false;
}
// 达到缓存上限时,不会被自动清理的文件
const inErasableIdentifier = [];
if (inErasableIdentifier.some(identifier => info.path.includes(identifier))) {
return false;
}
return true;
};
GameGlobal.WebAssembly = GameGlobal.WXWebAssembly;
GameGlobal.unityNamespace = GameGlobal.unityNamespace || unityNamespace;
GameGlobal.realtimeLogManager = wx.getRealtimeLogManager();
GameGlobal.logmanager = wx.getLogManager({ level: 0 });
GameGlobal.disableMultiTouch = false;
// 提前监听错误并打日志
function bindGloblException() {
// 默认上报小游戏实时日志与用户反馈日志(所有error日志+小程序框架异常)
wx.onError((result) => {
// 若manager已初始化,则直接用manager打日志即可
if (GameGlobal.manager) {
GameGlobal.manager.printErr(result.message);
}
else {
GameGlobal.realtimeLogManager.error(result);
const isErrorObj = result && result.stack;
GameGlobal.logmanager.warn(isErrorObj ? result.stack : result);
console.error('onError:', result);
}
});
wx.onUnhandledRejection((result) => {
GameGlobal.realtimeLogManager.error(result);
const isErrorObj = result && result.reason && result.reason.stack;
GameGlobal.logmanager.warn(isErrorObj ? result.reason.stack : result.reason);
console.error('unhandledRejection:', result.reason);
});
// 上报初始信息
function printSystemInfo(appBaseInfo, deviceInfo) {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { version, SDKVersion } = appBaseInfo;
const { platform, system } = deviceInfo;
unityNamespace.version = version;
unityNamespace.SDKVersion = SDKVersion;
unityNamespace.platform = platform;
unityNamespace.system = system;
unityNamespace.isPc = platform === 'windows' || platform === 'mac';
unityNamespace.isDevtools = platform === 'devtools';
unityNamespace.isMobile = !unityNamespace.isPc && !unityNamespace.isDevtools;
unityNamespace.isH5Renderer = GameGlobal.isIOSHighPerformanceMode;
unityNamespace.isIOS = platform === 'ios';
unityNamespace.isAndroid = platform === 'android';
const bootinfo = {
renderer: GameGlobal.isIOSHighPerformanceMode ? 'h5' : '',
isH5Plus: GameGlobal.isIOSHighPerformanceModePlus || false,
abi: deviceInfo.abi || '',
brand: deviceInfo.brand,
model: deviceInfo.model,
platform: deviceInfo.platform,
system: deviceInfo.system,
version: appBaseInfo.version,
SDKVersion: appBaseInfo.SDKVersion,
benchmarkLevel: deviceInfo.benchmarkLevel,
};
GameGlobal.realtimeLogManager.info('game starting', bootinfo);
GameGlobal.logmanager.info('game starting', bootinfo);
console.info('game starting', bootinfo);
}
const appBaseInfo = wx.getAppBaseInfo ? wx.getAppBaseInfo() : wx.getSystemInfoSync();
const deviceInfo = wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync();
printSystemInfo(appBaseInfo, deviceInfo);
}
bindGloblException();
// eslint-disable-next-line no-multi-assign
GameGlobal.onCrash = GameGlobal.unityNamespace.onCrash = function () {
GameGlobal.manager.showAbort();
const windowInfo = wx.getWindowInfo ? wx.getWindowInfo() : wx.getSystemInfoSync();
wx.createFeedbackButton({
type: 'text',
text: '提交反馈',
style: {
left: (windowInfo.screenWidth - 184) / 2,
top: windowInfo.screenHeight / 3 + 140,
width: 184,
height: 40,
lineHeight: 40,
backgroundColor: '#07C160',
color: '#ffffff',
textAlign: 'center',
fontSize: 16,
borderRadius: 4,
},
});
};
export default GameGlobal.unityNamespace;
/* eslint-disable @typescript-eslint/naming-convention */
import { formatJsonStr, uid, onEventCallback, offEventCallback, getListObject, convertInfoToPointer, formatResponse, convertDataToPointer } from '../utils';
const TCPSocketList = {};
const wxTCPSocketBindWifiList = {};
const wxTCPSocketCloseList = {};
const wxTCPSocketConnectList = {};
const wxTCPSocketErrorList = {};
const wxTCPSocketMessageList = {};
const getTCPSocketObject = getListObject(TCPSocketList, 'TCPSocket');
let wxTCPSocketOnMessageCallback;
function WX_CreateTCPSocket() {
const obj = wx.createTCPSocket({ type: 'ipv4' });
const key = uid();
TCPSocketList[key] = obj;
return key;
}
function WX_TCPSocketBindWifi(id, option) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
obj.bindWifi(formatJsonStr(option));
}
function WX_TCPSocketClose(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
obj.close();
delete TCPSocketList[id];
}
function WX_TCPSocketConnect(id, option) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
obj.connect(formatJsonStr(option));
}
function WX_TCPSocketWriteString(id, data) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
obj.write(data);
}
function WX_TCPSocketWriteBuffer(id, dataPtr, dataLength) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
obj.write(GameGlobal.Module.HEAPU8.buffer.slice(dataPtr, dataPtr + dataLength));
}
function WX_TCPSocketOffBindWifi(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxTCPSocketBindWifiList, (v) => {
obj.offBindWifi(v);
}, id);
}
function WX_TCPSocketOffClose(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxTCPSocketCloseList, (v) => {
obj.offClose(v);
}, id);
}
function WX_TCPSocketOffConnect(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxTCPSocketConnectList, (v) => {
obj.offConnect(v);
}, id);
}
function WX_TCPSocketOffError(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxTCPSocketErrorList, (v) => {
obj.offError(v);
}, id);
}
function WX_TCPSocketOffMessage(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxTCPSocketMessageList, (v) => {
obj.offMessage(v);
}, id);
}
function WX_TCPSocketOnBindWifi(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxTCPSocketBindWifiList, '_TCPSocketOnBindWifiCallback', id, id);
obj.onBindWifi(callback);
}
function WX_TCPSocketOnClose(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxTCPSocketCloseList, '_TCPSocketOnCloseCallback', id, id);
obj.onClose(callback);
}
function WX_TCPSocketOnConnect(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxTCPSocketConnectList, '_TCPSocketOnConnectCallback', id, id);
obj.onConnect(callback);
}
function WX_TCPSocketOnError(id) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxTCPSocketErrorList, '_TCPSocketOnErrorCallback', id, id);
obj.onError(callback);
}
function WX_TCPSocketOnMessage(id, needInfo) {
const obj = getTCPSocketObject(id);
if (!obj) {
return;
}
if (!wxTCPSocketMessageList[id]) {
wxTCPSocketMessageList[id] = [];
}
const callback = (res) => {
formatResponse('TCPSocketOnMessageListenerResult', res);
const idPtr = convertDataToPointer(id);
const messagePtr = convertDataToPointer(res.message);
if (needInfo) {
const localInfoPtr = convertInfoToPointer(res.localInfo);
const remoteInfoPtr = convertInfoToPointer(res.remoteInfo);
GameGlobal.Module.dynCall_viiiii(wxTCPSocketOnMessageCallback, idPtr, messagePtr, res.message.length || res.message.byteLength, localInfoPtr, remoteInfoPtr);
GameGlobal.Module._free(localInfoPtr);
GameGlobal.Module._free(remoteInfoPtr);
}
else {
GameGlobal.Module.dynCall_viiiii(wxTCPSocketOnMessageCallback, idPtr, messagePtr, res.message.length || res.message.byteLength, 0, 0);
}
GameGlobal.Module._free(idPtr);
GameGlobal.Module._free(messagePtr);
};
wxTCPSocketMessageList[id].push(callback);
obj.onMessage(callback);
}
function WX_RegisterTCPSocketOnMessageCallback(callback) {
wxTCPSocketOnMessageCallback = callback;
}
export default {
WX_CreateTCPSocket,
WX_TCPSocketBindWifi,
WX_TCPSocketClose,
WX_TCPSocketConnect,
WX_TCPSocketWriteString,
WX_TCPSocketWriteBuffer,
WX_TCPSocketOffBindWifi,
WX_TCPSocketOffClose,
WX_TCPSocketOffConnect,
WX_TCPSocketOffError,
WX_TCPSocketOffMessage,
WX_TCPSocketOnBindWifi,
WX_TCPSocketOnClose,
WX_TCPSocketOnConnect,
WX_TCPSocketOnError,
WX_TCPSocketOnMessage,
WX_RegisterTCPSocketOnMessageCallback,
};
/* eslint-disable @typescript-eslint/naming-convention */
import { formatJsonStr, uid, onEventCallback, offEventCallback, getListObject, convertDataToPointer, convertInfoToPointer, formatResponse } from '../utils';
const UDPSocketList = {};
const wxUDPSocketCloseList = {};
const wxUDPSocketErrorList = {};
const wxUDPSocketListeningList = {};
const wxUDPSocketMessageList = {};
const getUDPSocketObject = getListObject(UDPSocketList, 'UDPSocket');
let wxUDPSocketOnMessageCallback;
function WX_CreateUDPSocket() {
const obj = wx.createUDPSocket();
const key = uid();
UDPSocketList[key] = obj;
return key;
}
function WX_UDPSocketClose(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
obj.close();
delete UDPSocketList[id];
}
function WX_UDPSocketConnect(id, option) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
obj.connect(formatJsonStr(option));
}
function WX_UDPSocketOffClose(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxUDPSocketCloseList, (v) => {
obj.offClose(v);
}, id);
}
function WX_UDPSocketOffError(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxUDPSocketErrorList, (v) => {
obj.offError(v);
}, id);
}
function WX_UDPSocketOffListening(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxUDPSocketListeningList, (v) => {
obj.offListening(v);
}, id);
}
function WX_UDPSocketOffMessage(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
offEventCallback(wxUDPSocketMessageList, (v) => {
obj.offMessage(v);
}, id);
}
function WX_UDPSocketOnClose(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxUDPSocketCloseList, '_UDPSocketOnCloseCallback', id, id);
obj.onClose(callback);
}
function WX_UDPSocketOnError(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxUDPSocketErrorList, '_UDPSocketOnErrorCallback', id, id);
obj.onError(callback);
}
function WX_UDPSocketOnListening(id) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxUDPSocketListeningList, '_UDPSocketOnListeningCallback', id, id);
obj.onListening(callback);
}
function WX_UDPSocketOnMessage(id, needInfo) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
if (!wxUDPSocketMessageList[id]) {
wxUDPSocketMessageList[id] = [];
}
const callback = (res) => {
formatResponse('UDPSocketOnMessageListenerResult', res);
const idPtr = convertDataToPointer(id);
const messagePtr = convertDataToPointer(res.message);
if (needInfo) {
const localInfoPtr = convertInfoToPointer(res.localInfo);
const remoteInfoPtr = convertInfoToPointer(res.remoteInfo);
GameGlobal.Module.dynCall_viiiii(wxUDPSocketOnMessageCallback, idPtr, messagePtr, res.message.length || res.message.byteLength, localInfoPtr, remoteInfoPtr);
GameGlobal.Module._free(localInfoPtr);
GameGlobal.Module._free(remoteInfoPtr);
}
else {
GameGlobal.Module.dynCall_viiiii(wxUDPSocketOnMessageCallback, idPtr, messagePtr, res.message.length || res.message.byteLength, 0, 0);
}
GameGlobal.Module._free(idPtr);
GameGlobal.Module._free(messagePtr);
};
wxUDPSocketMessageList[id].push(callback);
obj.onMessage(callback);
}
function WX_UDPSocketSendString(id, data, param) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
const config = formatJsonStr(param);
obj.send({
address: config.address,
message: data,
port: config.port,
setBroadcast: config.setBroadcast,
});
}
function WX_UDPSocketSendBuffer(id, dataPtr, dataLength, param) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
const config = formatJsonStr(param);
obj.send({
address: config.address,
message: GameGlobal.Module.HEAPU8.buffer.slice(dataPtr, dataPtr + dataLength),
port: config.port,
length: config.length,
offset: config.offset,
setBroadcast: config.setBroadcast,
});
}
function WX_UDPSocketSetTTL(id, ttl) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
obj.setTTL(ttl);
}
function WX_UDPSocketWriteString(id, data, param) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
const config = formatJsonStr(param);
obj.write({
address: config.address,
message: data,
port: config.port,
setBroadcast: config.setBroadcast,
});
}
function WX_UDPSocketWriteBuffer(id, dataPtr, dataLength, param) {
const obj = getUDPSocketObject(id);
if (!obj) {
return;
}
const config = formatJsonStr(param);
obj.write({
address: config.address,
message: GameGlobal.Module.HEAPU8.buffer.slice(dataPtr, dataPtr + dataLength),
port: config.port,
length: config.length,
offset: config.offset,
setBroadcast: config.setBroadcast,
});
}
function WX_UDPSocketBind(id, param) {
const obj = getUDPSocketObject(id);
if (!obj) {
return 0;
}
const config = formatJsonStr(param);
return obj.bind(config.port);
}
function WX_RegisterUDPSocketOnMessageCallback(callback) {
wxUDPSocketOnMessageCallback = callback;
}
export default {
WX_CreateUDPSocket,
WX_UDPSocketBind,
WX_UDPSocketClose,
WX_UDPSocketConnect,
WX_UDPSocketOffClose,
WX_UDPSocketOffError,
WX_UDPSocketOffListening,
WX_UDPSocketOffMessage,
WX_UDPSocketOnClose,
WX_UDPSocketOnError,
WX_UDPSocketOnListening,
WX_UDPSocketOnMessage,
WX_UDPSocketSendString,
WX_UDPSocketSendBuffer,
WX_UDPSocketSetTTL,
WX_UDPSocketWriteString,
WX_UDPSocketWriteBuffer,
WX_RegisterUDPSocketOnMessageCallback,
};
/* eslint-disable no-param-reassign */
import moduleHelper from './module-helper';
import response from './response';
import { formatJsonStr, uid } from './utils';
import { resumeWebAudio } from './audio/utils';
const ads = {};
export default {
WXCreateBannerAd(conf) {
const config = formatJsonStr(conf);
config.style = JSON.parse(config.styleRaw || '{}');
const ad = wx.createBannerAd(config);
const key = uid();
ads[key] = ad;
ad.onError((res) => {
console.error(res);
moduleHelper.send('ADOnErrorCallback', JSON.stringify({
callbackId: key,
errMsg: res.errMsg,
errCode: res.errCode || res.err_code,
}));
});
ad.onLoad(() => {
moduleHelper.send('ADOnLoadCallback', JSON.stringify({
callbackId: key,
errMsg: '',
}));
});
ad.onResize((res) => {
moduleHelper.send('ADOnResizeCallback', JSON.stringify({
callbackId: key,
errMsg: '',
...res,
}));
});
return key;
},
WXCreateFixedBottomMiddleBannerAd(adUnitId, adIntervals, height) {
const info = wx.getWindowInfo ? wx.getWindowInfo() : wx.getSystemInfoSync();
const ad = wx.createBannerAd({
adUnitId,
adIntervals,
style: {
left: 0,
top: info.windowHeight - height,
height,
width: info.windowWidth,
},
});
const key = uid();
ads[key] = ad;
ad.onError((res) => {
console.error(res);
moduleHelper.send('ADOnErrorCallback', JSON.stringify({
callbackId: key,
errMsg: res.errMsg,
errCode: res.errCode || res.err_code,
}));
});
ad.onLoad(() => {
moduleHelper.send('ADOnLoadCallback', JSON.stringify({
callbackId: key,
errMsg: '',
}));
});
const oldWidth = info.windowWidth;
ad.onResize((res) => {
if (Math.abs(res.height - height) > 1 || Math.abs(res.width - oldWidth) > 1) {
ad.style.left = Math.round((info.windowWidth - res.width) / 2);
ad.style.top = Math.round(info.windowHeight - res.height);
}
moduleHelper.send('ADOnResizeCallback', JSON.stringify({
callbackId: key,
errMsg: '',
...res,
}));
});
return key;
},
WXCreateRewardedVideoAd(conf) {
const config = formatJsonStr(conf);
const ad = wx.createRewardedVideoAd(config);
const key = uid();
ads[key] = ad;
if (!config.multiton) {
// 单例模式要处理一下
ad.offLoad();
ad.offError();
ad.offClose();
}
ad.onError((res) => {
console.error(res);
moduleHelper.send('ADOnErrorCallback', JSON.stringify({
callbackId: key,
errMsg: res.errMsg,
errCode: res.errCode || res.err_code,
}));
});
ad.onLoad((res) => {
moduleHelper.send('ADOnLoadCallback', JSON.stringify({
callbackId: key,
errMsg: '',
...res,
}));
});
ad.onClose((res) => {
moduleHelper.send('ADOnVideoCloseCallback', JSON.stringify({
callbackId: key,
errMsg: '',
...res,
}));
setTimeout(() => {
resumeWebAudio();
}, 0);
});
return key;
},
WXCreateInterstitialAd(conf) {
const config = formatJsonStr(conf);
const ad = wx.createInterstitialAd(config);
const key = uid();
ads[key] = ad;
ad.onError((res) => {
console.error(res);
moduleHelper.send('ADOnErrorCallback', JSON.stringify({
callbackId: key,
errMsg: res.errMsg,
errCode: res.errCode || res.err_code,
}));
});
ad.onLoad(() => {
moduleHelper.send('ADOnLoadCallback', JSON.stringify({
callbackId: key,
errMsg: '',
}));
});
ad.onClose(() => {
moduleHelper.send('ADOnCloseCallback', JSON.stringify({
callbackId: key,
errMsg: '',
}));
});
return key;
},
WXCreateCustomAd(conf) {
const config = formatJsonStr(conf);
config.style = JSON.parse(config.styleRaw || '{}');
const ad = wx.createCustomAd(config);
const key = uid();
ads[key] = ad;
ad.onError((res) => {
console.error(res);
moduleHelper.send('ADOnErrorCallback', JSON.stringify({
callbackId: key,
errMsg: res.errMsg,
errCode: res.errCode || res.err_code,
}));
});
ad.onLoad(() => {
moduleHelper.send('ADOnLoadCallback', JSON.stringify({
callbackId: key,
errMsg: '',
}));
});
ad.onClose(() => {
moduleHelper.send('ADOnCloseCallback', JSON.stringify({
callbackId: key,
errMsg: '',
}));
});
ad.onHide(() => {
moduleHelper.send('ADOnHideCallback', JSON.stringify({
callbackId: key,
errMsg: '',
}));
});
return key;
},
WXADStyleChange(id, key, value) {
if (!ads[id]) {
return false;
}
if (typeof ads[id].style === 'undefined') {
return;
}
ads[id].style[key] = value;
},
WXShowAd(id, succ, fail) {
if (!ads[id]) {
return false;
}
ads[id]
.show()
.then(() => {
response.textFormat(succ, {
errMsg: 'show:ok',
});
})
.catch((e) => {
response.textFormat(fail, {
errMsg: e.errMsg || '',
});
});
},
WXShowAd2(id, branchId, branchDim, succ, fail) {
if (!ads[id]) {
return false;
}
ads[id]
.show({ branchId, branchDim })
.then(() => {
response.textFormat(succ, {
errMsg: 'show:ok',
});
})
.catch((e) => {
response.textFormat(fail, {
errMsg: e.errMsg || '',
});
});
},
WXHideAd(id, succ, fail) {
if (!ads[id]) {
return false;
}
if (typeof ads[id].hide === 'undefined') {
return;
}
if (succ || fail) {
const promise = ads[id].hide();
if (promise) {
promise
.then(() => {
response.textFormat(succ, {
errMsg: 'hide:ok',
});
})
.catch((e) => {
response.textFormat(fail, {
errMsg: e.errMsg || '',
});
});
}
else {
response.textFormat(succ, {
errMsg: 'hide:ok',
});
}
}
else {
ads[id].hide();
}
},
WXADGetStyleValue(id, key) {
if (!ads[id]) {
return -1;
}
if (typeof ads[id].style === 'undefined') {
return;
}
return ads[id].style[key];
},
WXADDestroy(id) {
if (!ads[id]) {
return false;
}
ads[id].destroy();
delete ads[id];
},
WXADLoad(id, succ, fail) {
if (!ads[id]) {
return false;
}
if (typeof ads[id].load === 'undefined') {
return;
}
ads[id]
.load()
.then(() => {
response.textFormat(succ, {});
})
.catch((res) => {
moduleHelper.send('ADLoadErrorCallback', JSON.stringify({
callbackId: fail,
...res,
}));
});
},
WXReportShareBehavior(id, conf) {
if (!ads[id]) {
return '{}';
}
if (typeof ads[id].reportShareBehavior === 'undefined') {
return '{}';
}
const config = formatJsonStr(conf);
return JSON.stringify(ads[id].reportShareBehavior(config));
},
};
import { WEBAudio, audios, unityAudioVolume, innerAudioVolume } from './store';
import { resumeWebAudio, mkCacheDir } from './utils';
mkCacheDir();
export default {
WXGetAudioCount() {
return {
innerAudio: Object.keys(audios).length,
webAudio: WEBAudio.bufferSourceNodeLength,
buffer: WEBAudio.audioBufferLength,
};
},
WXSetAudioMute(value) {
if (typeof value !== 'boolean') {
return;
}
if (WEBAudio.isMute === value) {
return;
}
WEBAudio.isMute = value;
for (const channelInstance of Object.keys(WEBAudio.audioInstances)) {
const channel = WEBAudio.audioInstances[+channelInstance];
if (channel.source) {
channel.setVolume?.(value ? 0 : unityAudioVolume.get(channel) ?? 1);
}
}
for (const innerAudio of Object.values(audios)) {
innerAudio.volume = value ? 0 : innerAudioVolume.get(innerAudio) ?? 1;
}
},
};
const HandleInterruption = {
init() {
let INTERRUPT_LIST = {};
wx.onHide(() => {
Object.keys(audios).forEach((key) => {
if (!audios[key].paused !== false) {
INTERRUPT_LIST[key] = true;
}
});
});
wx.onShow(() => {
Object.keys(audios).forEach((key) => {
if (audios[key].paused !== false && INTERRUPT_LIST[key]) {
audios[key].play();
}
});
INTERRUPT_LIST = {};
});
wx.onAudioInterruptionBegin(() => {
Object.keys(audios).forEach((key) => {
if (!audios[key].paused !== false) {
INTERRUPT_LIST[key] = true;
}
});
});
wx.onAudioInterruptionEnd(() => {
Object.keys(audios).forEach((key) => {
if (audios[key].paused !== false && INTERRUPT_LIST[key]) {
audios[key].play();
}
});
INTERRUPT_LIST = {};
resumeWebAudio();
});
},
};
HandleInterruption.init();
export const INNER_AUDIO_UNDEFINED_MSG = 'InnerAudioContext does not exist!';
export const IGNORE_ERROR_MSG = 'audio is playing, don\'t play again';
export const TEMP_DIR_PATH = `${wx.env.USER_DATA_PATH}/__GAME_FILE_CACHE/audios`;
import innerAudio from './inner-audio';
import unityAudio from './unity-audio';
import common from './common';
export default {
...innerAudio,
...unityAudio,
...common,
};
export const WEBAudio = {
audioInstanceIdCounter: 0,
audioInstances: {},
audioContext: null,
audioWebEnabled: 0,
audioCache: [],
lOrientation: {
x: 0,
y: 0,
z: 0,
xUp: 0,
yUp: 0,
zUp: 0,
},
lPosition: { x: 0, y: 0, z: 0 },
audio3DSupport: 0,
audioWebSupport: 0,
bufferSourceNodeLength: 0,
audioBufferLength: 0,
isMute: false,
FAKEMOD_SAMPLERATE: 44100,
};
export const audios = {};
export const localAudioMap = {};
export const downloadingAudioMap = {};
export const unityAudioVolume = new WeakMap();
export const innerAudioVolume = new WeakMap();
import { uid } from '../utils';
import { isSupportCacheAudio } from '../../check-version';
import { WEBAudio, audios } from './store';
import { TEMP_DIR_PATH } from './const';
export const resumeWebAudio = () => {
WEBAudio.audioContext?.resume();
GameGlobal.Module.mContext?.resume();
GameGlobal.Module.context?.resume();
};
export const createInnerAudio = () => {
const id = uid();
const audio = (isSupportCacheAudio && WEBAudio.audioCache.length ? WEBAudio.audioCache.shift() : wx.createInnerAudioContext());
if (audio) {
audios[id] = audio;
}
return {
id,
audio,
};
};
export const destroyInnerAudio = (id, useCache) => {
if (!id) {
return;
}
if (!useCache || !isSupportCacheAudio || WEBAudio.audioCache.length > 32) {
audios[id].destroy();
}
else {
['Play', 'Pause', 'Stop', 'Canplay', 'Error', 'Ended', 'Waiting', 'Seeking', 'Seeked', 'TimeUpdate'].forEach((eventName) => {
audios[id][`off${eventName}`]();
});
const state = {
startTime: 0,
obeyMuteSwitch: true,
volume: 1,
autoplay: false,
loop: false,
referrerPolicy: '',
};
Object.keys(state).forEach((key) => {
try {
// @ts-ignore
audios[id][key] = state[key];
}
catch (e) { }
});
audios[id].stop();
const cacheAudio = audios[id];
setTimeout(() => {
WEBAudio.audioCache.push(cacheAudio);
}, 1000);
}
delete audios[id];
};
export const printErrMsg = (msg) => {
GameGlobal.manager.printErr(msg);
};
export function mkCacheDir() {
const fs = wx.getFileSystemManager();
fs.rmdir({
dirPath: TEMP_DIR_PATH,
recursive: true,
complete: () => {
fs.mkdir({
dirPath: TEMP_DIR_PATH,
});
},
});
}
import moduleHelper from './module-helper';
import { formatJsonStr } from './utils';
let resolveFn = null;
export default {
WX_OnNeedPrivacyAuthorization() {
const callback = (resolve) => {
resolveFn = resolve;
moduleHelper.send('_OnNeedPrivacyAuthorizationCallback', '{}');
};
// @ts-ignore
wx.onNeedPrivacyAuthorization(callback);
},
WX_PrivacyAuthorizeResolve(conf) {
const config = formatJsonStr(conf);
config.event = config.eventString;
if (resolveFn) {
resolveFn(config);
if (config.event === 'agree' || config.event === 'disagree') {
resolveFn = null;
}
}
},
};
/* eslint-disable @typescript-eslint/naming-convention */
import { convertDataToPointer } from '../utils';
let wxOnBLECharacteristicValueChangeCallback;
const OnBLECharacteristicValueChange = (res) => {
const deviceIdPtr = convertDataToPointer(res.deviceId);
const serviceIdPtr = convertDataToPointer(res.serviceId);
const characteristicIdPtr = convertDataToPointer(res.characteristicId);
const valuePtr = convertDataToPointer(res.value);
GameGlobal.Module.dynCall_viiiii(wxOnBLECharacteristicValueChangeCallback, deviceIdPtr, serviceIdPtr, characteristicIdPtr, valuePtr, res.value.byteLength);
GameGlobal.Module._free(deviceIdPtr);
GameGlobal.Module._free(serviceIdPtr);
GameGlobal.Module._free(characteristicIdPtr);
GameGlobal.Module._free(valuePtr);
};
function WX_OnBLECharacteristicValueChange() {
wx.onBLECharacteristicValueChange(OnBLECharacteristicValueChange);
}
function WX_OffBLECharacteristicValueChange() {
wx.offBLECharacteristicValueChange();
}
function WX_RegisterOnBLECharacteristicValueChangeCallback(callback) {
wxOnBLECharacteristicValueChangeCallback = callback;
}
export default {
WX_OnBLECharacteristicValueChange,
WX_OffBLECharacteristicValueChange,
WX_RegisterOnBLECharacteristicValueChangeCallback,
};
import moduleHelper from './module-helper';
import { formatJsonStr, cacheArrayBuffer, getListObject } from './utils';
const cameraList = {};
const getObject = getListObject(cameraList, 'camera');
export default {
WXCameraCreateCamera(conf, callbackId) {
const obj = wx.createCamera({
...formatJsonStr(conf),
success(res) {
moduleHelper.send('CameraCreateCallback', JSON.stringify({
callbackId,
type: 'success',
res: JSON.stringify(res),
}));
},
fail(res) {
moduleHelper.send('CameraCreateCallback', JSON.stringify({
callbackId,
type: 'fail',
res: JSON.stringify(res),
}));
},
complete(res) {
moduleHelper.send('CameraCreateCallback', JSON.stringify({
callbackId,
type: 'complete',
res: JSON.stringify(res),
}));
},
});
cameraList[callbackId] = obj;
},
WXCameraCloseFrameChange(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.closeFrameChange();
},
WXCameraDestroy(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.destroy();
},
WXCameraListenFrameChange(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.listenFrameChange();
},
WXCameraOnAuthCancel(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('CameraOnAuthCancelCallback', resStr);
};
obj.onAuthCancel(callback);
},
WXCameraOnCameraFrame(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
cacheArrayBuffer(id, res.data);
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify({
width: res.width,
height: res.height,
}),
});
moduleHelper.send('CameraOnCameraFrameCallback', resStr);
};
obj.onCameraFrame(callback);
},
WXCameraOnStop(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('CameraOnStopCallback', resStr);
};
obj.onStop(callback);
},
};
const callbacks = [];
let isTriggered = false;
export default {
addCreatedListener(callback) {
if (isTriggered) {
callback();
}
else {
callbacks.push(callback);
}
},
_triggerCallback() {
isTriggered = true;
callbacks.forEach(v => v());
},
};
import response from './response';
import moduleHelper from './module-helper';
import { getDefaultData } from './utils';
export default {
WXToTempFilePathSync(conf) {
return canvas.toTempFilePathSync(getDefaultData(canvas, conf));
},
WXToTempFilePath(conf, s, f, c) {
if (conf) {
canvas.toTempFilePath({
...getDefaultData(canvas, conf),
...response.handleText(s, f, c),
success: (res) => {
moduleHelper.send('ToTempFilePathCallback', JSON.stringify({
callbackId: s,
errMsg: res.errMsg,
errCode: res.errCode || 0,
tempFilePath: res.tempFilePath,
}));
},
});
}
},
};
import moduleHelper from './module-helper';
import { formatJsonStr, uid } from './utils';
let MiniGameChat;
let instance;
let onList;
function createMiniGameChat(options, callback) {
try {
if (typeof requirePlugin !== 'undefined') {
if (!MiniGameChat) {
// @ts-ignore
MiniGameChat = requirePlugin('MiniGameChat', {
enableRequireHostModule: true,
customEnv: {
wx,
},
}).default;
}
if (instance) {
return '';
}
instance = new MiniGameChat(options);
if (typeof instance === 'undefined' || typeof instance.on === 'undefined') {
console.error('MiniGameChat create error');
return '';
}
// 等待插件初始化完成
instance.on('ready', () => {
if (!GameGlobal.miniGameChat) {
GameGlobal.miniGameChat = instance;
if (!onList) {
onList = {};
}
Object.keys(onList).forEach((eventType) => {
if (!onList) {
onList = {};
}
Object.values(onList[eventType]).forEach((callback) => {
instance.on(eventType, callback);
});
});
instance.emit('ready');
callback(instance);
}
});
instance.on('error', (err) => {
console.log('插件初始化失败', err);
});
return uid();
}
}
catch (e) {
console.error(e);
return '';
}
}
export default {
WXChatCreate(optionsStr) {
const options = formatJsonStr(optionsStr);
return createMiniGameChat({
x: options.x,
y: options.y,
autoShow: false,
logoUrl: options.logoUrl || '',
movable: options.movable,
enableSnap: options.enableSnap,
scale: options.scale,
}, (instance) => {
instance.on('error', (err) => {
console.error('error', err);
});
});
},
WXChatHide() {
if (!GameGlobal.miniGameChat) {
return;
}
GameGlobal.miniGameChat.hide();
},
WXChatShow(optionsStr) {
if (!GameGlobal.miniGameChat) {
return;
}
const options = formatJsonStr(optionsStr);
GameGlobal.miniGameChat.show({
x: options.x,
y: options.y,
});
},
WXChatClose() {
if (!GameGlobal.miniGameChat) {
return;
}
GameGlobal.miniGameChat.close();
},
WXChatOpen(key) {
if (!GameGlobal.miniGameChat) {
return;
}
GameGlobal.miniGameChat.open(key || '');
},
WXChatSetTabs(keysStr) {
if (!GameGlobal.miniGameChat) {
return;
}
if (!keysStr) {
// eslint-disable-next-line no-param-reassign
keysStr = '[]';
}
const keys = JSON.parse(keysStr);
GameGlobal.miniGameChat.setTabs(keys);
},
WXChatOff(eventType) {
const { miniGameChat } = GameGlobal;
if (!miniGameChat) {
return;
}
if (!miniGameChat || typeof onList === 'undefined' || typeof onList[eventType] === 'undefined') {
return;
}
// eslint-disable-next-line no-restricted-syntax
for (const key in Object.keys(onList[eventType])) {
const callback = onList[eventType][key];
if (callback) {
miniGameChat.off(eventType, callback);
}
}
onList[eventType] = {};
},
WXChatOn(eventType) {
const callbackId = uid();
const callback = (res) => {
let result = '';
if (res) {
result = JSON.stringify(res);
}
const resStr = JSON.stringify({
eventType,
result,
});
moduleHelper.send('OnWXChatCallback', resStr);
};
if (!onList) {
onList = {};
}
if (typeof onList[eventType] === 'undefined') {
onList[eventType] = {};
}
if (onList[eventType]) {
onList[eventType][callbackId] = callback;
const { miniGameChat } = GameGlobal;
if (miniGameChat) {
miniGameChat.on(eventType, callback);
}
return callbackId;
}
return '';
},
WXChatSetSignature(signature) {
const { miniGameChat } = GameGlobal;
if (miniGameChat) {
miniGameChat.setChatSignature({ signature });
}
},
};
/* eslint-disable no-param-reassign */
import moduleHelper from './module-helper';
import { uid, formatJsonStr, formatResponse } from './utils';
const CloudIDObject = {};
const CDNObject = {};
function fixCallFunctionData(data) {
Object.keys(data).forEach((key) => {
if (typeof data[key] === 'object') {
fixCallFunctionData(data[key]);
}
else if (typeof data[key] === 'string') {
if (CloudIDObject[data[key]]) {
data[key] = CloudIDObject[data[key]];
}
if (CDNObject[data[key]]) {
data[key] = CDNObject[data[key]];
}
}
});
}
const CloudList = {};
export default {
WX_CloudCloud(option) {
const config = formatJsonStr(option);
// @ts-ignore
const cloud = new wx.cloud.Cloud(config);
CloudList[config.resourceEnv] = cloud;
},
WX_CloudInit(option) {
const config = formatJsonStr(option);
if (config.env === '_default_') {
wx.cloud.init();
}
else {
wx.cloud.init(config);
}
},
WX_CloudCallFunction(env, conf, callbackId) {
const config = formatJsonStr(conf);
if (config.data) {
fixCallFunctionData(config.data);
}
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
targetCloud.callFunction({
...config,
success(res) {
formatResponse('CallFunctionResult', res);
moduleHelper.send('_CloudCallFunctionCallback', JSON.stringify({
callbackId, type: 'success', res: JSON.stringify(res),
}));
},
fail(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudCallFunctionCallback', JSON.stringify({
callbackId, type: 'fail', res: JSON.stringify(res),
}));
},
complete(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudCallFunctionCallback', JSON.stringify({
callbackId, type: 'complete', res: JSON.stringify(res),
}));
},
});
},
WX_CloudCloudID(env, cloudID) {
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
const res = targetCloud.CloudID(cloudID);
const id = `CloudID-${uid()}`;
CloudIDObject[id] = res;
return id;
},
WX_CloudCDN(env, target) {
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
const res = targetCloud.CDN(target);
const id = `CDN-${uid()}`;
CDNObject[id] = res;
return id;
},
WX_CloudCallContainer(env, conf, callbackId) {
const config = formatJsonStr(conf);
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
targetCloud.callContainer({
...config,
success(res) {
formatResponse('CallContainerResult', res);
moduleHelper.send('_CloudCallContainerCallback', JSON.stringify({
callbackId, type: 'success', res: JSON.stringify(res),
}));
},
fail(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudCallContainerCallback', JSON.stringify({
callbackId, type: 'fail', res: JSON.stringify(res),
}));
},
complete(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudCallContainerCallback', JSON.stringify({
callbackId, type: 'complete', res: JSON.stringify(res),
}));
},
});
},
WX_CloudUploadFile(env, conf, callbackId) {
const config = formatJsonStr(conf);
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
targetCloud.uploadFile({
...config,
success(res) {
formatResponse('UploadFileResult', res);
moduleHelper.send('_CloudUploadFileCallback', JSON.stringify({
callbackId, type: 'success', res: JSON.stringify(res),
}));
},
fail(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudUploadFileCallback', JSON.stringify({
callbackId, type: 'fail', res: JSON.stringify(res),
}));
},
complete(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudUploadFileCallback', JSON.stringify({
callbackId, type: 'complete', res: JSON.stringify(res),
}));
},
});
},
WX_CloudDownloadFile(env, conf, callbackId) {
const config = formatJsonStr(conf);
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
targetCloud.downloadFile({
...config,
success(res) {
formatResponse('DownloadFileResult', res);
moduleHelper.send('_CloudDownloadFileCallback', JSON.stringify({
callbackId, type: 'success', res: JSON.stringify(res),
}));
},
fail(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudDownloadFileCallback', JSON.stringify({
callbackId, type: 'fail', res: JSON.stringify(res),
}));
},
complete(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudDownloadFileCallback', JSON.stringify({
callbackId, type: 'complete', res: JSON.stringify(res),
}));
},
});
},
WX_CloudGetTempFileURL(env, conf, callbackId) {
const config = formatJsonStr(conf);
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
targetCloud.getTempFileURL({
...config,
success(res) {
formatResponse('GetTempFileURLResult', res);
moduleHelper.send('_CloudGetTempFileURLCallback', JSON.stringify({
callbackId, type: 'success', res: JSON.stringify(res),
}));
},
fail(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudGetTempFileURLCallback', JSON.stringify({
callbackId, type: 'fail', res: JSON.stringify(res),
}));
},
complete(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudGetTempFileURLCallback', JSON.stringify({
callbackId, type: 'complete', res: JSON.stringify(res),
}));
},
});
},
WX_CloudDeleteFile(env, conf, callbackId) {
const config = formatJsonStr(conf);
let targetCloud;
if (env === '_default_') {
targetCloud = wx.cloud;
}
else {
targetCloud = CloudList[env];
}
targetCloud.deleteFile({
...config,
success(res) {
formatResponse('DeleteFileResult', res);
moduleHelper.send('_CloudDeleteFileCallback', JSON.stringify({
callbackId, type: 'success', res: JSON.stringify(res),
}));
},
fail(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudDeleteFileCallback', JSON.stringify({
callbackId, type: 'fail', res: JSON.stringify(res),
}));
},
complete(res) {
formatResponse('GeneralCallbackResult', res);
moduleHelper.send('_CloudDeleteFileCallback', JSON.stringify({
callbackId, type: 'complete', res: JSON.stringify(res),
}));
},
});
},
};
export const MODULE_NAME = 'WXSDKManagerHandler';
function getObjectSize(data) {
if (data && (typeof data === 'string' || data.byteLength)) {
return data.byteLength || data.length || 0;
}
return 0;
}
export const fileInfoHandler = {
addFileInfo(filePath, data) {
if (GameGlobal.manager.fs && GameGlobal.manager.fs.addFileInfo) {
GameGlobal.manager.fs.addFileInfo({ path: filePath, size: getObjectSize(data), erasable: false });
}
},
modifyFileInfo(filePath, data) {
if (GameGlobal.manager.fs && GameGlobal.manager.fs.modifyFileInfo) {
GameGlobal.manager.fs.modifyFileInfo({ path: filePath, size: getObjectSize(data) });
}
},
removeFileInfo(filePath) {
if (GameGlobal.manager.fs && GameGlobal.manager.fs.removeFileInfo) {
GameGlobal.manager.fs.removeFileInfo(filePath);
}
},
};
export const fileInfoType = {
add: 0,
remove: 1,
modify: 2,
};
export function responseWrapper(responseHandler, info) {
const { filePath, data, type } = info;
return {
success(res) {
if (type === fileInfoType.add) {
fileInfoHandler.addFileInfo(filePath, data);
}
if (type === fileInfoType.remove) {
fileInfoHandler.removeFileInfo(filePath);
}
if (type === fileInfoType.modify) {
fileInfoHandler.modifyFileInfo(filePath, data);
}
responseHandler.success(res);
},
fail: responseHandler.fail,
complete: responseHandler.complete,
};
}
/* eslint-disable prefer-spread */
/* eslint-disable prefer-rest-params */
export default {
init() {
this.fixTimer();
},
fixTimer() {
const wm = {};
const privateSetTimeout = window.setTimeout;
let id = 0;
const getId = function () {
id += 1;
if (id > 100000000) {
id = 0;
}
return id;
};
// @ts-ignore
window.setTimeout = function (vCallback, nDelay) {
const aArgs = Array.prototype.slice.call(arguments, 2);
const id = getId();
const t = privateSetTimeout(vCallback instanceof Function
? () => {
// @ts-ignore
vCallback.apply(null, aArgs);
delete wm[id];
}
: vCallback, nDelay);
wm[id] = t;
return id;
};
const privateClearTimeout = window.clearTimeout;
// @ts-ignore
window.clearTimeout = function (id) {
if (id) {
const t = wm[id];
if (t) {
privateClearTimeout(t);
delete wm[id];
}
}
};
const privateSetInterval = window.setInterval;
// @ts-ignore
window.setInterval = function (vCallback, nDelay) {
const aArgs = Array.prototype.slice.call(arguments, 2);
const id = getId();
const t = privateSetInterval(vCallback instanceof Function
? () => {
// @ts-ignore
vCallback.apply(null, aArgs);
}
: vCallback, nDelay);
wm[id] = t;
return id;
};
const privateClearInterval = window.clearInterval;
// @ts-ignore
window.clearInterval = function (id) {
if (id) {
const t = wm[id];
if (t) {
privateClearInterval(t);
delete wm[id];
}
}
};
const privateRequestAnimationFrame = window.requestAnimationFrame;
window.requestAnimationFrame = function (vCallback) {
const id = getId();
const t = privateRequestAnimationFrame(() => {
vCallback(0);
delete wm[id];
});
wm[id] = t;
return id;
};
const privateCancelAnimationFrame = window.cancelAnimationFrame;
window.cancelAnimationFrame = function (id) {
const t = wm[id];
if (t) {
privateCancelAnimationFrame(t);
delete wm[id];
}
};
},
};
export default function fixCmapTable(arrayBuffer) {
const font = new DataView(arrayBuffer);
const tableCount = font.getUint16(4);
let cmapOffset = 0;
let cmapLength = 0;
let cmapCheckSumOffset = 0;
let cmapCheckSum = 0;
for (let i = 0; i < tableCount; i++) {
const tag = font.getUint32(12 + i * 16);
if (tag === 0x636D6170) {
cmapCheckSumOffset = 12 + i * 16 + 4;
cmapCheckSum = font.getUint32(cmapCheckSumOffset);
cmapOffset = font.getUint32(12 + i * 16 + 8);
cmapLength = font.getUint32(12 + i * 16 + 12);
GameGlobal.manager.Logger.pluginLog(`[font]cmapCheckSubOffset [${cmapCheckSumOffset}], cmapCheckSum [${cmapCheckSum}], cmapOffset [${cmapOffset}], cmapLength [${cmapLength}]`);
}
}
if (cmapOffset === 0) {
GameGlobal.manager.Logger.pluginError('[font]not found cmap');
return false;
}
const cmap = new DataView(arrayBuffer, cmapOffset, cmapLength);
const numTables = cmap.getUint16(2);
let subtableOffset = 4;
let targetSubtableOffset = 0;
for (let i = 0; i < numTables; i++) {
const platformId = cmap.getUint16(subtableOffset);
const encodingId = cmap.getUint16(subtableOffset + 2);
if (platformId === 0 && encodingId === 5) {
if (i === (numTables - 1)) {
targetSubtableOffset = subtableOffset;
GameGlobal.manager.Logger.pluginLog(`[font]targetSubtableOffset ${targetSubtableOffset}`);
}
break;
}
subtableOffset += 8;
}
if (targetSubtableOffset > 0) {
const newCmapView = new DataView(arrayBuffer, cmapOffset, cmapLength - 8);
newCmapView.setUint16(2, numTables - 1);
let sum = 0;
const lengthInUint32 = (newCmapView.byteLength + 3) / 4;
for (let i = 0; i < lengthInUint32; i++) {
sum += newCmapView.getUint32(i);
}
font.setUint32(cmapCheckSumOffset, sum);
return true;
}
GameGlobal.manager.Logger.pluginLog('[font]not found cmap subtable');
return false;
}
/* eslint-disable no-param-reassign */
import moduleHelper from '../module-helper';
import { formatJsonStr } from '../utils';
import fixCmapTable from './fix-cmap';
import readMetrics from './read-metrics';
import splitTTCToBufferOnlySC from './split-sc';
const { platform } = wx.getDeviceInfo ? wx.getDeviceInfo() : wx.getSystemInfoSync();
const tempCacheObj = {};
let fontDataCache;
let getFontPromise;
let isReadFromCache = false;
const isIOS = platform === 'ios';
const isAndroid = platform === 'android';
const fontOptions = {
CJK_Unified_Ideographs: {
include: true,
unicodeRange: [0x4E00, 0x9FFF],
},
C0_Controls_and_Basic_Latin: {
include: true,
unicodeRange: [0x0000, 0x007F],
},
CJK_Symbols_and_Punctuation: {
include: true,
unicodeRange: [0x3000, 0x303F],
},
General_Punctuation: {
include: true,
unicodeRange: [0x2000, 0x206F],
},
Enclosed_CJK_Letters_and_Months: {
include: true,
unicodeRange: [0x3200, 0x32FF],
},
Vertical_Forms: {
include: true,
unicodeRange: [0xFE10, 0xFE1F],
},
CJK_Compatibility_Forms: {
include: true,
unicodeRange: [0xFE30, 0xFE4F],
},
Miscellaneous_Symbols: {
include: true,
unicodeRange: [0x2600, 0x26FF],
},
CJK_Compatibility: {
include: true,
unicodeRange: [0x3300, 0x33FF],
},
Halfwidth_and_Fullwidth_Forms: {
include: true,
unicodeRange: [0xFF00, 0xFFEF],
},
Dingbats: {
include: true,
unicodeRange: [0x2700, 0x27BF],
},
Letterlike_Symbols: {
include: true,
unicodeRange: [0x2100, 0x214F],
},
Enclosed_Alphanumerics: {
include: true,
unicodeRange: [0x2460, 0x24FF],
},
Number_Forms: {
include: true,
unicodeRange: [0x2150, 0x218F],
},
Currency_Symbols: {
include: true,
unicodeRange: [0x20A0, 0x20CF],
},
Arrows: {
include: true,
unicodeRange: [0x2190, 0x21FF],
},
Geometric_Shapes: {
include: true,
unicodeRange: [0x25A0, 0x25FF],
},
Mathematical_Operators: {
include: true,
unicodeRange: [0x2200, 0x22FF],
},
CustomUnicodeRange: [],
};
function handleGetFontData(config, forceFallback) {
const canGetWxCommonFont = !!GameGlobal.manager?.font?.getCommonFont;
if (!config && !canGetWxCommonFont) {
return Promise.reject('invalid usage');
}
// eslint-disable-next-line @typescript-eslint/no-misused-promises
if (!getFontPromise || forceFallback) {
getFontPromise = new Promise((resolve, reject) => {
if ((!canGetWxCommonFont || forceFallback) && !!config) {
const xhr = new GameGlobal.unityNamespace.UnityLoader.UnityCache.XMLHttpRequest();
xhr.open('GET', config.fallbackUrl, true);
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
const notoFontData = xhr.response;
fontDataCache = notoFontData;
isReadFromCache = xhr.isReadFromCache;
resolve();
}
};
xhr.onerror = reject;
xhr.send();
return;
}
let unicodeRange = [];
Object.keys(fontOptions).forEach((key) => {
if (fontOptions[key].include) {
unicodeRange.push(fontOptions[key].unicodeRange);
}
});
unicodeRange = unicodeRange.concat(fontOptions.CustomUnicodeRange);
GameGlobal.manager.font.getCommonFont({
success(fontData) {
if (isIOS) {
fixCmapTable(fontData);
}
if (isAndroid) {
const tempData = splitTTCToBufferOnlySC(fontData);
if (tempData) {
fontData = tempData;
}
}
fontDataCache = fontData;
resolve();
},
fail: reject,
}, unicodeRange);
});
}
return getFontPromise;
}
function WXGetFontRawData(conf, callbackId, forceFallback = false) {
const config = formatJsonStr(conf);
const loadFromRemote = !GameGlobal.manager?.font?.getCommonFont;
GameGlobal.manager.TimeLogger.timeStart('WXGetFontRawData');
handleGetFontData(config, forceFallback).then(() => {
if (fontDataCache) {
GameGlobal.manager.font.reportGetFontCost(GameGlobal.manager.TimeLogger.timeEnd('WXGetFontRawData'), { loadFromRemote: forceFallback || loadFromRemote, isReadFromCache, preloadWXFont: GameGlobal.unityNamespace.preloadWXFont });
const { ascent, descent, lineGap, unitsPerEm } = readMetrics(fontDataCache) || {};
tempCacheObj[callbackId] = fontDataCache;
moduleHelper.send('GetFontRawDataCallback', JSON.stringify({ callbackId, type: 'success', res: JSON.stringify({ byteLength: fontDataCache.byteLength, ascent, descent, lineGap, unitsPerEm }) }));
GameGlobal.manager.Logger.pluginLog(`[font] load font from ${forceFallback || loadFromRemote ? `network, url=${config.fallbackUrl}` : 'local'}`);
fontDataCache = null;
}
else {
GameGlobal.manager.Logger.pluginError('[font] load font error: empty content');
}
})
.catch((err) => {
if (!loadFromRemote && !!config && forceFallback === false) {
WXGetFontRawData(conf, callbackId, true);
}
else {
GameGlobal.manager.Logger.pluginError('[font] load font error: ', err);
}
});
}
function WXShareFontBuffer(buffer, offset, callbackId) {
if (typeof tempCacheObj[callbackId] === 'string') {
GameGlobal.manager.Logger.pluginError('[font]内存写入异常');
}
buffer.set(new Uint8Array(tempCacheObj[callbackId]), offset);
delete tempCacheObj[callbackId];
}
export function preloadWxCommonFont() {
if (!!GameGlobal.unityNamespace.preloadWXFont && !!GameGlobal.manager?.font?.getCommonFont) {
handleGetFontData();
}
}
export default {
WXGetFontRawData,
WXShareFontBuffer,
};
import { toBytesInt32 } from './util';
export default function readMetrics(arrayBuffer) {
const font = new DataView(arrayBuffer);
const tableCount = font.getUint16(4);
const ppem = 1;
let ascent = 0;
let descent = 0;
let lineGap = 0;
let unitsPerEm;
for (let i = 0; i < tableCount; i++) {
const tag = font.getUint32(12 + i * 16);
const tagStr = toBytesInt32(tag);
if (tagStr === 'hhea') {
const offset = font.getUint32(12 + i * 16 + 8);
const length = font.getUint32(12 + i * 16 + 12);
const hhea = new DataView(arrayBuffer, offset, length);
ascent = hhea.getInt16(4);
descent = hhea.getInt16(6);
lineGap = hhea.getInt16(8);
}
else if (tagStr === 'head') {
const offset = font.getUint32(12 + i * 16 + 8);
const length = font.getUint32(12 + i * 16 + 12);
const head = new DataView(arrayBuffer, offset, length);
unitsPerEm = head.getUint16(18);
}
}
if (!ascent || !descent || !unitsPerEm) {
return undefined;
}
return {
ascent: ascent * ppem / unitsPerEm,
descent: descent * ppem / unitsPerEm,
lineGap: lineGap * ppem / unitsPerEm,
unitsPerEm,
};
}
import { ceil4, toBytesInt32, decodeUnicode } from './util';
function extractTTF(ttcView, tableHeaderOffset) {
const subFontTableCount = ttcView.getUint16(tableHeaderOffset + 0x04);
const subFontHeaderLength = 0x0C + subFontTableCount * 0x10;
let tableLength = 0;
for (let j = 0; j < subFontTableCount; j++) {
const length = ttcView.getUint32(tableHeaderOffset + 0x0C + 0x0C + j * 0x10);
tableLength += ceil4(length);
}
const totalLength = subFontHeaderLength + tableLength;
const newBuf = new ArrayBuffer(totalLength);
const newBufUint = new Uint8Array(newBuf);
const newBufData = new DataView(newBuf);
newBufUint.set(new Uint8Array(ttcView.buffer, tableHeaderOffset, subFontHeaderLength), 0);
let currentOffset = subFontHeaderLength;
for (let j = 0; j < subFontTableCount; j++) {
const offset = ttcView.getUint32(tableHeaderOffset + 0x0C + 0x08 + j * 0x10);
const length = ttcView.getUint32(tableHeaderOffset + 0x0C + 0x0C + j * 0x10);
newBufData.setUint32(0x0C + 0x08 + j * 0x10, currentOffset);
newBufUint.set(new Uint8Array(ttcView.buffer, offset, length), currentOffset);
currentOffset += ceil4(length);
}
return newBufData;
}
function parseTableToDataView(fontDataView, tableName, startOffset = 0) {
const font = fontDataView;
const tableCount = font.getUint16(startOffset + 4);
for (let i = 0; i < tableCount; i++) {
const tag = font.getUint32(startOffset + 12 + i * 16);
const tagStr = toBytesInt32(tag);
if (tagStr === tableName) {
const offset = font.getUint32(startOffset + 12 + i * 16 + 8);
const length = font.getUint32(startOffset + 12 + i * 16 + 12);
return new DataView(fontDataView.buffer, offset, length);
}
}
GameGlobal.manager.Logger.pluginError(`\tTable#${tableName} not found in DataView`);
return undefined;
}
function parseNameTable(fontDataView, startOffset = 0) {
const nameTable = parseTableToDataView(fontDataView, 'name', startOffset);
if (!nameTable) {
return undefined;
}
const result = {};
result.data = nameTable;
result.format = nameTable.getUint16(0);
result.count = nameTable.getUint16(2);
result.stringOffset = nameTable.getUint16(4);
const nameRecords = [];
for (let i = 0; i < result.count; i++) {
const offset = 6 + i * 12;
nameRecords.push({
platformID: nameTable.getUint16(offset),
platformSpecificID: nameTable.getUint16(offset + 2),
languageID: nameTable.getUint16(offset + 4),
nameID: nameTable.getUint16(offset + 6),
length: nameTable.getUint16(offset + 8),
offset: nameTable.getUint16(offset + 10),
});
}
result.nameRecords = nameRecords;
return result;
}
function parseFamilyName(fontDataView, startOffset = 0) {
const nameTable = parseNameTable(fontDataView, startOffset);
if (!nameTable) {
return undefined;
}
if (nameTable.nameRecords) {
for (const record of nameTable.nameRecords) {
const { nameID } = record;
if (nameID === 1) {
const { offset } = record;
const byteLength = record.length;
return decodeUnicode(fontDataView.buffer, (nameTable.data?.byteOffset || 0) + (nameTable.stringOffset || 0) + offset, byteLength);
}
}
}
return undefined;
}
export default function splitTTCToBufferOnlySC(arrayBuffer) {
const ttc = new DataView(arrayBuffer);
const tag = ttc.getUint32(0);
if (toBytesInt32(tag) !== 'ttcf') {
GameGlobal.manager.Logger.pluginError('input not a valid ttc file');
return undefined;
}
const ttfCount = ttc.getInt32(8);
let fontSCHeaderOffset = undefined;
const reg = /S\0?C/;
for (let i = 0; i < ttfCount; i++) {
const tableHeaderOffset = ttc.getUint32(0x0C + i * 4);
const familyName = parseFamilyName(ttc, tableHeaderOffset);
if (typeof familyName === 'string' && reg.test(familyName)) {
fontSCHeaderOffset = tableHeaderOffset;
break;
}
}
if (!fontSCHeaderOffset) {
GameGlobal.manager.Logger.pluginError('SC Font not found in TTC File.');
return undefined;
}
return extractTTF(ttc, fontSCHeaderOffset).buffer;
}
export function toBytesInt32(num) {
let ascii = '';
for (let i = 3; i >= 0; i--) {
ascii += String.fromCharCode((num >> (8 * i)) & 255);
}
return ascii;
}
;
export function ceil4(n) {
return (n + 3) & ~3;
}
export function decodeUnicode(buffer, byteOffset, byteLength) {
const dataview = new Uint8Array(buffer, byteOffset, byteLength);
const ret = String.fromCharCode.apply(null, Array.from(dataview));
return ret;
}
import moduleHelper from './module-helper';
import { formatJsonStr, getListObject, uid } from './utils';
const gameClubButtonList = {};
const typeEnum = {
0: 'text',
1: 'image',
};
const iconEnum = {
0: 'green',
1: 'white',
2: 'dark',
3: 'light',
};
const getObject = getListObject(gameClubButtonList, 'gameClubButton');
export default {
WXCreateGameClubButton(conf) {
const config = formatJsonStr(conf);
// @ts-ignore
config.style = JSON.parse(config.styleRaw);
if (config.style.fontSize === 0) {
// @ts-ignore
config.style.fontSize = undefined;
}
// @ts-ignore
config.type = typeEnum[config.type];
// @ts-ignore
config.icon = iconEnum[config.icon];
if (!config.text) {
config.text = '';
}
const id = uid();
gameClubButtonList[id] = wx.createGameClubButton(config);
return id;
},
WXGameClubButtonDestroy(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.destroy();
if (gameClubButtonList) {
delete gameClubButtonList[id];
}
},
WXGameClubButtonHide(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.hide();
},
WXGameClubButtonShow(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.show();
},
WXGameClubButtonAddListener(id, key) {
const obj = getObject(id);
if (!obj) {
return;
}
obj[key](() => {
moduleHelper.send('OnGameClubButtonCallback', JSON.stringify({
callbackId: id,
errMsg: key,
}));
});
},
WXGameClubButtonRemoveListener(id, key) {
const obj = getObject(id);
if (!obj) {
return;
}
obj[key]();
},
WXGameClubButtonSetProperty(id, key, value) {
const obj = getObject(id);
if (!obj) {
return;
}
obj[key] = value;
},
WXGameClubStyleChangeInt(id, key, value) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.style[key] = value;
},
WXGameClubStyleChangeStr(id, key, value) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.style[key] = value;
},
};
import moduleHelper from './module-helper';
import { formatJsonStr, getListObject, uid } from './utils';
const gameRecorderList = {};
let wxGameRecorderList;
const getObject = getListObject(gameRecorderList, 'gameRecorder');
export default {
WX_GetGameRecorder() {
const id = uid();
gameRecorderList[id] = wx.getGameRecorder();
return id;
},
WX_GameRecorderOff(id, eventType) {
const obj = getObject(id);
if (!obj) {
return;
}
if (!obj || typeof wxGameRecorderList === 'undefined' || typeof wxGameRecorderList[eventType] === 'undefined') {
return;
}
// eslint-disable-next-line no-restricted-syntax
for (const key in Object.keys(wxGameRecorderList[eventType])) {
const callback = wxGameRecorderList[eventType][key];
if (callback) {
obj.off(eventType, callback);
}
}
wxGameRecorderList[eventType] = {};
},
WX_GameRecorderOn(id, eventType) {
const obj = getObject(id);
if (!obj) {
return;
}
if (!wxGameRecorderList) {
wxGameRecorderList = {
start: {},
stop: {},
pause: {},
resume: {},
abort: {},
timeUpdate: {},
error: {},
};
}
const callbackId = uid();
const callback = (res) => {
let result = '';
if (res) {
result = JSON.stringify(res);
}
const resStr = JSON.stringify({
id,
res: JSON.stringify({
eventType,
result,
}),
});
moduleHelper.send('_OnGameRecorderCallback', resStr);
};
if (wxGameRecorderList[eventType]) {
wxGameRecorderList[eventType][callbackId] = callback;
obj.on(eventType, callback);
return callbackId;
}
return '';
},
WX_GameRecorderStart(id, option) {
const obj = getObject(id);
if (!obj) {
return;
}
const data = formatJsonStr(option);
obj.start(data);
},
WX_GameRecorderAbort(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.abort();
},
WX_GameRecorderPause(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.pause();
},
WX_GameRecorderResume(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.resume();
},
WX_GameRecorderStop(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.stop();
},
WX_OperateGameRecorderVideo(option) {
if (typeof wx.operateGameRecorderVideo !== 'undefined') {
const data = formatJsonStr(option);
data.fail = (res) => {
console.error(res);
};
wx.operateGameRecorderVideo(data);
}
},
};
/* eslint-disable @typescript-eslint/naming-convention */
import { formatJsonStr, formatResponse, convertDataToPointer } from '../utils';
let wxStartGyroscopeCallback;
let wxStopGyroscopeCallback;
let wxOnGyroscopeChangeCallback;
const OnGyroscopeChange = (res) => {
formatResponse('OnGyroscopeChangeListenerResult', res);
const xPtr = convertDataToPointer(res.x);
const yPtr = convertDataToPointer(res.y);
const zPtr = convertDataToPointer(res.z);
GameGlobal.Module.dynCall_viii(wxOnGyroscopeChangeCallback, xPtr, yPtr, zPtr);
GameGlobal.Module._free(xPtr);
GameGlobal.Module._free(yPtr);
GameGlobal.Module._free(zPtr);
};
function handleCallback(callback, id, callbackType, res) {
formatResponse('GeneralCallbackResult', res);
const idPtr = convertDataToPointer(id);
const msgPtr = convertDataToPointer(res.errMsg);
GameGlobal.Module.dynCall_viii(callback, idPtr, callbackType, msgPtr);
GameGlobal.Module._free(idPtr);
GameGlobal.Module._free(msgPtr);
}
function WX_StartGyroscope(id, conf) {
const config = formatJsonStr(conf);
wx.startGyroscope({
...config,
success(res) {
handleCallback(wxStartGyroscopeCallback, id, 2, res);
},
fail(res) {
handleCallback(wxStartGyroscopeCallback, id, 1, res);
},
complete(res) {
handleCallback(wxStartGyroscopeCallback, id, 0, res);
},
});
}
function WX_StopGyroscope(id, conf) {
const config = formatJsonStr(conf);
wx.stopGyroscope({
...config,
success(res) {
handleCallback(wxStopGyroscopeCallback, id, 2, res);
},
fail(res) {
handleCallback(wxStopGyroscopeCallback, id, 1, res);
},
complete(res) {
handleCallback(wxStopGyroscopeCallback, id, 0, res);
},
});
}
function WX_OnGyroscopeChange() {
wx.onGyroscopeChange(OnGyroscopeChange);
}
function WX_OffGyroscopeChange() {
wx.offGyroscopeChange();
}
function WX_RegisterStartGyroscopeCallback(callback) {
wxStartGyroscopeCallback = callback;
}
function WX_RegisterStopGyroscopeCallback(callback) {
wxStopGyroscopeCallback = callback;
}
function WX_RegisterOnGyroscopeChangeCallback(callback) {
wxOnGyroscopeChangeCallback = callback;
}
export default {
WX_StartGyroscope,
WX_StopGyroscope,
WX_OnGyroscopeChange,
WX_OffGyroscopeChange,
WX_RegisterStartGyroscopeCallback,
WX_RegisterStopGyroscopeCallback,
WX_RegisterOnGyroscopeChangeCallback,
};

import storage from './storage';
import userInfo from './userinfo';
import moduleHelper from './module-helper';
import share from './share';
import ad from './ad';
import canvasHelper from './canvas';
import fs from './fs';
import openData from './open-data';
import util from './util';
import cloud from './cloud';
import audio from './audio/index';
import texture from './texture';
import fix from './fix';
import canvasContext from './canvas-context';
import video from './video';
import logger from './logger';
import gameClub from './game-club';
import sdk from './sdk';
import camera from './camera';
import recorder from './recorder';
import uploadFile from './upload-file';
import gameRecorder from './game-recorder';
import chat from './chat';
import font from './font/index';
import authorize from './authorize';
import videoDecoder from './video/index';
import mobileKeyboard from './mobileKeyboard/index';
import touch from './touch/index';
import TCPSocket from './TCPSocket/index';
import UDPSocket from './UDPSocket/index';
import bluetooth from './bluetooth/index';
import gyroscope from './gyroscope/index';
const unityVersion = '2022.3.62f2c1';
GameGlobal.unityNamespace = GameGlobal.unityNamespace || {};
GameGlobal.unityNamespace.unityVersion = unityVersion;
window._ScaleRate = 1;
if (unityVersion && unityVersion.split('.').slice(0, 2)
.join('') < '20193') {
const width = window.innerWidth * window.devicePixelRatio;
const height = window.innerHeight * window.devicePixelRatio;
canvas.width = width;
canvas.height = height;
window._ScaleRate = window.devicePixelRatio;
}
Object.defineProperty(canvas, 'clientHeight', {
get() {
return window.innerHeight * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(canvas, 'clientWidth', {
get() {
return window.innerWidth * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(document.body, 'clientHeight', {
get() {
return window.innerHeight * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(document.body, 'clientWidth', {
get() {
return window.innerWidth * window._ScaleRate;
},
configurable: true,
});
Object.defineProperty(document, 'fullscreenEnabled', {
get() {
return true;
},
configurable: true,
});
fix.init();
const WXWASMSDK = {
WXInitializeSDK() {
moduleHelper.init();
moduleHelper.send('Inited', 200);
},
...storage,
...userInfo,
...share,
...ad,
...canvasHelper,
...fs,
...openData,
...util,
...cloud,
...audio,
...texture,
...video,
...logger,
...gameClub,
canvasContext,
...sdk,
...camera,
...recorder,
...uploadFile,
...gameRecorder,
...chat,
...font,
...authorize,
...videoDecoder,
...mobileKeyboard,
...touch,
...TCPSocket,
...UDPSocket,
...bluetooth,
...gyroscope,
};
GameGlobal.WXWASMSDK = WXWASMSDK;
let logger;
export default {
WXLogManagerDebug(str) {
if (!logger) {
logger = wx.getLogManager({ level: 0 });
}
logger.debug(str);
},
WXLogManagerInfo(str) {
if (!logger) {
logger = wx.getLogManager({ level: 0 });
}
logger.info(str);
},
WXLogManagerLog(str) {
if (!logger) {
logger = wx.getLogManager({ level: 0 });
}
logger.log(str);
},
WXLogManagerWarn(str) {
if (!logger) {
logger = wx.getLogManager({ level: 0 });
}
logger.warn(str);
},
};
/* eslint-disable @typescript-eslint/naming-convention */
let FrameworkData = null;
const keyboardSetting = {
value: '',
maxLength: 140,
multiple: false,
confirmHold: false,
confirmType: 'done',
};
const keyboardInputlistener = function (res) {
keyboardSetting.value = res.value;
};
const keyboardConfirmlistener = function (res) {
keyboardSetting.value = res.value;
_JS_MobileKeyboard_Hide(false);
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const keyboardCompletelistener = function (res) {
removeKeyboardListeners();
};
let hasExistingMobileInput = false;
let mobile_input_hide_delay = null;
let mobile_input_ignore_blur_event = false;
function _JS_MobileKeybard_GetIgnoreBlurEvent() {
return mobile_input_ignore_blur_event;
}
function _JS_MobileKeyboard_GetKeyboardStatus() {
const kKeyboardStatusVisible = 0;
const kKeyboardStatusDone = 1;
if (!hasExistingMobileInput) {
return kKeyboardStatusDone;
}
return kKeyboardStatusVisible;
}
function _JS_MobileKeyboard_GetText(buffer, bufferSize) {
if (buffer) {
FrameworkData.stringToUTF8(keyboardSetting.value, buffer, bufferSize);
}
return FrameworkData.lengthBytesUTF8(keyboardSetting.value);
}
function _JS_MobileKeyboard_GetTextSelection(outStart, outLength) {
const n = keyboardSetting.value.length;
FrameworkData.HEAP32[outStart >> 2] = n;
FrameworkData.HEAP32[outLength >> 2] = 0;
}
function _JS_MobileKeyboard_Hide(delay) {
if (mobile_input_hide_delay) {
return;
}
mobile_input_ignore_blur_event = true;
function hideMobileKeyboard() {
if (hasExistingMobileInput) {
wx.hideKeyboard();
}
hasExistingMobileInput = false;
mobile_input_hide_delay = null;
setTimeout(() => {
mobile_input_ignore_blur_event = false;
}, 100);
}
if (delay) {
const hideDelay = 200;
mobile_input_hide_delay = setTimeout(hideMobileKeyboard, hideDelay);
}
else {
hideMobileKeyboard();
}
}
function _JS_MobileKeyboard_SetCharacterLimit(limit) {
keyboardSetting.maxLength = limit;
}
function _JS_MobileKeyboard_SetText(text) {
if (!hasExistingMobileInput) {
return;
}
keyboardSetting.value = FrameworkData.UTF8ToString(text);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _JS_MobileKeyboard_SetTextSelection(start, length) {
}
function _JS_MobileKeyboard_Show(text, keyboardType, autocorrection, multiline, secure, alert, placeholder, characterLimit, data) {
if (FrameworkData === null) {
FrameworkData = data;
}
if (mobile_input_hide_delay) {
clearTimeout(mobile_input_hide_delay);
mobile_input_hide_delay = null;
}
if (hasExistingMobileInput) {
if (keyboardSetting.multiple !== !!multiline) {
_JS_MobileKeyboard_Hide(false);
return;
}
}
keyboardSetting.value = FrameworkData.UTF8ToString(text);
keyboardSetting.maxLength = characterLimit > 0 ? characterLimit : 524288;
keyboardSetting.multiple = !!multiline;
wx.showKeyboard({ defaultValue: keyboardSetting.value, maxLength: keyboardSetting.maxLength, multiple: keyboardSetting.multiple, confirmHold: keyboardSetting.confirmHold, confirmType: keyboardSetting.confirmType });
addKeyboardListeners();
hasExistingMobileInput = true;
}
function addKeyboardListeners() {
wx.onKeyboardInput(keyboardInputlistener);
wx.onKeyboardConfirm(keyboardConfirmlistener);
wx.onKeyboardComplete(keyboardCompletelistener);
}
function removeKeyboardListeners() {
wx.offKeyboardInput(keyboardInputlistener);
wx.offKeyboardConfirm(keyboardConfirmlistener);
wx.offKeyboardComplete(keyboardCompletelistener);
}
export default {
_JS_MobileKeybard_GetIgnoreBlurEvent,
_JS_MobileKeyboard_GetKeyboardStatus,
_JS_MobileKeyboard_GetText,
_JS_MobileKeyboard_GetTextSelection,
_JS_MobileKeyboard_Hide,
_JS_MobileKeyboard_SetCharacterLimit,
_JS_MobileKeyboard_SetText,
_JS_MobileKeyboard_SetTextSelection,
_JS_MobileKeyboard_Show,
};
/* eslint-disable no-underscore-dangle */
import { MODULE_NAME } from './conf';
export default {
_send: null,
init() {
this._send = GameGlobal.Module.SendMessage;
},
send(method, str = '') {
if (!this._send) {
this.init();
}
// @ts-ignore
this._send(MODULE_NAME, method, str);
},
};
import response from './response';
import moduleHelper from './module-helper';
import { getDefaultData, debugLog } from './utils';
import { isSupportSharedCanvasMode } from '../check-version';
let cachedOpenDataContext;
let cachedSharedCanvas;
var SharedCanvasMode;
(function (SharedCanvasMode) {
SharedCanvasMode["ScreenCanvas"] = "screenCanvas";
SharedCanvasMode["OffScreenCanvas"] = "offscreenCanvas";
})(SharedCanvasMode || (SharedCanvasMode = {}));
let sharedCanvasMode;
let timerId;
let textureObject = null;
let unityTextureObject = null;
let textureId;
function getOpenDataContext(mode) {
if (cachedOpenDataContext) {
return cachedOpenDataContext;
}
if (!isSupportSharedCanvasMode) {
if (mode === 'ScreenCanvas') {
console.warn('[unity-sdk]: 当前环境不支持 ScreenCanvas 模式');
}
sharedCanvasMode = SharedCanvasMode.OffScreenCanvas;
}
if (!sharedCanvasMode) {
if (typeof mode === 'string' && SharedCanvasMode[mode]) {
sharedCanvasMode = SharedCanvasMode[mode];
}
else {
sharedCanvasMode = SharedCanvasMode.OffScreenCanvas;
}
}
console.log(`[unity-sdk]: 当前开放数据域为 ${sharedCanvasMode} 模式`);
// @ts-ignore
cachedOpenDataContext = wx.getOpenDataContext({
sharedCanvasMode,
});
return cachedOpenDataContext;
}
function getSharedCanvas() {
return cachedSharedCanvas || getOpenDataContext().canvas;
}
function hookUnityRender() {
if (!textureId) {
return;
}
const Module = GameGlobal.manager.gameInstance.Module;
const { GL } = Module;
const gl = GL.currentContext.GLctx;
const isLinearColorSpace = GameGlobal.unityNamespace.unityColorSpace === 'Linear';
if (gl.emscriptenGLX) {
Module.ccall('glxShowOpenData', null, ['number', 'number', 'bool'], [textureId, getSharedCanvas().__uid(), isLinearColorSpace]);
}
else {
const commonTexImage2DHandler = () => {
if (textureId) {
gl.bindTexture(gl.TEXTURE_2D, GL.textures[textureId]);
if (isLinearColorSpace) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, gl.RGBA, gl.UNSIGNED_BYTE, getSharedCanvas());
}
else {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, getSharedCanvas());
}
}
};
if (!textureObject) {
textureObject = gl.createTexture();
unityTextureObject = GL.textures[textureId];
GL.textures[textureId] = textureObject;
commonTexImage2DHandler();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
else {
commonTexImage2DHandler();
}
timerId = requestAnimationFrame(hookUnityRender);
}
}
function stopLastRenderLoop() {
if (typeof timerId !== 'undefined') {
cancelAnimationFrame(timerId);
}
}
function startHookUnityRender() {
stopLastRenderLoop();
hookUnityRender();
}
function stopHookUnityRender() {
stopLastRenderLoop();
const sharedCanvas = getSharedCanvas();
sharedCanvas.width = 1;
sharedCanvas.height = 1;
const Module = GameGlobal.manager.gameInstance.Module;
const { GL } = Module;
const gl = GL.currentContext.GLctx;
if (textureObject) {
gl.deleteTexture(textureObject);
GL.textures[textureId] = unityTextureObject;
textureObject = null;
unityTextureObject = null;
}
if (gl.emscriptenGLX) {
Module.ccall('glxHideOpenData', null, [], []);
}
}
wx.onShow(() => {
if (cachedOpenDataContext) {
getOpenDataContext().postMessage({
type: 'WXShow',
});
}
});
export default {
WXGetOpenDataContext(mode) {
debugLog('WXGetOpenDataContext:', mode);
getOpenDataContext(mode);
},
WXDataContextPostMessage(msg) {
debugLog('WXDataContextPostMessage:', msg);
getOpenDataContext().postMessage(msg);
},
WXShowOpenData(id, x, y, width, height) {
debugLog('WXShowOpenData:', id, x, y, width, height);
if (width <= 0 || height <= 0) {
console.error('[unity-sdk]: WXShowOpenData要求 width 和 height 参数必须大于0');
}
if (!cachedOpenDataContext) {
console.warn('[unity-sdk]: 请先调用 WXGetOpenDataContext');
}
const openDataContext = getOpenDataContext();
const sharedCanvas = openDataContext.canvas;
sharedCanvas.width = width;
sharedCanvas.height = height;
if (sharedCanvasMode === SharedCanvasMode.ScreenCanvas && sharedCanvas.style) {
sharedCanvas.style.left = `${x / window.devicePixelRatio}px`;
sharedCanvas.style.top = `${y / window.devicePixelRatio}px`;
sharedCanvas.style.width = `${width / window.devicePixelRatio}px`;
sharedCanvas.style.height = `${height / window.devicePixelRatio}px`;
}
openDataContext.postMessage({
type: 'WXRender',
x,
y,
width,
height,
devicePixelRatio: window.devicePixelRatio,
});
if (sharedCanvasMode === SharedCanvasMode.OffScreenCanvas) {
textureId = id;
startHookUnityRender();
}
},
WXHideOpenData() {
debugLog('WXHideOpenData');
if (!cachedOpenDataContext) {
console.warn('[unity-sdk]: 请先调用 WXGetOpenDataContext');
return;
}
getOpenDataContext().postMessage({
type: 'WXDestroy',
});
if (sharedCanvasMode === SharedCanvasMode.OffScreenCanvas) {
stopHookUnityRender();
}
else if (sharedCanvasMode === SharedCanvasMode.ScreenCanvas) {
const sharedCanvas = getSharedCanvas();
if (sharedCanvas.style) {
sharedCanvas.style.top = '9999px';
}
}
},
WXOpenDataToTempFilePathSync(conf) {
debugLog('WXOpenDataToTempFilePathSync', conf);
const sharedCanvas = getSharedCanvas();
if (!sharedCanvas) {
return 'Please use WX.GetOpenDataContext() first';
}
return sharedCanvas.toTempFilePathSync(getDefaultData(sharedCanvas, conf));
},
WXOpenDataToTempFilePath(conf, s, f, c) {
debugLog('WXOpenDataToTempFilePath', conf);
if (conf) {
const sharedCanvas = getSharedCanvas();
if (!sharedCanvas) {
console.error('Please use WX.GetOpenDataContext() first');
return;
}
sharedCanvas.toTempFilePath({
...getDefaultData(sharedCanvas, conf),
...response.handleText(s, f, c),
success: (res) => {
moduleHelper.send('ToTempFilePathCallback', JSON.stringify({
callbackId: s,
errMsg: res.errMsg,
errCode: res.errCode || 0,
tempFilePath: res.tempFilePath,
}));
},
});
}
},
};
import moduleHelper from './module-helper';
import { formatJsonStr, cacheArrayBuffer, getListObject, uid } from './utils';
const recorderManagerList = {};
const getObject = getListObject(recorderManagerList, 'video');
export default {
WX_GetRecorderManager() {
const id = uid();
recorderManagerList[id] = wx.getRecorderManager();
return id;
},
WX_OnRecorderError(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('_OnRecorderErrorCallback', resStr);
};
obj.onError(callback);
},
WX_OnRecorderFrameRecorded(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
cacheArrayBuffer(id, res.frameBuffer);
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify({
frameBufferLength: res.frameBuffer.byteLength,
isLastFrame: res.isLastFrame,
}),
});
moduleHelper.send('_OnRecorderFrameRecordedCallback', resStr);
};
obj.onFrameRecorded(callback);
},
WX_OnRecorderInterruptionBegin(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('_OnRecorderInterruptionBeginCallback', resStr);
};
obj.onInterruptionBegin(callback);
},
WX_OnRecorderInterruptionEnd(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('_OnRecorderInterruptionEndCallback', resStr);
};
obj.onInterruptionEnd(callback);
},
WX_OnRecorderPause(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('_OnRecorderPauseCallback', resStr);
};
obj.onPause(callback);
},
WX_OnRecorderResume(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('_OnRecorderResumeCallback', resStr);
};
obj.onResume(callback);
},
WX_OnRecorderStart(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('_OnRecorderStartCallback', resStr);
};
obj.onStart(callback);
},
WX_OnRecorderStop(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = (res) => {
const resStr = JSON.stringify({
callbackId: id,
res: JSON.stringify(res),
});
moduleHelper.send('_OnRecorderStopCallback', resStr);
};
obj.onStop(callback);
},
WX_RecorderPause(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.pause();
},
WX_RecorderResume(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.resume();
},
WX_RecorderStart(id, option) {
const obj = getObject(id);
if (!obj) {
return;
}
const conf = formatJsonStr(option);
obj.start(conf);
},
WX_RecorderStop(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.stop();
},
};
export const ResTypeOther = {
Stats: {
lastAccessedTime: 'number',
lastModifiedTime: 'number',
mode: 'number',
size: 'number',
},
TCPSocketOnMessageListenerResult: {
localInfo: 'LocalInfo',
message: 'arrayBuffer',
remoteInfo: 'RemoteInfo',
},
LocalInfo: {
address: 'string',
family: 'string',
port: 'number',
},
RemoteInfo: {
address: 'string',
family: 'string',
port: 'number',
},
UDPSocketConnectOption: {
address: 'string',
port: 'number',
},
UDPSocketOnMessageListenerResult: {
localInfo: 'LocalInfo',
message: 'arrayBuffer',
remoteInfo: 'RemoteInfo',
},
UDPSocketSendOption: {
address: 'string',
message: 'string|arrayBuffer',
port: 'number',
length: 'number',
offset: 'number',
setBroadcast: 'bool',
},
UDPSocketSendParam: {
address: 'string',
port: 'number',
length: 'number',
offset: 'number',
setBroadcast: 'bool',
},
CallFunctionResult: {
result: 'string',
requestID: 'string',
errMsg: 'string',
},
CallContainerResult: {
data: 'string',
statusCode: 'number',
header: 'object',
callID: 'string',
errMsg: 'string',
},
UploadFileResult: {
fileID: 'string',
statusCode: 'number',
errMsg: 'string',
},
DownloadFileResult: {
tempFilePath: 'string',
statusCode: 'number',
errMsg: 'string',
},
GetTempFileURLResult: {
fileList: 'GetTempFileURLResultItem[]',
errMsg: 'string',
},
GetTempFileURLResultItem: {
fileID: 'string',
tempFileURL: 'string',
maxAge: 'number',
status: 'number',
errMsg: 'string',
},
DeleteFileResult: {
fileList: 'DeleteFileResultItem[]',
errMsg: 'string',
},
DeleteFileResultItem: {
fileID: 'string',
status: 'number',
errMsg: 'string',
},
LoadOption: {
openlink: 'string',
query: 'object',
},
ShowOption: {
openlink: 'string',
query: 'object',
},
};
/* eslint-disable @typescript-eslint/no-this-alias */
import moduleHelper from './module-helper';
export default {
handleText(s, f, c) {
const self = this;
return {
success(res) {
self.textFormat(s, res);
},
fail(res) {
self.textFormat(f, res);
},
complete(res) {
self.textFormat(c, res);
},
};
},
handleTextLongBack(s, f, c) {
const self = this;
return {
success(res) {
self.textFormatLongBack(s, res);
},
fail(res) {
self.textFormatLongBack(f, res);
},
complete(res) {
self.textFormatLongBack(c, res);
},
};
},
textFormat(id, res) {
if (!id) {
return false;
}
moduleHelper.send('TextResponseCallback', JSON.stringify({
callbackId: id,
errMsg: res.errMsg,
errCode: res.errCode,
}));
},
textFormatLongBack(id, res) {
if (!id) {
return false;
}
moduleHelper.send('TextResponseLongCallback', JSON.stringify({
callbackId: id,
errMsg: res.errMsg,
errCode: res.errCode,
}));
},
handle(formatFunc, s, f, c) {
return {
success(res) {
if (!s) {
return false;
}
formatFunc(s, res);
},
fail(res) {
if (!f) {
return false;
}
formatFunc(f, res);
},
complete(res) {
if (!c) {
return false;
}
formatFunc(c, res);
},
};
},
};
import moduleHelper from './module-helper';
import { formatJsonStr } from './utils';
let shareResolve;
export default {
WXShareAppMessage(conf) {
wx.shareAppMessage({
...formatJsonStr(conf),
});
},
WXOnShareAppMessage(conf, isPromise) {
wx.onShareAppMessage(() => ({
...formatJsonStr(conf),
promise: isPromise
? new Promise((resolve) => {
shareResolve = resolve;
moduleHelper.send('OnShareAppMessageCallback');
})
: null,
}));
},
WXOnShareAppMessageResolve(conf) {
if (shareResolve) {
shareResolve(formatJsonStr(conf));
}
},
};
wx.showShareMenu({
menus: ['shareAppMessage', 'shareTimeline'],
});
/* eslint-disable no-underscore-dangle */
const PreLoadKeys = [];
const storage = {
_cacheData: {},
_handleList: [],
isRunning: false,
isCallDeletedAll: false,
getData(key, defaultValue) {
let v = this._cacheData[key];
if (v === null) {
return defaultValue;
}
if (typeof v !== 'undefined') {
return v;
}
if (this.isCallDeletedAll) {
return defaultValue;
}
try {
v = wx.getStorageSync(key);
this._cacheData[key] = v !== '' ? v : null;
return v === '' ? defaultValue : v;
}
catch (e) {
// console.error(e);
return defaultValue;
}
},
setData(key, value) {
this._cacheData[key] = value;
this._handleList.push({
type: 'setData',
key,
value,
});
this._doRun();
},
deleteKey(key) {
this._cacheData[key] = null;
this._handleList.push({
type: 'deleteKey',
key,
});
this._doRun();
},
deleteAll() {
Object.keys(this._cacheData).forEach((key) => {
this._cacheData[key] = null;
});
this.isCallDeletedAll = true;
this._handleList.push({
type: 'deleteAll',
});
this._doRun();
},
_doRun() {
if (this.isRunning || this._handleList.length === 0) {
return false;
}
this.isRunning = true;
const task = this._handleList.shift();
if (!task) {
this.isRunning = false;
this._doRun();
return;
}
if (task.type === 'setData') {
wx.setStorage({
key: task.key || 'defaultKey',
data: task.value,
fail({ errMsg }) {
console.error(errMsg);
},
complete: () => {
this.isRunning = false;
this._doRun();
},
});
}
else if (task.type === 'deleteKey') {
wx.removeStorage({
key: task.key || 'defaultKey',
fail({ errMsg }) {
console.error(errMsg);
},
complete: () => {
this.isRunning = false;
this._doRun();
},
});
}
else if (task.type === 'deleteAll') {
wx.clearStorage({
fail({ errMsg }) {
console.error(errMsg);
},
complete: () => {
this.isRunning = false;
this._doRun();
},
});
}
else {
this.isRunning = false;
this._doRun();
}
},
init() {
if (Array.isArray(PreLoadKeys) && PreLoadKeys.length > 0) {
const key = PreLoadKeys.shift();
wx.getStorage({
key,
success(res) {
storage._cacheData[key] = res.data;
storage.init();
},
fail() {
storage._cacheData[key] = null;
storage.init();
},
});
}
},
};
setTimeout(() => {
storage.init();
}, 0);
export default {
WXStorageGetIntSync(key, defaultValue) {
return +(storage.getData(key, defaultValue) || '');
},
WXStorageSetIntSync(key, value) {
storage.setData(key, value);
},
WXStorageGetFloatSync(key, defaultValue) {
return +(storage.getData(key, defaultValue) || '');
},
WXStorageSetFloatSync(key, value) {
storage.setData(key, value);
},
WXStorageGetStringSync(key, defaultValue) {
return storage.getData(key, defaultValue) || '';
},
WXStorageSetStringSync(key, value) {
storage.setData(key, value);
},
WXStorageDeleteAllSync() {
storage.deleteAll();
},
WXStorageDeleteKeySync(key) {
storage.deleteKey(key);
},
WXStorageHasKeySync(key) {
return storage.getData(key, '') !== '';
},
};
/* eslint-disable @typescript-eslint/naming-convention */
import { formatTouchEvent, convertOnTouchStartListenerResultToPointer } from '../utils';
let wxOnTouchCancelCallback;
let wxOnTouchEndCallback;
let wxOnTouchMoveCallback;
let wxOnTouchStartCallback;
function handleTouchEvent(res, callback) {
const dataPtr = convertOnTouchStartListenerResultToPointer({
touches: res.touches.map(v => formatTouchEvent(v, res.type)),
changedTouches: res.changedTouches.map(v => formatTouchEvent(v, res.type, 1)),
timeStamp: parseInt(res.timeStamp.toString(), 10),
});
GameGlobal.Module.dynCall_viii(callback, dataPtr, res.touches.length, res.changedTouches.length);
GameGlobal.Module._free(dataPtr);
}
const OnTouchCancel = (res) => {
handleTouchEvent(res, wxOnTouchCancelCallback);
};
const OnTouchEnd = (res) => {
handleTouchEvent(res, wxOnTouchEndCallback);
};
const OnTouchMove = (res) => {
handleTouchEvent(res, wxOnTouchMoveCallback);
};
const OnTouchStart = (res) => {
handleTouchEvent(res, wxOnTouchStartCallback);
};
function WX_OnTouchCancel() {
wx.onTouchCancel(OnTouchCancel);
}
function WX_OffTouchCancel() {
wx.offTouchCancel(OnTouchCancel);
}
function WX_OnTouchEnd() {
wx.onTouchEnd(OnTouchEnd);
}
function WX_OffTouchEnd() {
wx.offTouchEnd(OnTouchEnd);
}
function WX_OnTouchMove() {
wx.onTouchMove(OnTouchMove);
}
function WX_OffTouchMove() {
wx.offTouchMove(OnTouchMove);
}
function WX_OnTouchStart() {
wx.onTouchStart(OnTouchStart);
}
function WX_OffTouchStart() {
wx.offTouchStart(OnTouchStart);
}
function WX_RegisterOnTouchCancelCallback(callback) {
wxOnTouchCancelCallback = callback;
}
function WX_RegisterOnTouchEndCallback(callback) {
wxOnTouchEndCallback = callback;
}
function WX_RegisterOnTouchMoveCallback(callback) {
wxOnTouchMoveCallback = callback;
}
function WX_RegisterOnTouchStartCallback(callback) {
wxOnTouchStartCallback = callback;
}
export default {
WX_OnTouchCancel,
WX_OffTouchCancel,
WX_OnTouchEnd,
WX_OffTouchEnd,
WX_OnTouchMove,
WX_OffTouchMove,
WX_OnTouchStart,
WX_OffTouchStart,
WX_RegisterOnTouchCancelCallback,
WX_RegisterOnTouchEndCallback,
WX_RegisterOnTouchMoveCallback,
WX_RegisterOnTouchStartCallback,
};
import moduleHelper from './module-helper';
import { formatJsonStr, getListObject, offEventCallback, onEventCallback } from './utils';
const uploadTaskList = {};
const wxUpdateTaskOnProgressList = {};
const wxUpdateTaskOnHeadersList = {};
const getObject = getListObject(uploadTaskList, 'uploadTask');
export default {
WX_UploadFile(option, callbackId) {
const conf = formatJsonStr(option);
const obj = wx.uploadFile({
...conf,
success: (res) => {
moduleHelper.send('UploadFileCallback', JSON.stringify({
callbackId,
type: 'success',
res: JSON.stringify(res),
}));
},
fail: (res) => {
moduleHelper.send('UploadFileCallback', JSON.stringify({
callbackId,
type: 'fail',
res: JSON.stringify(res),
}));
},
complete: (res) => {
moduleHelper.send('UploadFileCallback', JSON.stringify({
callbackId,
type: 'complete',
res: JSON.stringify(res),
}));
setTimeout(() => {
if (uploadTaskList) {
delete uploadTaskList[callbackId];
}
}, 0);
},
});
uploadTaskList[callbackId] = obj;
},
WXUploadTaskAbort(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.abort();
},
WXUploadTaskOffHeadersReceived(id) {
const obj = getObject(id);
if (!obj) {
return;
}
offEventCallback(wxUpdateTaskOnHeadersList, (v) => {
obj.offHeadersReceived(v);
}, id);
},
WXUploadTaskOffProgressUpdate(id) {
const obj = getObject(id);
if (!obj) {
return;
}
offEventCallback(wxUpdateTaskOnProgressList, (v) => {
obj.offProgressUpdate(v);
}, id);
},
WXUploadTaskOnHeadersReceived(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxUpdateTaskOnHeadersList, '_OnHeadersReceivedCallback', id);
obj.onHeadersReceived(callback);
},
WXUploadTaskOnProgressUpdate(id) {
const obj = getObject(id);
if (!obj) {
return;
}
const callback = onEventCallback(wxUpdateTaskOnProgressList, '_OnProgressUpdateCallback', id);
obj.onProgressUpdate(callback);
},
};
import moduleHelper from './module-helper';
import { getListObject, uid } from './utils';
const userInfoButtonList = {};
const getObject = getListObject(userInfoButtonList, 'userInfoButton');
export default {
WXCreateUserInfoButton(x, y, width, height, lang, withCredentials) {
const id = uid();
const button = wx.createUserInfoButton({
type: 'text',
text: '',
withCredentials,
lang,
style: {
left: x / window.devicePixelRatio,
top: y / window.devicePixelRatio,
width: width / window.devicePixelRatio,
height: height / window.devicePixelRatio,
backgroundColor: 'rgba(0, 0, 0, 0)',
color: 'rgba(0, 0, 0, 0)',
textAlign: 'center',
fontSize: 0,
borderRadius: 0,
borderColor: '#FFFFFF',
borderWidth: 0,
lineHeight: height / window.devicePixelRatio,
},
});
userInfoButtonList[id] = button;
return id;
},
WXUserInfoButtonShow(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.show();
},
WXUserInfoButtonDestroy(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.destroy();
if (userInfoButtonList) {
delete userInfoButtonList[id];
}
},
WXUserInfoButtonHide(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.hide();
},
WXUserInfoButtonOffTap(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.offTap();
},
WXUserInfoButtonOnTap(id) {
const obj = getObject(id);
if (!obj) {
return;
}
obj.onTap((res) => {
res.userInfo = res.userInfo || {};
moduleHelper.send('UserInfoButtonOnTapCallback', JSON.stringify({
callbackId: id,
errCode: res.err_code || (res.errMsg.indexOf('getUserInfo:fail') === 0 ? 1 : 0),
errMsg: res.errMsg || '',
signature: res.signature || '',
encryptedData: res.encryptedData || '',
iv: res.iv || '',
cloudID: res.cloudID || '',
userInfoRaw: JSON.stringify({
nickName: res.userInfo.nickName || '',
avatarUrl: res.userInfo.avatarUrl || '',
country: res.userInfo.country || '',
province: res.userInfo.province || '',
city: res.userInfo.city || '',
language: res.userInfo.language || '',
gender: res.userInfo.gender || 0,
}),
}));
});
},
};
import moduleHelper from './module-helper';
import { launchEventType } from '../plugin-config';
import { setArrayBuffer, uid } from './utils';
import '../events';
export default {
WXReportGameStart() {
GameGlobal.manager.reportCustomLaunchInfo();
},
WXReportGameSceneError(sceneId, errorType, errStr, extInfo) {
if (GameGlobal.manager && GameGlobal.manager.reportGameSceneError) {
GameGlobal.manager.reportGameSceneError(sceneId, errorType, errStr, extInfo);
}
},
WXWriteLog(str) {
if (GameGlobal.manager && GameGlobal.manager.writeLog) {
GameGlobal.manager.writeLog(str);
}
},
WXWriteWarn(str) {
if (GameGlobal.manager && GameGlobal.manager.writeWarn) {
GameGlobal.manager.writeWarn(str);
}
},
WXHideLoadingPage() {
if (GameGlobal.manager && GameGlobal.manager.hideLoadingPage) {
GameGlobal.manager.hideLoadingPage();
}
},
WXReportUserBehaviorBranchAnalytics(branchId, branchDim, eventType) {
wx.reportUserBehaviorBranchAnalytics({ branchId, branchDim, eventType });
},
WXPreloadConcurrent(count) {
if (GameGlobal.manager && GameGlobal.manager.setConcurrent) {
GameGlobal.manager.setConcurrent(count);
}
},
WXIsCloudTest() {
if (typeof GameGlobal.isTest !== 'undefined' && GameGlobal.isTest) {
return true;
}
return false;
},
WXUncaughtException(needAbort) {
function currentStackTrace() {
const err = new Error('WXUncaughtException');
return err;
}
const err = currentStackTrace();
let fullTrace = err.stack?.toString();
if (fullTrace) {
const posOfThisFunc = fullTrace.indexOf('WXUncaughtException');
if (posOfThisFunc !== -1) {
fullTrace = fullTrace.substr(posOfThisFunc);
}
const posOfRaf = fullTrace.lastIndexOf('browserIterationFunc');
if (posOfRaf !== -1) {
fullTrace = fullTrace.substr(0, posOfRaf);
}
}
const realTimelog = wx.getRealtimeLogManager();
realTimelog.error(fullTrace);
const logmanager = wx.getLogManager({ level: 0 });
logmanager.warn(fullTrace);
if (needAbort === true) {
GameGlobal.onCrash(err);
throw err;
}
else {
setTimeout(() => {
throw err;
}, 0);
}
},
WXCleanAllFileCache() {
if (GameGlobal.manager && GameGlobal.manager.cleanCache) {
const key = uid();
GameGlobal.manager.cleanAllCache().then((res) => {
moduleHelper.send('CleanAllFileCacheCallback', JSON.stringify({
callbackId: key,
result: res,
}));
});
return key;
}
return '';
},
WXCleanFileCache(fileSize) {
if (GameGlobal.manager && GameGlobal.manager.cleanCache) {
const key = uid();
GameGlobal.manager.cleanCache(fileSize).then((res) => {
moduleHelper.send('CleanFileCacheCallback', JSON.stringify({
callbackId: key,
result: res,
}));
});
return key;
}
return '';
},
WXRemoveFile(path) {
if (GameGlobal.manager && GameGlobal.manager.removeFile && path) {
const key = uid();
GameGlobal.manager.removeFile(path).then((res) => {
moduleHelper.send('RemoveFileCallback', JSON.stringify({
callbackId: key,
result: res,
}));
});
return key;
}
return '';
},
WXGetCachePath(url) {
if (GameGlobal.manager && GameGlobal.manager.getCachePath) {
return GameGlobal.manager.getCachePath(url);
}
},
WXGetPluginCachePath() {
if (GameGlobal.manager && GameGlobal.manager.PLUGIN_CACHE_PATH) {
return GameGlobal.manager.PLUGIN_CACHE_PATH;
}
},
WXOnLaunchProgress() {
if (GameGlobal.manager && GameGlobal.manager.onLaunchProgress) {
const key = uid();
// 异步执行,保证C#已经记录这个回调ID
setTimeout(() => {
GameGlobal.manager.onLaunchProgress((e) => {
moduleHelper.send('OnLaunchProgressCallback', JSON.stringify({
callbackId: key,
res: JSON.stringify(Object.assign({}, e.data, {
type: e.type,
})),
}));
if (e.type === launchEventType.prepareGame) {
moduleHelper.send('RemoveLaunchProgressCallback', JSON.stringify({
callbackId: key,
}));
}
});
}, 0);
return key;
}
return '';
},
WXSetDataCDN(path) {
if (GameGlobal.manager && GameGlobal.manager.setDataCDN) {
GameGlobal.manager.setDataCDN(path);
}
},
WXSetPreloadList(paths) {
if (GameGlobal.manager && GameGlobal.manager.setPreloadList) {
const list = (paths || '').split(',').filter(str => !!str && !!str.trim());
GameGlobal.manager.setPreloadList(list);
}
},
WXSetArrayBuffer(buffer, offset, callbackId) {
setArrayBuffer(buffer, offset, callbackId);
},
WXLaunchOperaBridge(args) {
const res = GameGlobal.events.emit('launchOperaMsgBridgeFromWasm', args);
if (Array.isArray(res) && res.length > 0) {
return res[0];
}
return null;
},
WXLaunchOperaBridgeToC(callback, args) {
moduleHelper.send('WXLaunchOperaBridgeToC', JSON.stringify({
callback,
args,
}));
},
WX_SetPreferredFramesPerSecond(fps) {
wx.setPreferredFramesPerSecond(fps);
},
};
import moduleHelper from './module-helper';
import { formatJsonStr, getListObject, uid } from './utils';
const videoList = {};
const getObject = getListObject(videoList, 'video');
export default {
WXCreateVideo(conf) {
const id = uid();
const params = formatJsonStr(conf);
if (params.underGameView) {
GameGlobal.enableTransparentCanvas = true;
}
videoList[id] = wx.createVideo(params);
return id;
},
WXVideoSetProperty(id, key, value) {
const obj = getObject(id);
if (!obj) {
return;
}
if (key === 'x' || key === 'y' || key === 'width' || key === 'height' || key === 'initialTime' || key === 'playbackRate') {
obj[key] = +value;
}
else if (key === 'src' || key === 'poster' || key === 'objectFit' || key === 'backgroundColor') {
obj[key] = value;
}
else if (key === 'live' || key === 'controls' || key === 'showProgress' || key === 'showProgressInControlMode'
|| key === 'autoplay' || key === 'loop' || key === 'muted' || key === 'obeyMuteSwitch'
|| key === 'enableProgressGesture' || key === 'enablePlayGesture' || key === 'showCenterPlayBtn') {
obj[key] = value === 'True';
}
},
WXVideoAddListener(id, key) {
getObject(id)?.[key]((e) => {
moduleHelper.send('OnVideoCallback', JSON.stringify({
callbackId: id,
type: key,
position: e?.position,
buffered: e?.buffered ? Number(e.buffered) : undefined,
duration: e?.duration,
errMsg: e?.errMsg,
}));
if (key === 'onError') {
GameGlobal.enableTransparentCanvas = false;
console.error(e);
}
});
},
WXVideoRemoveListener(id, key) {
getObject(id)?.[key]();
},
WXVideoDestroy(id, isLast) {
getObject(id)?.destroy();
if (isLast) {
GameGlobal.enableTransparentCanvas = false;
}
},
WXVideoPlay(id) {
getObject(id)?.play();
},
WXVideoPause(id) {
getObject(id)?.pause();
},
WXVideoStop(id) {
getObject(id)?.stop();
},
WXVideoSeek(id, time) {
getObject(id)?.seek(time);
},
WXVideoRequestFullScreen(id, direction) {
getObject(id)?.requestFullScreen(direction);
},
WXVideoExitFullScreen(id) {
getObject(id)?.exitFullScreen();
},
};
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
// 消息类型
const messageType = {
config: 0,
writeFile: 1, // 写文件
};
// @ts-ignore SDK实际有暴露这几个API,但是协议里没有
const { createSharedArrayBuffer, getFileSystemManager } = worker;
const fs = getFileSystemManager ? getFileSystemManager() : null;
function compareVersion(_v1, _v2) {
return (_v1
.split('.')
.map(v => v.padStart(2, '0'))
.join('')
>= _v2
.split('.')
.map(v => v.padStart(2, '0'))
.join(''));
}
worker.onMessage((res) => {
const { type, payload } = res;
if (type === messageType.writeFile) {
const { filePath, data, isSharedBuffer } = payload;
let content = data;
if (isSharedBuffer) {
content = data.buffer;
}
if (!fs) {
console.error('getFileSystemManager不存在');
return;
}
fs.writeFile({
filePath,
data: content,
success: () => {
worker.postMessage({
type: messageType.writeFile,
payload: {
isok: true,
filePath,
},
});
},
fail: (err) => {
worker.postMessage({
type: messageType.writeFile,
payload: {
isok: false,
filePath,
err,
},
});
},
});
}
if (type === messageType.config) {
const { systemInfo } = payload;
const { platform, version } = systemInfo;
// 安卓才需要使用worker写文件
const isAndroid = platform.toLocaleLowerCase() === 'android';
// 8.0.18以下版本出现写文件报错
const isClientValid = compareVersion(version, '8.0.18');
worker.postMessage({
type: messageType.config,
payload: {
supportWorkerFs: isAndroid && !!fs && isClientValid,
supportSharedBuffer: isAndroid && !!createSharedArrayBuffer,
},
});
}
});
import SDK from './sdk.js'
const sdkBridgeMap = {
sdk: null,
initSdk: function(params) {
this.sdk = new SDK(params)
const resObj = {
type: 'initSdk'
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
},
getGameConf: async function() {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.getGameConf().then((res) => {
const result = {
...res,
data: Array.isArray(res.data) ? res.data : res.data.data || {}
}
const resObj = {
type: 'getGameConf',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
login: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
const {
query
} = wx.getEnterOptionsSync()
this.sdk
.login({
state: query.state || '',
query: query,
...params
})
.then((res) => {
const result = {
...res,
data: Array.isArray(res.data) ? res.data : res.data.data || {}
}
const resObj = {
type: 'login',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
updateUserInfo: async function() {
if (!this.sdk) return console.error('请初始化sdk')
wx.getSetting({
success: (res) => {
if (res.authSetting['scope.userInfo']) {
// 用户当前已授权,则可调用 wx.getUserInfo 获取用户最新个人信息
wx.getUserInfo({
success: (userInfo) => {
this.sdk
.updateUserInfo({
raw_data: userInfo.rawData,
signature: userInfo.signature,
encrypted_data: userInfo.encryptedData,
iv: userInfo.iv,
user_info: userInfo.userInfo
})
.then((res) => {
const result = {
...res,
data: Array.isArray(res.data) ? res.data : res.data.data || {}
}
const resObj = {
type: 'updateUserInfo',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
}
})
}
}
})
},
createOrder: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.createOrder(params).then((res) => {
const result = {
...res,
data: Array.isArray(res.data) ? res.data : res.data.data || {}
}
const resObj = {
type: 'createOrder',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
checkOrder: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.checkOrder(params).then((res) => {
const result = {
...res,
data: Array.isArray(res.data) ? res.data : res.data.data || {}
}
const resObj = {
type: 'checkOrder',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
getShareInfo: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.getShareInfo(params)
},
shareAppMessage: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.shareAppMessage(params)
},
updateRole: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.updateRole(params).then((res) => {
const resObj = {
type: 'updateRole',
result: res
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
checkMsg: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.checkMsg(params).then((res) => {
const result = {
...res,
data: Array.isArray(res.data) ? res.data : res.data.data || {}
}
const resObj = {
type: 'checkMsg',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
checkImg: async function() {
if (!this.sdk) return console.error('请初始化sdk')
wx.chooseImage({
count: 1,
success: (res) => {
this.sdk
.checkImg({
filePath: res.tempFilePaths[0]
})
.then((res) => {
const result = res.data
const resObj = {
type: 'checkImg',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
fail: (res) => console.error(res)
})
},
customMessage: function() {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.customMessage()
},
subscribeMessage: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.subscribeMessage(params).then((res) => {
const resObj = {
type: 'subscribeMessage',
result: res
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
gameClubSetStyle: function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.gameClubSetStyle(params)
},
gameClubShow: function() {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.gameClubShow()
},
gameClubHide: function() {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.gameClubHide()
},
gameClubDecryptedData: async function() {
if (!this.sdk) return console.error('请初始化sdk')
wx.getGameClubData({
dataTypeList: [{
type: 1
}],
success: (getGameClubData) => {
this.sdk
.gameClubDecryptedData({
encryptedData: getGameClubData.encryptedData,
iv: getGameClubData.iv,
signature: getGameClubData.signature
})
.then((res) => {
const result = {
...res,
data: Array.isArray(res.data) ? res.data : res.data.data || {}
}
const resObj = {
type: 'gameClubDecryptedData',
result
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
fail: (res) => console.error(res)
})
},
roleEventReport: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.roleEventReport(params).then((res) => {
const resObj = {
type: 'roleEventReport',
result: res
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
},
adReport: async function(params) {
if (!this.sdk) return console.error('请初始化sdk')
this.sdk.adReport(params).then((res) => {
const resObj = {
type: 'adReport',
result: res
}
Module.SendMessage('MiniGameSDKBridge', 'OnSuccessCallBack', JSON.stringify(resObj))
})
}
}
function sdkBridge(fn, params) {
sdkBridgeMap[fn](params)
}
GameGlobal['wxSdkBridge'] = sdkBridge
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论