1415 lines
38 KiB
JavaScript
1415 lines
38 KiB
JavaScript
var MANIFEST = chrome.runtime.getManifest();
|
||
//var INFOBAR = chrome.infobars || (chrome.experimental && chrome.experimental.infobars);
|
||
var isDebug = (compressFunc + '').indexOf("false") !== -1;
|
||
var bv = window.external.LiebaoGetVersion && window.external.LiebaoGetVersion() || /Chrome\/([\d\.]+)/i.exec(navigator.userAgent)[1];
|
||
var entry12306 = false;
|
||
|
||
var log = (function () {
|
||
var fun = function () {
|
||
|
||
this.print = function () {
|
||
/// <summary>向控制台打印消息</summary>
|
||
if (!isDebug) return;
|
||
|
||
console.log.apply(console, $.makeArray(arguments));
|
||
};
|
||
return this;
|
||
};
|
||
|
||
return new fun();
|
||
})();
|
||
|
||
function compressFunc() {
|
||
return false;
|
||
}
|
||
|
||
|
||
var notification = (function () {
|
||
var notify = function () {
|
||
var __ = this;
|
||
var notifyMap = {};
|
||
|
||
this.mapParam = function (opts) {
|
||
return {
|
||
type: opts.type || "basic",
|
||
title: opts.title || "提示",
|
||
message: opts.message || "",
|
||
iconUrl: opts.iconUrl || "/icons/icon_n.png",
|
||
//contextMessage: opts.contextMessage || "",
|
||
priority: opts.priority || 0,
|
||
eventTime: opts.eventTime || null,
|
||
buttons: _.map(opts.buttons, function (e) {
|
||
return { title: e.title, iconUrl: e.iconUrl || "/icons/icon_16.png" };
|
||
}) || null,
|
||
imageUrl: opts.imageUrl || null,
|
||
items: _.map(opts.items, function (e) {
|
||
return { title: e.title, message: e.message };
|
||
}) || null//,
|
||
//progress: opts.progress || null,
|
||
//isClickable: opts.isClickable || true
|
||
};
|
||
};
|
||
|
||
__.create = function (opts) {
|
||
var opt = __.mapParam(opts);
|
||
var id = opts.id || "";
|
||
chrome.notifications.create(id, opt, function (_id) {
|
||
notifyMap[_id] = opts;
|
||
opts.id = _id;
|
||
});
|
||
opts.update = function () {
|
||
__.update(opts);
|
||
};
|
||
opts.clear = function () {
|
||
__.clear(opts.id);
|
||
};
|
||
};
|
||
__.update = function (opts) {
|
||
var opt = __.mapParam(opts);
|
||
chrome.notifications.update(opts.id, opt, function () {
|
||
opts.onUpdate && opts.onUpdate.apply(opts, $.makeArray(arguments));
|
||
});
|
||
};
|
||
__.clear = function (id) {
|
||
chrome.notifications.clear(id, function () {
|
||
opts.onClear && opts.onClear.apply(opts, $.makeArray(arguments));
|
||
});
|
||
};
|
||
|
||
__.getAll = function (callback) {
|
||
chrome.notifications.getAll(callback);
|
||
};
|
||
|
||
__.getPermissionLevel = function (callback) {
|
||
chrome.notifications.getPermissionLevel(callback);
|
||
};
|
||
|
||
chrome.notifications.onClicked.addListener(function (id) {
|
||
var opts = notifyMap[id];
|
||
if (opts === undefined || opts === null) return;
|
||
|
||
if ($.isFunction(opts.onClick)) {
|
||
opts.onClick.apply(this);
|
||
}
|
||
});
|
||
chrome.notifications.onClosed.addListener(function (id, byUser) {
|
||
var opts = notifyMap[id];
|
||
if (opts === undefined || opts === null) return;
|
||
|
||
if ($.isFunction(opts.onClose)) {
|
||
opts.onClose.apply(this, [byUser]);
|
||
}
|
||
});
|
||
chrome.notifications.onButtonClicked.addListener(function (id, index) {
|
||
var opts = notifyMap[id];
|
||
if (opts === undefined || opts === null) return;
|
||
|
||
var button = opts.buttons && opts.buttons[index];
|
||
if (!button || !$.isFunction(button.onClick)) return;
|
||
|
||
button.onClick.apply(opts);
|
||
});
|
||
|
||
chrome.runtime.onMessage.addListener(function (m, sender) {
|
||
if (m.action === "showNotification")
|
||
__.create(
|
||
{ message: m.detail.message, title: m.detail.title, iconUrl: m.detail.iconUrl }
|
||
);
|
||
else if (m.action === "notify") __.create(m.detail);
|
||
else if (m.action === "attention" && sender.tab) {
|
||
chrome.tabs.update((m.detail && m.detail.tabid) || sender.tab.id, { active: true, highlighted: true });
|
||
chrome.windows.update((m.detail && m.detail.windowid), { drawAttention: true, focused: true, state: "maximized" });
|
||
}
|
||
});
|
||
chrome.runtime.onMessage.addListener(function (m, sender) {
|
||
if (!m || !m.action)
|
||
return;
|
||
|
||
if (m.action === "attention" && sender.tab) {
|
||
chrome.tabs.update((m.detail && m.detail.tabid) || sender.tab.id, { active: true, highlighted: true });
|
||
chrome.windows.update((m.detail && m.detail.windowid), { drawAttention: true, focused: true, state: "maximized" });
|
||
}
|
||
});
|
||
};
|
||
|
||
return new notify();
|
||
})();
|
||
|
||
//#region 系统配置处理
|
||
|
||
var CFG_MANGER = (function () {
|
||
function manager() {
|
||
var __ = this;
|
||
var loaded = false;
|
||
var lastUpdate = null;
|
||
var sleepTime = 1000 * 1200;
|
||
var timerId = null;
|
||
|
||
this.baseConfig = {
|
||
appendCacheTagHeader: true,
|
||
showRealSeatCount: true,
|
||
autoSubmitAfterVerifyCode: true,
|
||
autoLoginAfterVerifyCode: true,
|
||
rememberLoginUser: true,
|
||
rememberLoginPwd: true,
|
||
enableSoundPrompt: true,
|
||
enablePopupPrompt: true,
|
||
musicUrl: "http://static.liebao.cn/resources/audio/music2.ogg",
|
||
submitOrderDelay: 5,
|
||
refreshDelay: 5,
|
||
autoWaitToSell: true,
|
||
keepOnline: true,
|
||
blockDynamicJs: false,
|
||
enableRealTimeTicketQuery: true,
|
||
showTicketPrice: true,
|
||
otnAutoConfirmOrderDelay: 0,
|
||
dynamicAutoConfirmOrderDelay: 1000,
|
||
dynamicAutoSubmitOrderDelay: 5000,
|
||
otnAutoSubmitOrderDelay: 0,
|
||
enableServerAutoChange: true,
|
||
enableAutoCaptcha: true && typeof window.external.LieBaoSign === 'function',
|
||
autoCaptchaFailedLimit: 5,
|
||
captchaServerUrl: "http://api.12306.liebao.cn/code.php",
|
||
appendPriceUnit: true,
|
||
blockVcVerify: false,
|
||
blockQueueCount: false,
|
||
chatServerApi: "http://srv.12306.liebao.cn/room/list"
|
||
};
|
||
//if (isDebug)
|
||
// this.baseConfig.chatServerApi = "http://chatdev.fishlee.net/room/list";
|
||
this.sysConfig = {};
|
||
this.userConfig = { enableAutoCaptcha: false };
|
||
if (localStorage["sysConfig"])
|
||
this.sysConfig = $.extend(this.sysConfig, JSON.parse(localStorage["sysConfig"]));
|
||
if (localStorage["userConfig"])
|
||
this.userConfig = JSON.parse(localStorage["userConfig"]);
|
||
|
||
this.refresh = function () {
|
||
__.config = $.extend({}, __.baseConfig, __.userConfig, __.sysConfig);
|
||
};
|
||
this.refresh();
|
||
|
||
this.isEnabled = function (tag) {
|
||
|
||
};
|
||
|
||
var msgHandler = function (m, s, r) {
|
||
if (m && m.action === 'enter12306') {
|
||
sleepTime = 20 * 60 * 1000;
|
||
//if (lastUpdate === null || (new Date() - lastUpdate) >= 20 * 60 * 1000)
|
||
// __.refreshConfig();
|
||
}
|
||
if (m && m.action === 'setUserConfig') {
|
||
__.userConfig = $.extend({}, __.userConfig, m.detail);
|
||
__.config = $.extend({}, __.baseConfig, __.userConfig, __.sysConfig);
|
||
localStorage["userConfig"] = JSON.stringify(__.userConfig);
|
||
chrome.runtime.sendMessage({ action: "sysConfigUpdate", detail: __.config });
|
||
}
|
||
};
|
||
chrome.runtime.onMessage.addListener(msgHandler);
|
||
chrome.runtime.onMessageExternal.addListener(msgHandler);
|
||
|
||
//this.refreshConfig();
|
||
loaded = true;
|
||
|
||
return this;
|
||
};
|
||
|
||
var mm = new manager();
|
||
var mmCallback = function (m, s, r) {
|
||
if (m.action === "getSysConfig") {
|
||
r({ action: "responseSysConfig", detail: mm.config });
|
||
}
|
||
if (m.action === "getBaseSysConfig") {
|
||
r({ action: "responseBaseSysConfig", detail: $.extend(mm.baseConfig, mm.sysConfig) });
|
||
}
|
||
};
|
||
chrome.runtime.onMessage.addListener(mmCallback);
|
||
chrome.runtime.onMessageExternal.addListener(mmCallback);
|
||
|
||
return mm;
|
||
})();
|
||
|
||
|
||
|
||
//#endregion
|
||
|
||
//#region 检测更新和更新通知
|
||
|
||
//TODO 检测更新
|
||
|
||
(function showNotificationIfUpdated() {
|
||
if (window.localStorage["cv"] != MANIFEST.version) {
|
||
window.localStorage["cv"] = MANIFEST.version;
|
||
|
||
notification.create({
|
||
title: "更新成功",
|
||
message: "您的订票助手已成功更新至 " + MANIFEST.version + " :-)"
|
||
});
|
||
}
|
||
})();
|
||
|
||
//#endregion
|
||
|
||
//#region 对请求的处理
|
||
|
||
(function requestManager() {
|
||
var filter = {
|
||
urls: ["*://*.12306.cn/*"],
|
||
types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
|
||
};
|
||
|
||
var extraInfo = ["blocking", "requestHeaders"];
|
||
|
||
var autoEnableTrainClassRandom = function (url) {
|
||
var qtc = /trainClass=([^&]+)&/g.exec(url)[1];
|
||
var tc = qtc.replace(/%23/g, "#").split('#');
|
||
if (tc[0] == 'QB') return null;
|
||
|
||
//QB#D#Z#T#K#QT#
|
||
var flags = [0, 0, 0, 0, 0];
|
||
for (var t in tc) {
|
||
var code = tc[t];
|
||
|
||
if (code == 'D') flags[0] = 1;
|
||
else if (code == 'Z') flags[1] = 1;
|
||
else if (code == 'T') flags[2] = 1;
|
||
else if (code == 'K') flags[3] = 1;
|
||
else if (code == 'QT') flags[4] = 1;
|
||
}
|
||
//随机化各个请求
|
||
var result = [];
|
||
var order = ["D", "Z", "T", "K", "QT"];
|
||
for (var i = 0; i < flags.length; i++) {
|
||
if (!flags[i])
|
||
flags[i] = Math.random() > 0.5 ? 1 : 0;
|
||
if (flags[i])
|
||
result.push(order[i]);
|
||
}
|
||
//合并请求
|
||
var ntc = result.join("#") + "#";
|
||
return url.replace(qtc, escape(ntc));
|
||
};
|
||
|
||
function parseCookies(v) {
|
||
var arr = {};
|
||
v.split('; ').forEach(function (x) { var idx = x.indexOf("="); arr[x.substr(0, idx)] = x.substr(idx + 1); });
|
||
return arr;
|
||
};
|
||
|
||
function processRequest(details) {
|
||
var url = details.url;
|
||
|
||
var skipBlacklist = !CFG_MANGER.config.blockDynamicJs;
|
||
var newHeaders = {};
|
||
|
||
var newCookies = null;
|
||
var oldCookiesValue = null;
|
||
|
||
for (var i = 0; i < details.requestHeaders.length; ++i) {
|
||
var h = details.requestHeaders[i];
|
||
var name = h.name;
|
||
var value = h.value;
|
||
|
||
if (name === 'User-Agent') {
|
||
newHeaders[name] = "Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; Trident/5.0;)";
|
||
} else if (h.name == "TRefer") {
|
||
newHeaders["Referer"] = value;
|
||
} else if (h.name == "Referer") {
|
||
if (!newHeaders["Referer"] && value.indexOf("12306.cn") != -1)
|
||
newHeaders["Referer"] = value;
|
||
} else if (name === "Cookie") {
|
||
oldCookiesValue = value;
|
||
newHeaders["Cookie"] = value;
|
||
} else if (name.indexOf("Fish-") !== -1) {
|
||
name = name.substr(5);
|
||
|
||
if (name === "Cookie") {
|
||
newCookies = parseCookies(value);
|
||
} else {
|
||
if (!value) {
|
||
if (newHeaders[name])
|
||
delete newHeaders[name];
|
||
} else {
|
||
newHeaders[name] = value;
|
||
}
|
||
}
|
||
skipBlacklist = true;
|
||
} else if (!newHeaders[name]) {
|
||
newHeaders[name] = value;
|
||
}
|
||
}
|
||
|
||
if (newCookies) {
|
||
var oc = parseCookies(oldCookiesValue);
|
||
newCookies = _.extend({}, oc, newCookies);
|
||
newHeaders["Cookie"] = _.filter(_.map(newCookies, function (v, k) {
|
||
if (!v)
|
||
return "";
|
||
return k + "=" + encodeURIComponent((v));
|
||
}), function (v) { return v || false; }).join("; ");
|
||
if (!newHeaders["Cookie"]) {
|
||
delete newHeaders["Cookie"];
|
||
}
|
||
}
|
||
|
||
var headerCollection = [];
|
||
for (var i in newHeaders) {
|
||
headerCollection.push({ name: i, value: newHeaders[i] });
|
||
}
|
||
|
||
if (!skipBlacklist && $.isFunction(window.cbl)) {
|
||
//检测是否在黑名单中
|
||
if (window.cbl.call(details, url, newHeaders)) {
|
||
return { cancel: true };
|
||
}
|
||
}
|
||
|
||
if (CFG_MANGER.config.appendCacheTagHeader && url.indexOf("querySingleAction.do?method=queryLeftTicket") != -1) {
|
||
headerCollection.push({ name: "If-None-Match", value: Math.random() + "" });
|
||
headerCollection.push({ name: "Pragma", value: "No-cache" });
|
||
// return { requestHeaders: headerCollection, redirectUrl: autoEnableTrainClassRandom(details.url) };
|
||
}
|
||
return { requestHeaders: headerCollection };
|
||
}
|
||
|
||
|
||
chrome.webRequest.onBeforeSendHeaders.addListener(processRequest, filter, extraInfo);
|
||
|
||
chrome.webRequest.onBeforeRequest.addListener(function (data) {
|
||
//if (data.url.indexOf("querySingleAction.do?method=queryLeftTicket") != -1) {
|
||
// return { redirectUrl: autoEnableTrainClassRandom(data.url) };
|
||
//}
|
||
//if (data.url.indexOf("indexAction.do") != -1 || /Action\.do\?method=[a-z\d]{1,3}$/i.test(data.url)) {
|
||
// return { cancel: true };
|
||
//}
|
||
|
||
return null;
|
||
}, filter, ["blocking"]);
|
||
})();
|
||
|
||
//#endregion
|
||
|
||
//#endregion
|
||
|
||
|
||
//#region 服务器测速
|
||
|
||
(function directAccessModule() {
|
||
/// <summary>服务器IP</summary>
|
||
|
||
//TODO: 由于目前猎豹后端并没有现有的云服务平台,并不支持.NET服务,所以暂时下架。
|
||
//重新上架需要部署服务器端。详情联系木鱼,给不给回复看心情。
|
||
|
||
var valid = 0; //window.external.LieBaoLookupDnsAddress ? 1 : 0;
|
||
var enableDirectAccess = typeof (chrome.tabs.httpRequest) === "function";
|
||
|
||
chrome.runtime.onMessage.addListener(function (m, s, r) {
|
||
if (m && m.action === "servervalid")
|
||
r({ valid: valid });
|
||
});
|
||
chrome.runtime.onMessageExternal.addListener(function (m, s, r) {
|
||
if (m && m.action === "servervalid")
|
||
r({ valid: valid });
|
||
});
|
||
|
||
if (!valid)
|
||
return;
|
||
|
||
var serviceUrl = "http://srv.12306.liebao.cn/web/cn12306/ipservice/getlist";
|
||
var reportUrl = "http://srv.12306.liebao.cn/web/cn12306/ipservice/update2";
|
||
var inupdateMode = false;
|
||
var serverStorage = {
|
||
count: 0,
|
||
valid: 0,
|
||
timeout: 0,
|
||
failed: 0,
|
||
lastUpdate: null,
|
||
validList: [],
|
||
status: 0,
|
||
enableDirectAccess: enableDirectAccess
|
||
};
|
||
var serverlist = [],
|
||
testedServer = [],
|
||
currentServer = {
|
||
"kyfw.12306.cn": { ip: null, speed: null }
|
||
//, "dynamic.12306.cn": { ip: null, speed: null }
|
||
//, "www.12306.cn": { ip: null, speed: null }
|
||
};
|
||
var servers = [
|
||
//{ host: "dynamic.12306.cn", url: "http://dynamic.12306.cn/otn/", count: 0 },
|
||
//{ host: "www.12306.cn", url: "http://www.12306.cn/otn/", count: 0 },
|
||
{ host: "kyfw.12306.cn", url: "https://kyfw.12306.cn/otn/", count: 0 }
|
||
],
|
||
serverIndex = 0;
|
||
var localDns = {}, initialChange = false;
|
||
|
||
//消息
|
||
(function () {
|
||
var messageCallback = function (message, sender, response) {
|
||
if (message && message.action) {
|
||
if (message.action === "getServerStatus") {
|
||
response(serverStorage);
|
||
} else if (message.action === "getServerList") {
|
||
response(serverStorage.status == 2 ? _.flatten([testedServer, serverlist]) : []);
|
||
} else if (message.action === "getCurrentServer") {
|
||
response(currentServer);
|
||
}
|
||
}
|
||
};
|
||
chrome.runtime.onMessage.addListener(messageCallback);
|
||
chrome.runtime.onMessageExternal.addListener(messageCallback);
|
||
})();
|
||
|
||
var randomTake = function (list, count) {
|
||
if (!list || list.length <= count) return list;
|
||
var result = [];
|
||
var randomIndex;
|
||
|
||
while (result.length < count) {
|
||
randomIndex = Math.floor(Math.random() * list.length);
|
||
result.push(list.splice(randomIndex, 1));
|
||
}
|
||
|
||
return result;
|
||
};
|
||
|
||
var loadFromServer = function () {
|
||
serverStorage.status = 1;
|
||
chrome.runtime.sendMessage({ action: "serverStateChange", detail: { state: serverStorage.status } });
|
||
chrome.runtime.sendMessage({ action: "track", detail: { type: 90 } });
|
||
|
||
$.getJSON(serviceUrl).done(function (data) {
|
||
//取100个
|
||
data = _.groupBy(data, function (e) { return e.host; });
|
||
for (var host in data) {
|
||
data[host] = randomTake(data[host], 100);
|
||
}
|
||
data = _.flatten(data);
|
||
|
||
serverlist = data;
|
||
serverStorage.count = data.length;
|
||
serverStorage.valid = serverStorage.timeout = serverStorage.failed = 0;
|
||
|
||
|
||
|
||
//增加本地解析的地址
|
||
if (localDns) {
|
||
_.each(localDns, function (ips, host) {
|
||
_.each(ips, function (ip) {
|
||
serverlist.push({ host: host, ip: ip });
|
||
});
|
||
});
|
||
}
|
||
|
||
runServerTest();
|
||
}).fail(function () {
|
||
setTimeout(loadFromServer, 1000 * 60 * 10);
|
||
});
|
||
};
|
||
|
||
var runServerTest = function () {
|
||
testedServer = [];
|
||
serverStorage.status = 2;
|
||
chrome.runtime.sendMessage({ action: "serverStateChange", detail: { state: serverStorage.status } });
|
||
serverTestEntry();
|
||
};
|
||
|
||
var serverTestEntry = function () {
|
||
if (serverlist.length) {
|
||
testServer(serverlist.splice(0, 1), serverTestEntry);
|
||
} else {
|
||
filterServer();
|
||
}
|
||
};
|
||
|
||
var ajaxWrapper = function (url, host) {
|
||
var def = new $.Deferred();
|
||
|
||
chrome.tabs.httpRequest(url, "User-Agent: MSIE 9.0\r\nHost: " + host, 3000, function (result) {
|
||
var resp = null;
|
||
try {
|
||
resp = JSON.parse(result);
|
||
} catch (e) {
|
||
|
||
}
|
||
if (!resp) {
|
||
def.reject(0, 'unknown error.');
|
||
return;
|
||
}
|
||
var a = resp[0];
|
||
var b = resp[1];
|
||
var c = resp[2];
|
||
if (!a) {
|
||
if (b === 10001) {
|
||
//timeout
|
||
def.reject(0, 'timeout');
|
||
} else {
|
||
def.reject(b, c);
|
||
}
|
||
} else {
|
||
def.resolve(c, b);
|
||
}
|
||
});
|
||
|
||
return def.promise();
|
||
};
|
||
|
||
var testServer = function (server, callback) {
|
||
server = server[0];
|
||
server.host = server.host || "kyfw.12306.cn";
|
||
|
||
var url = "https://" + server.ip + "/otn/";
|
||
var time = new Date();
|
||
|
||
ajaxWrapper(url, server.host).done(function (text) {
|
||
if (!text || text.indexOf("客运服务") !== -1)
|
||
server.speed = new Date() - time;
|
||
else {
|
||
server.speed = -2;
|
||
}
|
||
}).fail(function () {
|
||
server.speed = -1;
|
||
}).always(function () {
|
||
server.status = server.speed == -1 || server.speed == -2 ? -1 : server.speed > 1000 ? -2 : 1;
|
||
if (inupdateMode) {
|
||
if (server.status === -1) serverStorage.failed++;
|
||
else if (server.status === -2) serverStorage.timeout++;
|
||
else if (server.status === 0) serverStorage.timeout++;
|
||
else {
|
||
serverStorage.valid++;
|
||
serverStorage.validList.push(server);
|
||
}
|
||
}
|
||
|
||
testedServer.push(server);
|
||
setTimeout(function () {
|
||
chrome.runtime.sendMessage({ action: "serverTestResult", detail: server });
|
||
callback();
|
||
}, 100);
|
||
});
|
||
};
|
||
|
||
var filterServer = function () {
|
||
serverStorage.status = 3;
|
||
chrome.runtime.sendMessage({ action: "serverStateChange", detail: { state: serverStorage.status } });
|
||
|
||
//分组
|
||
serverStorage.validList = _.groupBy(serverStorage.validList, function (e) {
|
||
return e.host;
|
||
});
|
||
//排序
|
||
_.each(serverStorage.validList, function (e, i, l) {
|
||
e.sort(function (x, y) {
|
||
if (x.speed === y.speed) return 0;
|
||
if (x.speed === -1 && y.speed !== -1) return 1;
|
||
if (x.speed !== -1 && y.speed === -1) return -1;
|
||
if (x.speed === 0 && y.speed !== 0) return 1;
|
||
if (x.speed !== 0 && y.speed === 0) return -1;
|
||
|
||
return x.speed - y.speed;
|
||
});
|
||
l[i] = e.splice(0, 20);
|
||
});
|
||
//取前20个
|
||
serverStorage.status = 0;
|
||
serverStorage.lastUpdate = new Date();
|
||
chrome.runtime.sendMessage({ action: "serverStateChange", detail: { state: serverStorage.status } });
|
||
|
||
if (inupdateMode) {
|
||
//更新模式, 提交速度报告
|
||
var data = [];
|
||
_.each(testedServer, function (e) {
|
||
var x = _.pick(e, 'ip', 'averageSpeed', 'host');
|
||
x.averageSpeed = e.speed;
|
||
data.push(x);
|
||
});
|
||
//上报到服务器
|
||
var updata = _.groupBy(data, function (e) {
|
||
return e.host;
|
||
});
|
||
var rptData = {};
|
||
for (var host in updata) {
|
||
rptData[host] = JSON.stringify(updata[host]);
|
||
}
|
||
chrome.runtime.sendMessage({ action: "track", detail: { type: 91 } });
|
||
$.post(reportUrl, rptData);
|
||
localStorage["serverStorage"] = JSON.stringify(serverStorage);
|
||
} else {
|
||
//缓存测速模式
|
||
if (_.flatten(serverStorage.validList).length < 5) {
|
||
//服务器过少,强行更新一次
|
||
inupdateMode = true;
|
||
serverStorage.validList = [];
|
||
loadFromServer();
|
||
return;
|
||
} else {
|
||
localStorage["serverStorage"] = JSON.stringify(serverStorage);
|
||
}
|
||
}
|
||
|
||
//开始实时跟踪当前的状态
|
||
testServerLoop();
|
||
};
|
||
|
||
var applyServerLoop = function () {
|
||
_.each(currentServer, function (e) {
|
||
if (e.ip)
|
||
window.external.LieBaoSetHostAddress(e.host, e.ip, 1);
|
||
});
|
||
};
|
||
setInterval(applyServerLoop, 20000);
|
||
|
||
var applyServer = function (host, ip) {
|
||
chrome.runtime.sendMessage({ action: "track", detail: { type: 92, values: [ip] } });
|
||
|
||
if (ip) {
|
||
window.external.LieBaoSetHostAddress(host, ip, 1);
|
||
} else {
|
||
window.external.LieBaoSetHostAddress(host, localDns[host][0], 0);
|
||
}
|
||
|
||
//if (initialChange)
|
||
// chrome.runtime.sendMessage({ action: "showNotification", detail: { title: "订票助手提示", message: "服务器访问不流畅,已经为您切换服务器。", iconUrl: "/icons/icon_128.png" } });
|
||
};
|
||
|
||
var testLoopSleepTime = 20000;
|
||
var testServerLoop = function () {
|
||
//切换IP会导致掉线,所以暂时屏蔽
|
||
return;
|
||
//if (entry12306) {
|
||
// var testCallback = function (time) {
|
||
// var server = servers[serverIndex];
|
||
// var host = server.host;
|
||
// if (CFG_MANGER.config.enableServerAutoChange) {
|
||
// if (time > 3000 || (time > 500 && ++currentServer[host].count >= 5)) {
|
||
// currentServer[host].count = 0;
|
||
|
||
// if (!currentServer[host].ip) {
|
||
// //速度过慢,请求切换,策略随机选
|
||
// var targetList = serverStorage.validList[host];
|
||
// var target = targetList[Math.floor(Math.random() * targetList.length)];
|
||
// if (target && target.ip && (targetList[0].speed < time || time <= 0)) {
|
||
// currentServer[host].rate = Math.max(Math.floor((target.speed - time) * 1000 / time), 10) / 10;
|
||
// currentServer[host].ip = target.ip;
|
||
// applyServer(host, target.ip);
|
||
|
||
// //立刻重新测速
|
||
// setTimeout(testServerLoop, 1000);
|
||
// return;
|
||
// }
|
||
// } else {
|
||
// //实在找不到或已经设置过了,那就恢复默认吧。
|
||
// currentServer[host].ip = null;
|
||
// applyServer(host, null);
|
||
// setTimeout(testServerLoop, 1000);
|
||
// return;
|
||
// }
|
||
// } else {
|
||
// currentServer[host].speed = time;
|
||
// currentServer[host].count = 0;
|
||
// }
|
||
// }
|
||
// chrome.runtime.sendMessage({ action: "serverStateChange", detail: { state: serverStorage.status } });
|
||
|
||
// serverIndex++;
|
||
// if (serverIndex >= servers.length) {
|
||
// serverIndex = 0;
|
||
|
||
// if (!initialChange && entry12306) {
|
||
|
||
// //初始化的时候自动选择一次
|
||
// var selected = [];
|
||
// _.each(currentServer, function (e, h) {
|
||
// var list = serverStorage.validList[h];
|
||
// if (!list || !list.length) return;
|
||
|
||
// if (e.speed > list[0].speed) {
|
||
// var rate = Math.max(Math.floor((e.speed - list[0].speed) * 1000 / e.speed), 10) / 10;
|
||
// e.ip = list[0].ip;
|
||
// e.speed = list[0].speed;
|
||
// e.rate = rate;
|
||
// applyServer(h, e.ip);
|
||
// selected.push(e.ip + "(加速 " + rate + "%)");
|
||
// }
|
||
// });
|
||
|
||
// if (selected.length) {
|
||
// chrome.runtime.sendMessage({ action: "showNotification", detail: { title: "订票助手已优化服务器", message: "订票助手已为您选择最快的服务器:" + selected.join("; ") + "。", iconUrl: "/icons/icon_128.png" } });
|
||
// }
|
||
// chrome.runtime.sendMessage({ action: "serverStateChange", detail: { state: serverStorage.status } });
|
||
// initialChange = true;
|
||
// }
|
||
// setTimeout(testServerLoop, testLoopSleepTime);
|
||
// testLoopSleepTime += 5000;
|
||
|
||
// } else {
|
||
// testServerLoop();
|
||
// }
|
||
// };
|
||
|
||
// testUrlSpeed(servers[serverIndex].url, testCallback);
|
||
//} else {
|
||
// setTimeout(testServerLoop, 5000);
|
||
//}
|
||
};
|
||
|
||
var testUrlSpeed = function (url, callback) {
|
||
var n = new Date();
|
||
|
||
$.ajax(url, { dataType: "text", method: "GET", timeout: 3000 }).done(function () {
|
||
callback(new Date() - n);
|
||
}).fail(function () {
|
||
callback(999999);
|
||
});
|
||
};
|
||
|
||
var checkAndStart = function () {
|
||
if (localStorage['serverStorage']) {
|
||
serverStorage = JSON.parse(localStorage['serverStorage']);
|
||
serverStorage.enableDirectAccess = enableDirectAccess;
|
||
}
|
||
if (!serverStorage.lastUpdate || (new Date().getTime() / 3600000) - new Date(serverStorage.lastUpdate).getTime() / 3600000 >= 12 || serverStorage.validList.length < 5) {
|
||
inupdateMode = true;
|
||
serverStorage.validList = [];
|
||
loadFromServer();
|
||
} else {
|
||
serverlist = serverStorage.validList;
|
||
testServerLoop();
|
||
}
|
||
};
|
||
|
||
//尝试解析地址
|
||
var boot = function () {
|
||
var failedCount = 0;
|
||
_.each(servers, function (e) {
|
||
localDns[e.host] = _.filter(window.external.LieBaoLookupDnsAddress(e.host, 'false').split(';'), function (e) { return e || false; });
|
||
if (!localDns[e.host] || !localDns[e.host].length)
|
||
failedCount++;
|
||
});
|
||
//如果存在不能解析的情况,则失败
|
||
if (failedCount) {
|
||
valid = -1;
|
||
return;
|
||
}
|
||
//测试是否有代理服务器
|
||
ajaxWrapper("https://" + localDns['kyfw.12306.cn'][0] + "/otn/", "kyfw.12306.cn").done(function () {
|
||
checkAndStart();
|
||
}).fail(function () {
|
||
valid = -1;
|
||
});
|
||
};
|
||
|
||
//策略:如果前一天有用过12306的话,那就执行
|
||
var booted = false;
|
||
var triggerUpdate = function () {
|
||
localStorage["lastUsed"] = Math.floor(new Date().getTime() / 86400000);
|
||
if (!booted) {
|
||
booted = true;
|
||
boot();
|
||
}
|
||
entry12306 = true;
|
||
}
|
||
var parseJson = function (text) {
|
||
try {
|
||
return JSON.parse(text);
|
||
} catch (e) {
|
||
if (isDebug)
|
||
console.log("WARNING: unable to parse json response. content -> " + text);
|
||
return null;
|
||
}
|
||
};
|
||
chrome.runtime.onMessage.addListener(function (m, s, r) {
|
||
if (!m || !m.action)
|
||
return;
|
||
|
||
if (m.action === 'triggerUpdate') {
|
||
triggerUpdate();
|
||
} else if (m.action === "directAccess") {
|
||
var data = m.data;
|
||
var host = /^https?:\/\/([^\/]+)\//.exec(data.url) && RegExp.$1;;
|
||
var hostip = null;
|
||
var hostindex = 0;
|
||
if (enableDirectAccess && host && serverStorage.validList && serverStorage.validList[host] && serverStorage.validList[host].length) {
|
||
var hosts = serverStorage.validList[host];
|
||
hostindex = Math.floor(Math.random() * hosts.length);
|
||
hostip = hosts[hostindex];
|
||
data.url = data.url.replace("//" + host, "//" + hostip.ip);
|
||
}
|
||
|
||
if (hostip) {
|
||
//build header
|
||
var headers = [];
|
||
if (data.headers) {
|
||
for (var i in data.headers) {
|
||
var key = i;
|
||
if (key.indexOf("Fish-") === 0)
|
||
key = key.substr(5);
|
||
headers.push(key + ": " + data.headers[i]);
|
||
}
|
||
}
|
||
headers.push("Host: " + host);
|
||
//using direct access
|
||
if (data.data) {
|
||
data.url += "?" + $.param(data.data);
|
||
}
|
||
if (isDebug)
|
||
console.log("direct access to url " + data.url);
|
||
chrome.tabs.httpRequest(
|
||
data.url,
|
||
headers.join("\r\n"),
|
||
20000,
|
||
function (response) {
|
||
if (isDebug)
|
||
console.log("direct access response received. data: ", response);
|
||
(function (success, status, text, rHeader, base64) {
|
||
if (!success || status !== 200) {
|
||
//failed.
|
||
r([false, status, status, text, rHeader || "", null]);
|
||
|
||
//block error ip
|
||
hostip.failedCount = (hostip.failedCount || 0) + 1;
|
||
console.log("bad response for host [" + hostip.ip + "], increase failed counter. current at " + hostip.failedCount);
|
||
if (hostip.failedCount > 3) {
|
||
//block error ip
|
||
serverStorage.validList[host].splice(hostindex, 1);
|
||
console.log("bad response for host [" + hostip.ip + "] failed too many times, removed from validlist.");
|
||
localStorage["serverStorage"] = JSON.stringify(serverStorage);
|
||
}
|
||
} else {
|
||
r([true, status, status, text, rHeader || "", parseJson(text)]);
|
||
}
|
||
}).apply(this, parseJson(response));
|
||
}
|
||
);
|
||
} else {
|
||
//doing a regular access
|
||
$.ajax(data).done(function (result, status, xhr) {
|
||
r([true, xhr.status, xhr.statusText, xhr.responseText, xhr.getAllResponseHeaders(), result]);
|
||
}).fail(function (xhr) {
|
||
r([false, xhr.status, xhr.statusText, xhr.responseText, "", null]);
|
||
});
|
||
}
|
||
|
||
return true;
|
||
}
|
||
});
|
||
chrome.runtime.onMessageExternal.addListener(function (m, s, r) {
|
||
if (m && m.action === 'triggerUpdate') {
|
||
triggerUpdate();
|
||
}
|
||
});
|
||
setInterval(function () {
|
||
entry12306 = false;
|
||
chrome.tabs.query({ url: "*://*.12306.cn/*" }, function (a) {
|
||
entry12306 |= a && a.length > 0;
|
||
});
|
||
chrome.tabs.query({ url: "*://12306.liebao.cn/*" }, function (a) {
|
||
entry12306 |= a && a.length > 0;
|
||
});
|
||
}, 20000);
|
||
})();
|
||
|
||
|
||
//#endregion
|
||
|
||
//#region 统计
|
||
|
||
(function statModule() {
|
||
var url1 = "http://liebao.tjweb.ijinshan.com/click/__infoc.gif?actionname=liebao_80";
|
||
|
||
var trackback = function (type, values) {
|
||
values = values || [];
|
||
var data = { type: type };
|
||
|
||
for (var index in values) {
|
||
if (values[index]) {
|
||
data["value" + (parseInt(index) + 1)] = values[index] + '';
|
||
}
|
||
}
|
||
$.get(url1, data);
|
||
};
|
||
|
||
chrome.runtime.onMessage.addListener(function (m, s, r) {
|
||
if (!m || !m.action || m.action !== 'track')
|
||
return;
|
||
|
||
trackback(m.detail.type, m.detail.values);
|
||
});
|
||
|
||
chrome.runtime.onMessageExternal.addListener(function (m, s, r) {
|
||
if (!m || !m.action || m.action !== 'track')
|
||
return;
|
||
|
||
trackback(m.detail.type, m.detail.values);
|
||
});
|
||
|
||
trackback(99, [MANIFEST.version, bv]);
|
||
})();
|
||
|
||
//#endregion
|
||
|
||
|
||
//#region 版本更新
|
||
|
||
(function versionUpdateModule() {
|
||
//var cv = parseInt(/Chrome\/(\d+)/i.exec(navigator.userAgent)[1]);
|
||
//var updateurl = "http://www.fishlee.net/service/update2/44/" + (cv < 34 ? "44" : "60") + "/version_v6.json?" + Math.random();
|
||
var updateurl = "http://srv.12306.liebao.cn/data/version_v6.json?" + Math.random();
|
||
var lastCheckUpdate = null;
|
||
var hasUpdate = false, lastVersion = null, lastMessage = null, updateInfo = null;
|
||
|
||
var compareVersion = function (v1, v2) {
|
||
var vv1 = v1.split('.');
|
||
var vv2 = v2.split('.');
|
||
|
||
var length = Math.min(vv1.length, vv2.length);
|
||
for (var i = 0; i < length; i++) {
|
||
var s1 = parseInt(vv1[i]);
|
||
var s2 = parseInt(vv2[i]);
|
||
|
||
if (s1 < s2) return -1;
|
||
if (s1 > s2) return 1;
|
||
}
|
||
|
||
return vv1.length > vv2.length ? 1 : vv1.length < vv2.length ? -1 : 0;
|
||
};
|
||
|
||
var checkUpdate = function () {
|
||
$.getJSON(updateurl, function (data) {
|
||
updateInfo = data;
|
||
lastVersion = data.version;
|
||
lastMessage = data.notify;
|
||
updateInfo.hasUpdate = hasUpdate = compareVersion(MANIFEST.version, data.version) < 0;
|
||
|
||
chrome.runtime.sendMessage({ action: "updateInfoRefreshed", detail: updateInfo });
|
||
});
|
||
lastCheckUpdate = new Date();
|
||
};
|
||
|
||
var msgCallback = function (m, s, r) {
|
||
if (!m || !m.action)
|
||
return;
|
||
|
||
if (m.action === 'getUpdateInfo')
|
||
r(updateInfo);
|
||
else if (m.action === 'getVersionInfo')
|
||
r({ curVersion: MANIFEST.version, updateInfo: updateInfo });
|
||
else if (m.action === 'triggerUpdate') {
|
||
if (!lastCheckUpdate || (new Date() - lastCheckUpdate) >= 1200000) {
|
||
checkUpdate();
|
||
}
|
||
} else if (m.action === "getBv") {
|
||
r({ bv: bv });
|
||
}
|
||
};
|
||
chrome.runtime.onMessage.addListener(msgCallback);
|
||
chrome.runtime.onMessageExternal.addListener(msgCallback);
|
||
|
||
//TODO 移除内建的检查更新机制,因为这个不是很必须
|
||
//checkUpdate();
|
||
})();
|
||
|
||
//#endregion
|
||
|
||
|
||
//#region Captcha
|
||
|
||
(function webCaptchaModule() {
|
||
var msgCallback = function (m, s, r) {
|
||
if (m && m.action === 'captcha' && CFG_MANGER.config.captchaServerUrl) {
|
||
var code;
|
||
|
||
$.ajax(CFG_MANGER.config.captchaServerUrl, {
|
||
method: "POST",
|
||
data: { pic: m.detail.base64, sign: window.external.LieBaoSign(m.detail.base64) },
|
||
timeout: 3000
|
||
}).done(function (data) {
|
||
code = data.success ? data.code.replace(/\s/g, "") : "";
|
||
}).fail(function () {
|
||
code = "";
|
||
}).always(function () {
|
||
r({ code: code });
|
||
});
|
||
|
||
return true;
|
||
}
|
||
};
|
||
chrome.runtime.onMessage.addListener(msgCallback);
|
||
chrome.runtime.onMessageExternal.addListener(msgCallback);
|
||
})();
|
||
|
||
//#endregion
|
||
|
||
|
||
//#region 配置同步和网页上的提示接口
|
||
|
||
(function webStorageInterface() {
|
||
var msgCallback = function (m, s, r) {
|
||
if (m.action === "getStorage")
|
||
r({ action: "sendStorage", detail: localStorage });
|
||
else if (m.action === "setStorage" && m.detail) {
|
||
_.each(m.detail, function (v, k) {
|
||
if (v)
|
||
localStorage.setItem(k, v);
|
||
else localStorage.removeItem(k);
|
||
});
|
||
r({ action: "sendStorage", detail: m.detail });
|
||
} else if (m.action === "notify") {
|
||
var notify = new Notification(m.title || "订票助手", { body: m.content || null, icon: "/icons/icon_n.png" });
|
||
setTimeout(function () {
|
||
notify.close();
|
||
}, 5000);
|
||
}
|
||
};
|
||
//chrome.runtime.onMessage.addListener(msgCallback);
|
||
chrome.runtime.onMessageExternal.addListener(msgCallback);
|
||
})();
|
||
|
||
//#endregion
|
||
|
||
|
||
//#region 聊天系统
|
||
|
||
(function chatModule() {
|
||
var ports = [];
|
||
var msgQueue = [];
|
||
var lastMessages = [];
|
||
var checkPortTimer = null;
|
||
|
||
var clearPortTimer = function () {
|
||
serverConnection.disconnect();
|
||
lastMessages = [];
|
||
msgQueue = [];
|
||
checkPortTimer = null;
|
||
};
|
||
|
||
var portOnMessage = function (msg, port) {
|
||
if (!msg || !msg.action)
|
||
return;
|
||
|
||
switch (msg.action) {
|
||
case "getChatServerStatus":
|
||
serverMgr.loadServers(function (servers) {
|
||
port.postMessage({ action: "responseServer", detail: servers });
|
||
});
|
||
break;
|
||
case "getCurrentRoomInfo":
|
||
port.postMessage({ action: "responseCurrentRoomInfo", detail: serverConnection.currentRoom });
|
||
break;
|
||
case "enterChatRoom":
|
||
serverConnection.connect(msg.detail);
|
||
break;
|
||
case "chatRoomSendMsg":
|
||
//if (!msg.detail.roomid)
|
||
// msg.detail.roomid = serverConnection.currentRoom.id;
|
||
|
||
//$.post("http://12306.liebao.cn/index.php?r=Api/SentMessage", {
|
||
// data: JSON.stringify(msg)
|
||
//}).done(function (result) {
|
||
// if (result.resCode === 0) {
|
||
|
||
// } else {
|
||
// port.postMessage({ action: "sendMessageFailed", detail: result.message });
|
||
// }
|
||
//}).fail(function () {
|
||
// port.postMessage({ action: "sendMessageFailed", detail: "聊天服务器繁忙,发送失败" });
|
||
//});
|
||
serverConnection.sendMsg(msg.detail);
|
||
|
||
break;
|
||
case "disconnectChatRoom":
|
||
lastMessages = [];
|
||
msgQueue = [];
|
||
serverConnection.disconnect();
|
||
break;
|
||
default:
|
||
}
|
||
};
|
||
var portOnDisconnect = function (port) {
|
||
var idx = _.indexOf(ports, port);
|
||
if (idx > -1) {
|
||
ports.splice(idx, 1);
|
||
}
|
||
if (!checkPortTimer && ports.length === 0)
|
||
checkPortTimer = setTimeout(clearPortTimer, 30 * 60 * 1000);
|
||
};
|
||
var postMessageToPort = function (msg) {
|
||
if (msg && msg.action === "chatRoomReceiveMsg") {
|
||
if (!ports.length) {
|
||
msgQueue.push(msg);
|
||
return;
|
||
}
|
||
lastMessages.push(msg);
|
||
lastMessages.length > 20 && lastMessages.splice(0, 1);
|
||
}
|
||
|
||
ports.forEach(function (p) {
|
||
p.postMessage(msg);
|
||
});
|
||
|
||
if (msg && msg.action === "chatRoomConnected") {
|
||
if (lastMessages.length) {
|
||
lastMessages.forEach(function (m) {
|
||
ports.forEach(function (p) {
|
||
p.postMessage(m);
|
||
});
|
||
});
|
||
}
|
||
if (msgQueue.length) {
|
||
msgQueue.forEach(function (m) {
|
||
ports.forEach(function (p) {
|
||
p.postMessage(m);
|
||
});
|
||
});
|
||
msgQueue = [];
|
||
}
|
||
}
|
||
};
|
||
|
||
chrome.runtime.onConnectExternal.addListener(function (port) {
|
||
ports.push(port);
|
||
|
||
port.onMessage.addListener(portOnMessage);
|
||
port.onDisconnect.addListener(portOnDisconnect);
|
||
|
||
if (checkPortTimer) {
|
||
clearTimeout(checkPortTimer);
|
||
checkPortTimer = null;
|
||
}
|
||
});
|
||
|
||
var serverMgr = (function chatServerManager() {
|
||
var isServerLoaded = null;
|
||
var isInServerLoading = false;
|
||
var servers = null;
|
||
var callbackQueue = [];
|
||
var lastLoad = null;
|
||
|
||
var setRoomCount = function (id, count) {
|
||
if (!servers)
|
||
return;
|
||
var room = _.findWhere(servers, { id: id });
|
||
if (room) room.onlinecount = count;
|
||
};
|
||
|
||
var execCallback = function () {
|
||
var callback;
|
||
while (callbackQueue.length) {
|
||
(callback = callbackQueue.pop()) && callback(servers);
|
||
};
|
||
};
|
||
|
||
var loadServers = function (callback) {
|
||
if (!callback)
|
||
return;
|
||
|
||
if (isServerLoaded && lastLoad && (new Date() - lastLoad) < 1000 * 60 * 10)
|
||
callback(servers);
|
||
else {
|
||
callbackQueue.push(callback);
|
||
if (!isInServerLoading) {
|
||
isInServerLoading = true;
|
||
|
||
$.get(CFG_MANGER.config.chatServerApi, null, null, "json").done(function (data) {
|
||
servers = data;
|
||
isInServerLoading = false;
|
||
isServerLoaded = true;
|
||
execCallback();
|
||
}).fail(function () {
|
||
servers = null;
|
||
isInServerLoading = false;
|
||
execCallback();
|
||
}).always(function () {
|
||
lastLoad = new Date();
|
||
});
|
||
}
|
||
}
|
||
};
|
||
//转发系统消息
|
||
chrome.runtime.onMessage.addListener(function (m, s, r) {
|
||
if (!m || !m.action)
|
||
return;
|
||
|
||
if (m.action === "serverStateChange" || m.action === "sysConfigUpdate")
|
||
postMessageToPort(m);
|
||
|
||
});
|
||
|
||
return {
|
||
loadServers: loadServers,
|
||
setRoomCount: setRoomCount
|
||
};
|
||
})();
|
||
|
||
var serverConnection = (function () {
|
||
var currentRoom = null;
|
||
var socket = null;
|
||
var that = this;
|
||
var roomId;
|
||
|
||
var connect = function (room) {
|
||
currentRoom = room;
|
||
var url = currentRoom.url;
|
||
|
||
//如果已变更房间,则先断开
|
||
if (socket !== null && room.id !== roomId)
|
||
disconnect();
|
||
|
||
roomId = room.id;
|
||
|
||
if (socket === null) {
|
||
socket = new WebSocket(url, []);
|
||
socket.binaryType = "arraybuffer";
|
||
socket.onclose = function () {
|
||
socket = null;
|
||
postMessageToPort({ action: "chatRoomDisconnected" });
|
||
};
|
||
socket.onopen = function () {
|
||
postMessageToPort({ action: "chatRoomConnected" });
|
||
};
|
||
socket.onmessage = function (e) {
|
||
var buffer = new Uint8Array(e.data);
|
||
var data = [];
|
||
for (var i = 0; i < buffer.length; i++) {
|
||
data.push(buffer[i]);
|
||
}
|
||
|
||
postMessageToPort({ action: "chatRoomReceiveMsg", detail: { buffer: data } });
|
||
};
|
||
socket.onerror = function () {
|
||
try {
|
||
socket.close();
|
||
} catch (e) {
|
||
|
||
}
|
||
};
|
||
postMessageToPort({ action: "chatRoomConnecting" });
|
||
} else {
|
||
postMessageToPort({ action: "chatRoomConnected" });
|
||
}
|
||
};
|
||
var sendMsg = function (msg) {
|
||
if (socket !== null) {
|
||
//socket.send(JSON.stringify(msg));
|
||
socket.send(new Uint8Array(msg).buffer);
|
||
}
|
||
};
|
||
var disconnect = function () {
|
||
if (socket) {
|
||
socket.close();
|
||
socket = null;
|
||
}
|
||
currentRoom = null;
|
||
roomId = null;
|
||
};
|
||
|
||
var ret = {
|
||
connect: connect,
|
||
disconnect: disconnect,
|
||
sendMsg: sendMsg
|
||
};
|
||
Object.defineProperty(ret, "currentRoom", {
|
||
get: function () {
|
||
return currentRoom;
|
||
}
|
||
});
|
||
|
||
return ret;
|
||
})();
|
||
})();
|
||
|
||
//#endregion
|
||
|
||
|
||
//#region 定时提醒
|
||
|
||
(function TimerAlerm() {
|
||
var tasks = JSON.parse(localStorage["alarm"] || "[]");
|
||
var buttonImgUrl = "/infobar/theme/plus_16.png";
|
||
var iconLeft = "/icons/icon_n.png";
|
||
var checkTimer = null;
|
||
var alarmData = {};
|
||
|
||
var saveAlarm = function () {
|
||
localStorage["alarm"] = JSON.stringify(tasks);
|
||
};
|
||
|
||
var buttonClickCallback = function (btnId, index) {
|
||
if (!alarmData[btnId])
|
||
return;
|
||
|
||
var task = alarmData[btnId];
|
||
var data = task.data;
|
||
delete alarmData[btnId];
|
||
|
||
chrome.tabs.create({
|
||
active: true,
|
||
url: "http://12306.liebao.cn/#ALARM-" + encodeURIComponent(JSON.stringify(data))
|
||
});
|
||
};
|
||
chrome.notifications.onButtonClicked.addListener(buttonClickCallback);
|
||
|
||
var checkForAlarm = function () {
|
||
checkTimer = null;
|
||
var hasChange = false;
|
||
var alarms = {};
|
||
while (tasks.length > 0 && tasks[0].time <= new Date().getTime()) {
|
||
var task = tasks.shift();
|
||
alarms[task.group] = task;
|
||
hasChange = true;
|
||
}
|
||
if (hasChange) {
|
||
_.each(alarms, function (task) {
|
||
var id = "ALARM-" + task.data.fromCode + "-" + task.data.toCode + new Date().getTime();
|
||
chrome.runtime.sendMessage({ action: "track", detail: { type: 132, values: [task.type || 0, task.point || 0] } });
|
||
|
||
chrome.notifications.create(id, {
|
||
type: "basic",
|
||
iconUrl: iconLeft,
|
||
title: task.group,
|
||
message: task.text,
|
||
buttons: [
|
||
{ title: "立刻打开订票页面", iconUrl: buttonImgUrl }
|
||
]
|
||
}, function (_id) {
|
||
id = _id;
|
||
alarmData[id] = task;
|
||
setTimeout(function () {
|
||
delete alarmData[_id];
|
||
chrome.notifications.clear(_id, function () { });
|
||
}, 10000);
|
||
});
|
||
});
|
||
}
|
||
|
||
if (tasks.length)
|
||
checkTimer = setTimeout(checkForAlarm, 30000);
|
||
if (hasChange)
|
||
saveAlarm();
|
||
};
|
||
|
||
|
||
chrome.runtime.onMessageExternal.addListener(function (m, s, r) {
|
||
if (!m || !m.action || m.action !== 'setAlarmTask')
|
||
return;
|
||
|
||
var newtasks = m.detail;
|
||
_.each(newtasks, function (t) {
|
||
tasks.push(t);
|
||
});
|
||
tasks.sort(function (x, y) {
|
||
return x.time - y.time;
|
||
});
|
||
saveAlarm();
|
||
if (!checkTimer)
|
||
checkForAlarm();
|
||
});
|
||
|
||
checkForAlarm();
|
||
})();
|
||
|
||
|
||
|
||
//#endregion
|