You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
AdLike2048/assets/mx/tools/MiniGameHostInfo.ts

131 lines
5.4 KiB

/**
* 小游戏宿主设备信息。
* 微信:getSystemInfo 自 2.20.1 停维,鸿蒙 3.7.0+ 用 getDeviceInfo / getWindowInfo / getAppBaseInfo。
* https://developers.weixin.qq.com/minigame/dev/guide/open-ability/ohos.html
*/
export type MiniGameHostApi = {
getDeviceInfo?: () => Record<string, unknown>;
getWindowInfo?: () => Record<string, unknown>;
getAppBaseInfo?: () => Record<string, unknown>;
getSystemInfoSync?: () => Record<string, unknown>;
};
/**
* 合并新/旧宿主信息接口。appName 等字段可能只在 getSystemInfoSync / getAppBaseInfo。
* @param api 微信 / 抖音 jsbridge
*/
export function readMiniGameHostInfo(api: MiniGameHostApi | null | undefined): Record<string, unknown> | null {
if (!api) return null;
const merged: Record<string, unknown> = {};
try {
if (typeof api.getDeviceInfo === 'function') {
Object.assign(merged, api.getDeviceInfo() ?? {});
}
} catch { /* jsbridge 未就绪 */ }
try {
if (typeof api.getWindowInfo === 'function') {
const win = api.getWindowInfo() ?? {};
if (win.screenWidth != null) merged.screenWidth = win.screenWidth;
if (win.screenHeight != null) merged.screenHeight = win.screenHeight;
if (win.windowWidth != null) merged.windowWidth = win.windowWidth;
if (win.windowHeight != null) merged.windowHeight = win.windowHeight;
if (win.pixelRatio != null) {
merged.pixelRatio = win.pixelRatio;
merged.devicePixelRatio = win.pixelRatio;
}
if (win.statusBarHeight != null) merged.statusBarHeight = win.statusBarHeight;
if (win.safeArea != null) merged.safeArea = win.safeArea;
}
} catch { /* jsbridge 未就绪 */ }
try {
if (typeof api.getAppBaseInfo === 'function') {
const app = api.getAppBaseInfo() ?? {};
if (app.SDKVersion != null) merged.SDKVersion = app.SDKVersion;
if (app.language != null) merged.language = app.language;
if (app.version != null) merged.version = app.version;
if (app.theme != null) merged.theme = app.theme;
if (app.enableDebug != null) merged.enableDebug = app.enableDebug;
if (app.host != null) merged.host = app.host;
if (app.appName != null) merged.appName = app.appName;
}
} catch { /* jsbridge 未就绪 */ }
if (typeof api.getSystemInfoSync === 'function') {
try {
const sys = api.getSystemInfoSync() ?? {};
if (merged.platform == null && sys.platform != null) merged.platform = sys.platform;
if (merged.system == null && sys.system != null) merged.system = sys.system;
if (merged.model == null && sys.model != null) merged.model = sys.model;
if (merged.appName == null && sys.appName != null) merged.appName = sys.appName;
if (merged.brand == null && sys.brand != null) merged.brand = sys.brand;
} catch { /* 旧接口失败则保持已合并字段 */ }
}
if (!merged.platform && !merged.system && !merged.model && !merged.appName) {
return null;
}
return merged;
}
/**
* 微信鸿蒙:platform=ohos;开发者工具模拟鸿蒙 platform=devtools 且 system=HarmonyOS。
* @param info 宿主信息
*/
export function isHarmonyHost(info: { platform?: unknown; system?: unknown } | null): boolean {
if (!info) return false;
const platform = String(info.platform ?? '').toLowerCase();
const system = String(info.system ?? '').toLowerCase();
return platform === 'ohos'
|| platform === 'ohos_pc'
|| platform === 'openharmony'
|| system.includes('harmony')
|| system.includes('openharmony');
}
/** 小游戏运行时平台(与 window 全局对象对应) */
export type MiniGamePfId = 'ks' | 'tt' | 'qg' | 'qq' | 'bl' | 'my' | 'wx';
/**
* 运行时宿主探测。wx 必须最后,避免快手「兼容微信」时 window.wx 抢先。
* my 在 wx 之前:支付宝全局对象是 my。
*/
export class MiniGamePf {
/** 探测顺序:ks → tt → qg → qq → bl → my → wx */
private static readonly _order: MiniGamePfId[] = ['ks', 'tt', 'qg', 'qq', 'bl', 'my', 'wx'];
/** 当前平台 id;非小游戏返回 null */
static id(): MiniGamePfId | null {
const order = MiniGamePf._order;
for (let i = 0; i < order.length; i++) {
const k = order[i];
if ((window as Record<string, unknown>)[k]) return k;
}
return null;
}
/** 当前平台全局对象 */
static api(): Record<string, any> | null {
const id = MiniGamePf.id();
if (!id) return null;
return ((window as Record<string, unknown>)[id] as Record<string, any>) ?? null;
}
/** 是否快手(含微信兼容包) */
static isKs(): boolean {
return !!(window as Record<string, unknown>)['ks'];
}
/** 是否 B 站小游戏 */
static isBl(): boolean {
return MiniGamePf.id() === 'bl';
}
/** 是否支付宝小游戏(全局对象 my) */
static isMy(): boolean {
return MiniGamePf.id() === 'my';
}
/** 是否走 ZYSDK 上报(抖音 / 快手 / B 站 / 微信)。支付宝不进 ZYSDK */
static canReport(): boolean {
const id = MiniGamePf.id();
return id === 'tt' || id === 'ks' || id === 'bl' || id === 'wx';
}
}