Light12306/Web12306/js/platform/messageCoder.js

209 lines
4.6 KiB
JavaScript
Raw Normal View History

2015-07-01 16:18:25 +08:00
define(function (require, exports, module) {
2015-07-08 17:24:45 +08:00
var sessMgr = require("../account/sessionMgr.js");
2015-07-01 16:18:25 +08:00
var keystr = "iFishMessagePack";
2015-07-03 21:04:37 +08:00
var step = Math.pow(2, 32);
2015-07-01 16:18:25 +08:00
2015-07-03 21:04:37 +08:00
exports.encode = function (item) {
2015-07-08 17:24:45 +08:00
if (!item)
return [];
if (!item.fromUser)
item.fromUser = {
username: sessMgr.current.username,
realname: sessMgr.current.dispname
};
2015-07-03 21:04:37 +08:00
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);
};
2015-07-08 17:24:45 +08:00
var putString = function (str, unicode, writeLengthPrefix) {
2015-07-03 21:04:37 +08:00
str = str || "";
if (typeof writeLengthPrefix === 'undefined')
writeLengthPrefix = true;
2015-07-01 16:18:25 +08:00
2015-07-03 21:04:37 +08:00
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
2015-07-08 17:24:45 +08:00
putString(keystr, false, false);
2015-07-03 21:04:37 +08:00
//3.action
2015-07-08 17:24:45 +08:00
putInt64(item.id);
putString(item.action, false);
2015-07-03 21:04:37 +08:00
//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
2015-07-08 17:24:45 +08:00
putString(item.content, true);
2015-07-03 21:04:37 +08:00
//10.color
2015-07-08 17:24:45 +08:00
putString(item.color, false);
2015-07-03 21:04:37 +08:00
//11.images
putInt32(item.images ? item.images.length || 0 : 0);
if (item.images) {
item.images.forEach(function (image) {
2015-07-08 17:24:45 +08:00
putString(image, false);
2015-07-03 21:04:37 +08:00
});
}
//12.from user
2015-07-08 17:24:45 +08:00
putString(item.fromUser.username || "", false);
putString(item.fromUser.realname || "", true);
2015-07-03 21:04:37 +08:00
//13.images
putInt32(item.toUsers ? item.toUsers.length || 0 : 0);
if (item.toUsers) {
item.toUsers.forEach(function (user) {
2015-07-08 17:24:45 +08:00
putString(user.username, false);
putString(user.realname, true);
2015-07-03 21:04:37 +08:00
});
2015-07-01 16:18:25 +08:00
}
2015-07-03 21:04:37 +08:00
//encrypt
2015-07-08 17:24:45 +08:00
for (var j = 1; j < buffer.length; j++) {
key = buffer[j] ^= key;
}
2015-07-03 21:04:37 +08:00
return buffer;
2015-07-01 16:18:25 +08:00
};
2015-07-03 21:04:37 +08:00
exports.decode = function (data) {
2015-07-08 17:24:45 +08:00
var keyIndex = data[0];
2015-07-03 21:04:37 +08:00
var key = keystr.charCodeAt(keyIndex);
2015-07-01 16:18:25 +08:00
2015-07-03 21:04:37 +08:00
//decrypt
2015-07-08 17:24:45 +08:00
for (var i = 1; i < data.length; i++) {
var bit = data[i];
data[i] = bit ^ key;
key = bit;
}
2015-07-03 21:04:37 +08:00
var pos = 1;
//helper
2015-07-08 17:24:45 +08:00
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++];
2015-07-31 23:11:30 +08:00
return b1 + b2 * 256 + b3 * Math.pow(2, 16) + b4 * Math.pow(2, 24);
2015-07-08 17:24:45 +08:00
};
2015-07-03 21:04:37 +08:00
var readInt64 = function () {
2015-07-08 17:24:45 +08:00
var int1 = readInt32();
var int2 = readInt32();
2015-07-03 21:04:37 +08:00
return int2 * step + int1;
};
var readString = function (unicode, length) {
if (typeof (unicode) === 'undefined') {
2015-07-08 17:24:45 +08:00
unicode = false;
2015-07-03 21:04:37 +08:00
}
if (typeof (length) === 'undefined') {
2015-07-08 17:24:45 +08:00
length = readInt32();
2015-07-03 21:04:37 +08:00
}
var buffer = [];
2015-07-08 17:24:45 +08:00
var textLength = length / (unicode ? 2 : 1);
for (var j = 0; j < textLength; j++) {
2015-07-03 21:04:37 +08:00
if (unicode) {
2015-07-08 17:24:45 +08:00
buffer.push(String.fromCharCode(readInt16()));
2015-07-03 21:04:37 +08:00
} else {
2015-07-08 17:24:45 +08:00
buffer.push(String.fromCharCode(data[pos++]));
2015-07-03 21:04:37 +08:00
}
}
return buffer.join("");
};
2015-07-08 17:24:45 +08:00
var readMessageUser = function () {
return {
username: readString(false),
realname: readString(true)
};
};
2015-07-03 21:04:37 +08:00
//check package header
if (readString(false, keystr.length) !== keystr)
return null;
var item = {};
2015-07-08 17:24:45 +08:00
item.id = readInt64();
2015-07-03 21:04:37 +08:00
item.action = readString(false);
2015-07-08 17:24:45 +08:00
item.success = data[pos++] === 1;
2015-07-03 21:04:37 +08:00
item.time = new Date(readInt64());
2015-07-08 17:24:45 +08:00
item.systemMessage = data[pos++] === 1;
item.sysMsgType = readInt32();
item.userMsgType = readInt32();
item.content = readString(true);
item.color = readString(false);
var imgCount = readInt32();
2015-07-03 21:04:37 +08:00
if (imgCount > 0) {
item.images = [];
for (var j = 0; j < imgCount; j++) {
item.images.push(readString(false));
}
}
2015-07-08 17:24:45 +08:00
item.fromUser = readMessageUser();
var toUserCount = readInt32();
2015-07-03 21:04:37 +08:00
if (toUserCount > 0) {
item.toUsers = [];
for (var j = 0; j < toUserCount; j++) {
2015-07-08 17:24:45 +08:00
item.toUsers.push(readMessageUser());
2015-07-03 21:04:37 +08:00
}
}
return item;
};
2015-07-01 16:18:25 +08:00
});