hyapp-h5/game-bridge/voice-room-game-bridge.v1.js
2026-06-10 18:58:46 +08:00

641 lines
21 KiB
JavaScript

(function () {
var remoteBridgeVersion = '20260610.2';
function safeCall(fn, args) {
try {
if (typeof fn === 'function') {
return fn.apply(window, args || []);
}
} catch (error) {
post('debugLog', {
message: String((error && error.message) || error),
});
}
return null;
}
function readObject(value) {
return value && typeof value === 'object' && !Array.isArray(value)
? value
: {};
}
function readString(value) {
if (value === null || value === undefined) {
return '';
}
return String(value).trim();
}
function readPositiveInteger(value) {
if (typeof value === 'number' && isFinite(value)) {
return value > 0 ? Math.floor(value) : 0;
}
var text = readString(value);
if (!/^[0-9]+$/.test(text)) {
return 0;
}
var parsed = Number(text);
return isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : 0;
}
function normalizeAdapterConfig(config, adapter) {
if (adapter !== 'vivagames_v1') {
return config;
}
var appId = readPositiveInteger(config.app_id);
if (appId <= 0) {
appId = readPositiveInteger(config.appId);
}
if (appId > 0) {
config.app_id = appId;
config.appId = appId;
}
return config;
}
function post(action, body) {
var message = JSON.stringify({ action: action, payload: body || {} });
if (postToChannel('GameBridgeChannel', message)) {
return;
}
if (postToChannel('BaishunBridgeChannel', message)) {
return;
}
if (postToChannel('LeaderBridgeChannel', message)) {
return;
}
postToChannel('NativeBridge', message);
}
function postToChannel(name, message) {
if (window[name] && window[name].postMessage) {
window[name].postMessage(message);
return true;
}
if (
window.webkit &&
window.webkit.messageHandlers &&
window.webkit.messageHandlers[name] &&
window.webkit.messageHandlers[name].postMessage
) {
window.webkit.messageHandlers[name].postMessage(message);
return true;
}
return false;
}
function launchPayload() {
return readObject(window.hyappGameLaunchPayload);
}
function launchConfig() {
var payload = launchPayload();
return readObject(window.hyappGameLaunchConfig || payload.launchConfig);
}
function launchEntry() {
var payload = launchPayload();
return readObject(window.hyappGameEntry || payload.entry);
}
function detectAdapter(config, payload) {
var values = [
config.adapterType,
config.adapter_type,
config.platformCode,
config.platform_code,
config.vendorType,
config.vendor_type,
payload.vendorType,
payload.vendor_type,
payload.platformCode,
payload.platform_code,
payload.gameId,
payload.game_id,
]
.map(readString)
.join('|')
.toLowerCase();
if (values.indexOf('vivagames') >= 0) {
return 'vivagames_v1';
}
if (values.indexOf('baishun') >= 0) {
return 'baishun_v1';
}
if (values.indexOf('leadercc') >= 0) {
return 'leadercc_v1';
}
if (values.indexOf('zeeone') >= 0) {
return 'zeeone_v1';
}
if (values.indexOf('reyou') >= 0 || values.indexOf('hotgame') >= 0) {
return 'reyou_v1';
}
if (values.indexOf('yomi') >= 0) {
return 'yomi_v4';
}
return 'generic';
}
function stringifyParams(body) {
try {
return JSON.stringify(body || {});
} catch (_) {
return '{}';
}
}
function notifyVivaGames(method, body) {
var params = body || {};
safeCall(window.OnCallGame, [method, params]);
try {
window.postMessage(
{ method: method, params: stringifyParams(params) },
'*'
);
} catch (_) {}
try {
if (
window.parent &&
window.parent !== window &&
window.parent.postMessage
) {
window.parent.postMessage(
{ method: method, params: stringifyParams(params) },
'*'
);
}
} catch (_) {}
}
function installAlias(name, action) {
var fn = function (body) {
return callNativeBridge(action || name, body);
};
fn.postMessage = function (body) {
callNativeBridge(action || name, body);
};
window[name] = fn;
window.webkit = window.webkit || {};
window.webkit.messageHandlers = window.webkit.messageHandlers || {};
window.webkit.messageHandlers[name] = { postMessage: fn.postMessage };
}
function parseBridgePayload(value) {
if (typeof value === 'string') {
var text = value.trim();
if (!text) {
return {};
}
try {
var decoded = JSON.parse(text);
return decoded && typeof decoded === 'object'
? decoded
: { value: decoded };
} catch (_) {
return { raw: text };
}
}
if (value && typeof value === 'object') {
return value;
}
if (value === null || value === undefined) {
return {};
}
return { value: value };
}
function actionFromPayload(payload, fallbackAction) {
return (
readString(
payload.type ||
payload.action ||
payload.method ||
payload.name ||
payload.cmd ||
payload.event
) || fallbackAction
);
}
function invokeNamedCallback(callbackName, payload) {
var text = readString(callbackName);
if (
!/^[A-Za-z_$][0-9A-Za-z_$]*(\.[A-Za-z_$][0-9A-Za-z_$]*)*$/.test(
text
)
) {
return false;
}
var parts = text.split('.');
var target = window;
for (var i = 0; i < parts.length; i += 1) {
target = target[parts[i]];
if (target === null || target === undefined) {
return false;
}
}
if (typeof target !== 'function') {
return false;
}
safeCall(target, [payload || {}]);
return true;
}
function yomiActionResult(action, payload) {
var normalized = readString(action).toLowerCase();
if (normalized === 'insufficient') {
return {
action: 'insufficient',
result: 'success',
balance: payload && payload.balance,
};
}
if (normalized === 'hidesplash') {
return { action: 'hideSplash', result: 'success' };
}
if (normalized === 'closegame') {
return { action: 'closeGame', result: 'success' };
}
return { action: action, result: 'success' };
}
function postYomiAction(action, input) {
var payload = parseBridgePayload(input);
var normalized = actionFromPayload(payload, action);
if (!normalized) {
normalized = 'NativeBridge';
}
payload.type = payload.type || normalized;
payload.action = payload.action || normalized;
post(normalized, payload);
invokeNamedCallback(
payload.callback || payload.callbackName || payload.cb,
yomiActionResult(normalized, payload)
);
return yomiActionResult(normalized, payload);
}
function extractYomiBalance(payload) {
var body = parseBridgePayload(payload);
if (body.balance !== null && body.balance !== undefined) {
return body.balance;
}
if (body.amount !== null && body.amount !== undefined) {
return body.amount;
}
if (body.coin !== null && body.coin !== undefined) {
return body.coin;
}
if (body.balanceLabel !== null && body.balanceLabel !== undefined) {
return body.balanceLabel;
}
return undefined;
}
function notifyYomiGame(action, body) {
var normalized = readString(action);
if (normalized === 'onBalanceUpdate') {
var balance = extractYomiBalance(body);
if (balance === undefined) {
safeCall(window.onBalanceUpdate, []);
} else {
safeCall(window.onBalanceUpdate, [balance]);
}
}
if (normalized === 'setSound') {
var payload = parseBridgePayload(body);
var soundEnabled =
payload.bool !== undefined
? payload.bool
: payload.enabled !== undefined
? payload.enabled
: payload.value;
safeCall(window.setSound, [!!soundEnabled]);
}
if (normalized === 'passiveCloseGame') {
safeCall(window.passiveCloseGame, []);
}
try {
window.dispatchEvent(
new CustomEvent('yomiBridgeAction', {
detail: { action: normalized, payload: body || {} },
})
);
} catch (_) {}
}
function installYomiPostMessageListener() {
if (window.__hyappYomiPostMessageListenerInstalled) {
return;
}
window.__hyappYomiPostMessageListenerInstalled = true;
window.addEventListener('message', function (event) {
var data = parseBridgePayload(event && event.data);
if (readString(data.from).toLowerCase() !== 'yomi') {
return;
}
var action = actionFromPayload(data, '');
if (!action) {
return;
}
postYomiAction(action, data);
});
}
function installYomiBridgeAliases(nativeBridge) {
var previousYomi = window.yomi || {};
var yomiBridge = {};
var previousUpdateCoin =
typeof nativeBridge.updateCoin === 'function'
? nativeBridge.updateCoin.bind(nativeBridge)
: null;
yomiBridge.postMessage = function (message) {
var payload = parseBridgePayload(message);
return postYomiAction(
actionFromPayload(payload, 'NativeBridge'),
payload
);
};
yomiBridge.closeGame = function (body) {
return postYomiAction('closeGame', body || {});
};
yomiBridge.hideSplash = function (body) {
return postYomiAction('hideSplash', body || {});
};
yomiBridge.insufficient = function (body) {
return postYomiAction('insufficient', body || {});
};
yomiBridge.onBalanceUpdate = function (body) {
notifyYomiGame('onBalanceUpdate', body || {});
};
yomiBridge.setSound = function (body) {
notifyYomiGame('setSound', body || {});
};
yomiBridge.passiveCloseGame = function () {
notifyYomiGame('passiveCloseGame', {});
};
Object.keys(previousYomi).forEach(function (key) {
if (yomiBridge[key] === undefined) {
yomiBridge[key] = previousYomi[key];
}
});
window.yomi = yomiBridge;
window.webkit = window.webkit || {};
window.webkit.messageHandlers = window.webkit.messageHandlers || {};
window.webkit.messageHandlers.yomi = {
postMessage: yomiBridge.postMessage,
};
nativeBridge.insufficient = function (body) {
postYomiAction('insufficient', body || {});
};
nativeBridge.hideSplash = function (body) {
postYomiAction('hideSplash', body || {});
};
nativeBridge.onBalanceUpdate = function (body) {
notifyYomiGame('onBalanceUpdate', body || {});
};
nativeBridge.setSound = function (body) {
notifyYomiGame('setSound', body || {});
};
nativeBridge.passiveCloseGame = function () {
notifyYomiGame('passiveCloseGame', {});
};
nativeBridge.updateCoin = function (body) {
if (previousUpdateCoin) {
previousUpdateCoin(body || {});
}
notifyYomiGame('onBalanceUpdate', body || {});
};
installYomiPostMessageListener();
}
function notifyReyouRechargeSuccess(body) {
var payload = body || {};
var notified = false;
[window.rechargeSuccess, window.onRechargeSuccess].forEach(
function (fn) {
if (typeof fn === 'function') {
safeCall(fn, [payload]);
notified = true;
}
}
);
try {
window.dispatchEvent(
new CustomEvent('rechargeSuccess', { detail: payload })
);
} catch (_) {}
return notified;
}
function installReyouBridgeAliases(nativeBridge) {
var jsBridge = window.JsBridge || {};
jsBridge.recharge = function (body) {
return callNativeBridge('gameRecharge', body || {});
};
jsBridge.quit = function (body) {
return callNativeBridge('closeGame', body || {});
};
window.JsBridge = jsBridge;
installAlias('recharge', 'gameRecharge');
installAlias('quit', 'closeGame');
nativeBridge.recharge = function (body) {
callNativeBridge('gameRecharge', body || {});
};
nativeBridge.quit = function (body) {
callNativeBridge('closeGame', body || {});
};
nativeBridge.rechargeSuccess = function (body) {
notifyReyouRechargeSuccess(body || {});
};
nativeBridge.updateCoin = function (body) {
notifyReyouRechargeSuccess(body || {});
callNativeBridge('refreshBalance', body || {});
};
}
function callNativeBridge(action, body) {
var config = launchConfig();
var payload = launchPayload();
var adapter = detectAdapter(config, payload);
config = normalizeAdapterConfig(config, adapter);
var normalized = readString(action);
if (normalized === 'getConfig') {
post('getConfig', body || {});
if (adapter === 'vivagames_v1') {
notifyVivaGames('getConfig', config);
}
return config;
}
if (normalized === 'getLaunchPayload') {
post('getLaunchPayload', body || {});
return payload;
}
post(normalized || 'NativeBridge', body || {});
if (adapter === 'vivagames_v1') {
notifyVivaGames(normalized || 'NativeBridge', body || {});
}
return null;
}
function installNativeBridge() {
var config = launchConfig();
var payload = launchPayload();
var entry = launchEntry();
var adapter = detectAdapter(config, payload);
config = normalizeAdapterConfig(config, adapter);
var nativeBridge = window.NativeBridge || {};
var oldPostMessage =
typeof nativeBridge.postMessage === 'function'
? nativeBridge.postMessage.bind(nativeBridge)
: null;
window.__hyappRemoteGameBridge = {
adapter: adapter,
version: remoteBridgeVersion,
installedAt: Date.now(),
};
window.hyappGameLaunchPayload = payload;
window.hyappGameLaunchConfig = config;
window.hyappGameEntry = entry;
window.__baishunLastConfig = config;
window.baishunBridgeConfig = config;
window.leaderLaunchPayload = payload;
window.leaderLaunchConfig = config;
window.leaderLaunchEntry = entry;
nativeBridge.config = config;
nativeBridge.launchConfig = config;
nativeBridge.entry = entry;
nativeBridge.launchPayload = payload;
nativeBridge.getConfigSync = function () {
return launchConfig();
};
nativeBridge.getLaunchPayloadSync = function () {
return launchPayload();
};
nativeBridge.postMessage = function (body) {
if (oldPostMessage) {
oldPostMessage(
typeof body === 'string' ? body : stringifyParams(body)
);
return;
}
callNativeBridge('NativeBridge', body);
};
nativeBridge.getConfig = function (bodyOrCallback) {
var currentConfig = launchConfig();
if (typeof bodyOrCallback === 'function') {
safeCall(bodyOrCallback, [currentConfig, launchPayload()]);
}
callNativeBridge('getConfig', bodyOrCallback || {});
return currentConfig;
};
nativeBridge.getLaunchPayload = function (bodyOrCallback) {
var currentPayload = launchPayload();
if (typeof bodyOrCallback === 'function') {
safeCall(bodyOrCallback, [currentPayload]);
}
callNativeBridge('getLaunchPayload', bodyOrCallback || {});
return currentPayload;
};
nativeBridge.destroy = function (body) {
callNativeBridge('destroy', body || {});
};
nativeBridge.closeGame = function (body) {
callNativeBridge('closeGame', body || {});
};
nativeBridge.gameStart = function (body) {
callNativeBridge('gameStart', body || {});
};
nativeBridge.gameLoading = function (body) {
callNativeBridge('gameLoading', body || {});
};
nativeBridge.gameLoaded = function (body) {
callNativeBridge('gameLoaded', body || {});
};
nativeBridge.loadComplete = function (body) {
callNativeBridge('loadComplete', body || {});
};
nativeBridge.gameRecharge = function (body) {
callNativeBridge('gameRecharge', body || {});
};
nativeBridge.pay = function (body) {
callNativeBridge('pay', body || {});
};
nativeBridge.copyText = function (body) {
callNativeBridge('copyText', body || {});
};
nativeBridge.refreshBalance = function (body) {
callNativeBridge('refreshBalance', body || {});
};
nativeBridge.refreshBlance = function (body) {
callNativeBridge('refreshBalance', body || {});
};
nativeBridge.debugLog = function (body) {
callNativeBridge('debugLog', body || {});
};
installReyouBridgeAliases(nativeBridge);
installYomiBridgeAliases(nativeBridge);
window.NativeBridge = nativeBridge;
[
['getConfig', 'getConfig'],
['destroy', 'destroy'],
['closeGame', 'closeGame'],
['hideSplash', 'hideSplash'],
['insufficient', 'insufficient'],
['gameStart', 'gameStart'],
['gameLoading', 'gameLoading'],
['gameLoaded', 'gameLoaded'],
['loadComplete', 'loadComplete'],
['gameRecharge', 'gameRecharge'],
['pay', 'pay'],
['copyText', 'copyText'],
['refreshBalance', 'refreshBalance'],
['refreshBlance', 'refreshBalance'],
['debugLog', 'debugLog'],
].forEach(function (item) {
installAlias(item[0], item[1]);
});
if (adapter === 'vivagames_v1') {
safeCall(window.OnCallGame, ['getConfig', config]);
}
signalReady(config, payload);
}
function signalReady(config, payload) {
[
['hyappGameBridgeReady', payload],
['hyappRemoteGameBridgeReady', window.__hyappRemoteGameBridge],
['baishunBridgeReady', config],
['leaderLaunchConfig', payload],
['launchConfig', config],
].forEach(function (item) {
try {
window.dispatchEvent(
new CustomEvent(item[0], { detail: item[1] })
);
if (document && document.dispatchEvent) {
document.dispatchEvent(
new CustomEvent(item[0], { detail: item[1] })
);
}
} catch (_) {}
});
}
window.HYAppGameBridge = window.HYAppGameBridge || {};
window.HYAppGameBridge.install = installNativeBridge;
window.HYAppGameBridge.version = remoteBridgeVersion;
installNativeBridge();
})();