mergeInto(LibraryManager.library, { $AIGameSockets: { nextId: 1, sockets: {} }, AIGame_WsCreate__deps: ['$AIGameSockets'], AIGame_WsCreate: function (urlPointer) { var id = AIGameSockets.nextId++; var entry = { events: [], socket: null, disposed: false, terminal: false, wechat: false }; AIGameSockets.sockets[id] = entry; var finish = function (kind, reason) { if (entry.disposed || entry.terminal) return; entry.terminal = true; entry.events.push(kind + (reason || 'closed')); }; var closeSocket = function () { if (!entry.socket) return; try { if (entry.wechat) entry.socket.close({ code: 1000, reason: 'client close' }); else entry.socket.close(1000, 'client close'); } catch (ignored) {} }; var opened = function () { // WeChat may finish opening after a close requested while connecting. if (entry.disposed || entry.terminal) { closeSocket(); return; } entry.events.push('O'); }; var message = function (event) { if (!entry.disposed && !entry.terminal && typeof event.data === 'string') entry.events.push('M' + event.data); }; try { var url = UTF8ToString(urlPointer); var api = typeof wx !== 'undefined' ? wx : (typeof GameGlobal !== 'undefined' ? GameGlobal.wx : null); if (api && api.connectSocket) { entry.wechat = true; var task = api.connectSocket({ url: url, fail: function (error) { finish('E', error.errMsg || 'connectSocket failed'); } }); entry.socket = task; task.onOpen(opened); task.onMessage(message); task.onError(function (error) { finish('E', error.errMsg || 'socket error'); }); task.onClose(function (event) { finish('C', String(event.code || '') + ' ' + (event.reason || 'closed')); }); } else { var socket = new WebSocket(url); entry.socket = socket; socket.onopen = opened; socket.onmessage = message; socket.onerror = function () { finish('E', 'WebSocket connection failed'); }; socket.onclose = function (event) { finish('C', String(event.code) + ' ' + (event.reason || 'closed')); }; } } catch (error) { finish('E', error.message || String(error)); } return id; }, AIGame_WsPoll__deps: ['$AIGameSockets'], AIGame_WsPoll: function (id) { var entry = AIGameSockets.sockets[id]; if (!entry || !entry.events.length) return 0; var text = entry.events.shift(); var size = lengthBytesUTF8(text) + 1; var pointer = _malloc(size); stringToUTF8(text, pointer, size); // IL2CPP frees the native buffer for a marshalled string return value. return pointer; }, AIGame_WsSend__deps: ['$AIGameSockets'], AIGame_WsSend: function (id, textPointer) { var entry = AIGameSockets.sockets[id]; if (!entry || entry.disposed || entry.terminal) return; var fail = function (error) { if (entry.disposed || entry.terminal) return; entry.terminal = true; entry.events.push('E' + (error.errMsg || error.message || 'send failed')); }; try { var text = UTF8ToString(textPointer); if (entry.wechat) entry.socket.send({ data: text, fail: fail }); else entry.socket.send(text); } catch (error) { fail(error); } }, AIGame_WsDispose__deps: ['$AIGameSockets'], AIGame_WsDispose: function (id) { var entry = AIGameSockets.sockets[id]; if (!entry) return; entry.disposed = true; entry.events.length = 0; delete AIGameSockets.sockets[id]; try { if (entry.socket) { if (entry.wechat) entry.socket.close({ code: 1000, reason: 'client close' }); else entry.socket.close(1000, 'client close'); } } catch (ignored) {} } });