Light12306/Web12306/js/platform/messageCoder.js
2015-07-03 21:04:37 +08:00

190 lines
4.2 KiB
JavaScript

define(function (require, exports, module) {
var keystr = "iFishMessagePack";
var step = Math.pow(2, 32);
exports.encode = function (item) {
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, writeFlag, writeLengthPrefix) {
str = str || "";
if (typeof writeFlag === 'undefined')
writeFlag = true;
if (typeof writeLengthPrefix === 'undefined')
writeLengthPrefix = true;
unicode &= writeFlag;
if (writeFlag) {
buffer.push(unicode ? 1 : 0);
}
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, false);
//3.action
putString(item.action, false, 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);
//10.color
putString(item.color, false, false);
//11.images
putInt32(item.images ? item.images.length || 0 : 0);
if (item.images) {
item.images.forEach(function (image) {
putString(image, false, false);
});
}
//12.from user
putString(item.fromUser, false, false);
//13.images
putInt32(item.toUsers ? item.toUsers.length || 0 : 0);
if (item.toUsers) {
item.toUsers.forEach(function (user) {
putString(user, false, false);
});
}
//encrypt
//for (var j = 1; j < buffer.length; j++) {
// key = buffer[j] ^= key;
//}
console.log(buffer);
return buffer;
};
exports.decode = function (data) {
var dv = new DataView(data, 0);
var keyIndex = dv.getUint8(0);
var key = keystr.charCodeAt(keyIndex);
//decrypt
//for (var i = 1; i < dv.byteLength; i++) {
// var bit = dv.getUint8(i);
// dv.setUint8(i, bit ^ key);
// key = bit;
//}
var pos = 1;
//helper
var readInt64 = function () {
var int1 = dv.getInt32(pos, true);
var int2 = dv.getInt32(pos + 4, true);
pos += 8;
return int2 * step + int1;
};
var readString = function (unicode, length) {
if (typeof (unicode) === 'undefined') {
unicode = dv.getUint8(pos++) === 1;
}
if (typeof (length) === 'undefined') {
length = dv.getInt32(pos, true);
pos += 4;
}
var buffer = [];
for (var j = 0; j < length; j++) {
if (unicode) {
buffer.push(String.fromCharCode(dv.getUint16(pos, true)));
pos += 2;
} else {
buffer.push(String.fromCharCode(dv.getUint8(pos++, true)));
}
}
return buffer.join("");
};
//check package header
if (readString(false, keystr.length) !== keystr)
return null;
var item = {};
item.action = readString(false);
item.success = dv.getUint8(pos++) === 1;
item.time = new Date(readInt64());
item.systemMessage = dv.getUint8(pos++) === 1;
item.sysMsgType = dv.getInt32(pos, true);
pos += 4;
item.userMsgType = dv.getInt32(pos, true);
pos += 4;
item.content = readString();
item.Color = readString(false);
var imgCount = dv.getInt32(pos, true);
pos += 4;
if (imgCount > 0) {
item.images = [];
for (var j = 0; j < imgCount; j++) {
item.images.push(readString(false));
}
}
item.fromUser = readString(false);
var toUserCount = dv.getInt32(pos, true);
pos += 4;
if (toUserCount > 0) {
item.toUsers = [];
for (var j = 0; j < toUserCount; j++) {
item.images.push(readString(false));
}
}
return item;
};
});