209 lines
4.6 KiB
JavaScript
209 lines
4.6 KiB
JavaScript
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 * 256 + b3 * Math.pow(2, 16) + b4 * Math.pow(2, 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;
|
|
};
|
|
});
|