define(function (require, exports, module) { var sessMgr = require("../account/sessionMgr.js"); var keystr = "iFishMessagePack"; var step = Math.pow(2, 32); exports.encode = function (item) { if (!item) return []; if (!item.fromUser) item.fromUser = { username: sessMgr.current.username, realname: sessMgr.current.dispname }; var buffer = []; var keyidx = Math.floor(Math.random() * keystr.length); var key = keystr.charCodeAt(keyidx); //helper var putInt16 = function (value) { value = value || 0; for (var i = 0; i < 2; i++) { buffer.push(value - (value >> 8 << 8)); value >>= 8; } }; var putInt32 = function (value) { value = value || 0; for (var i = 0; i < 4; i++) { buffer.push(value - (value >> 8 << 8)); value >>= 8; } }; var putInt64 = function (value) { value = value || 0; var int1 = value % step; var int2 = Math.floor((value - int1) / step); putInt32(int1); putInt32(int2); }; var putBool = function (value) { value = value || false; buffer.push(value ? 1 : 0); }; var putString = function (str, unicode, writeLengthPrefix) { str = str || ""; if (typeof writeLengthPrefix === 'undefined') writeLengthPrefix = true; if (writeLengthPrefix) { putInt32((unicode ? 2 : 1) * str.length); } for (var i = 0; i < str.length; i++) { var code = str.charCodeAt(i); if (unicode) putInt16(code); else buffer.push(code); } }; //1. buffer.push(keyidx); //2. keystr putString(keystr, false, false); //3.action putInt64(item.id); putString(item.action, false); //4.success putBool(item.success); //5.time putInt64(item.time.getTime()); //6.system message putBool(item.systemMessage); //7.8. putInt32(item.sysMsgType); putInt32(item.userMsgType); //9.content putString(item.content, true); //10.color putString(item.color, false); //11.images putInt32(item.images ? item.images.length || 0 : 0); if (item.images) { item.images.forEach(function (image) { putString(image, false); }); } //12.from user putString(item.fromUser.username || "", false); putString(item.fromUser.realname || "", true); //13.images putInt32(item.toUsers ? item.toUsers.length || 0 : 0); if (item.toUsers) { item.toUsers.forEach(function (user) { putString(user.username, false); putString(user.realname, true); }); } //encrypt for (var j = 1; j < buffer.length; j++) { key = buffer[j] ^= key; } return buffer; }; exports.decode = function (data) { var keyIndex = data[0]; var key = keystr.charCodeAt(keyIndex); //decrypt for (var i = 1; i < data.length; i++) { var bit = data[i]; data[i] = bit ^ key; key = bit; } var pos = 1; //helper var readInt16 = function () { var b1 = data[pos++]; var b2 = data[pos++]; return b1 | b2 << 8; }; var readInt32 = function () { var b1 = data[pos++]; var b2 = data[pos++]; var b3 = data[pos++]; var b4 = data[pos++]; return b1 | b2 << 8 | b3 << 16 | b4 << 24; }; var readInt64 = function () { var int1 = readInt32(); var int2 = readInt32(); return int2 * step + int1; }; var readString = function (unicode, length) { if (typeof (unicode) === 'undefined') { unicode = false; } if (typeof (length) === 'undefined') { length = readInt32(); } var buffer = []; var textLength = length / (unicode ? 2 : 1); for (var j = 0; j < textLength; j++) { if (unicode) { buffer.push(String.fromCharCode(readInt16())); } else { buffer.push(String.fromCharCode(data[pos++])); } } return buffer.join(""); }; var readMessageUser = function () { return { username: readString(false), realname: readString(true) }; }; //check package header if (readString(false, keystr.length) !== keystr) return null; var item = {}; item.id = readInt64(); item.action = readString(false); item.success = data[pos++] === 1; item.time = new Date(readInt64()); item.systemMessage = data[pos++] === 1; item.sysMsgType = readInt32(); item.userMsgType = readInt32(); item.content = readString(true); item.color = readString(false); var imgCount = readInt32(); if (imgCount > 0) { item.images = []; for (var j = 0; j < imgCount; j++) { item.images.push(readString(false)); } } item.fromUser = readMessageUser(); var toUserCount = readInt32(); if (toUserCount > 0) { item.toUsers = []; for (var j = 0; j < toUserCount; j++) { item.toUsers.push(readMessageUser()); } } return item; }; });