Light12306/RwTicketAssistantV2/app/background.js

1234 lines
33 KiB
JavaScript
Raw Normal View History

var MANIFEST = chrome.runtime.getManifest();
var INFOBAR = chrome.infobars || (chrome.experimental && chrome.experimental.infobars);
var isDebug = (compressFunc + '').indexOf("false") != -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 || "",
2014-08-08 20:46:37 +08:00
iconUrl: opts.iconUrl || "/icons/icon_128.png",
//contextMessage: opts.contextMessage || "",
priority: opts.priority || 0,
eventTime: opts.eventTime || null,
buttons: _.map(opts.buttons, function (e) {
2014-08-08 20:46:37 +08:00
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(
2014-08-08 20:46:37 +08:00
{ 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" });
}
});
};
return new notify();
})();
(function () {
var notifyId;
var tabid, message;
//未加载提醒
var closeCallback = function (id) {
if (id === notifyId) {
notifyId = null;
}
};
var clickCallback = function (id, idx) {
if (id === notifyId && idx === 0) {
chrome.tabs.update(tabid, {
url: chrome.extension.getURL(message.detail.url.indexOf("/otn") != -1 ? "/infobar/main.html?new" : "/infobar/main.html"),
selected: true
}, function () { });
chrome.notifications.clear("notLoadMessage", function () { });
}
};
chrome.notifications.onClosed.addListener(closeCallback);
chrome.notifications.onButtonClicked.addListener(clickCallback);
chrome.runtime.onMessage.addListener(function (m, sender, response) {
if (m.action && m.action === "notLoadTip") {
message = m;
tabid = sender.tab.id;
if (notifyId) {
chrome.notifications.update(notifyId, {
type: 'basic',
iconUrl: '/icons/icon_128.png',
title: '订票助手未启动',
message: '订票助手未加载,请点击工具栏『订票助手』图标并点击订票菜单来使用。',
buttons: [
{ title: '或点击这里启动订票助手', iconUrl: "/infobar/theme/plus_16.png" }
]
}, function () {
});
} else {
chrome.notifications.create('', {
type: 'basic',
iconUrl: '/icons/icon_128.png',
title: '订票助手未启动',
message: '订票助手未加载,请点击工具栏『订票助手』图标并点击订票菜单来使用。',
buttons: [
{ title: '或点击这里启动订票助手', iconUrl: "/infobar/theme/plus_16.png" }
]
}, function (id) {
notifyId = id;
});
}
setTimeout(function () {
closeCallback(notifyId);
}, 5000);
}
});
})();
//#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,
enableSelfTrack: true,
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
};
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.refresh = function () {
if (timerId) {
clearTimeout(timerId);
timerId = null;
}
if (entry12306 || !loaded) {
lastUpdate = new Date();
$.getJSON("http://storage.fishlee.net/soft/files/44/rwticketconfig.json?" + Math.random(), function (data) {
if (typeof (data.enableAutoCaptcha) === 'undefined' || data.enableAutoCaptcha)
data.enableAutoCaptcha = data.enableAutoCaptcha && typeof window.external.LieBaoSign === 'function';
localStorage["sysConfig"] = JSON.stringify(data);
__.sysConfig = data;
__.config = $.extend({}, __.baseConfig, __.userConfig, __.sysConfig);
chrome.runtime.sendMessage({ action: "sysConfigUpdate", detail: __.config });
});
}
var m = new Date().getMinutes();
if (m >= 50 || m <= 15) {
timerId = setTimeout(__.refresh, 5 * 60 * 1000);
} else {
timerId = setTimeout(__.refresh, sleepTime);
}
};
this.isEnabled = function (tag) {
};
chrome.runtime.onMessage.addListener(function (m, s, r) {
if (m && m.action === 'enter12306') {
sleepTime = 20 * 60 * 1000;
if (lastUpdate == null || (new Date() - lastUpdate) >= 300 * 1000);
__.refresh();
}
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 });
}
});
this.refresh();
loaded = true;
return this;
};
var mm = new manager();
chrome.runtime.onMessage.addListener(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) });
}
if (m.action === "setUserConfig") {
mm.userConfig = $.extend({}, mm.userConfig, r.detail);
mm.refresh();
}
});
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 () {
chrome.runtime.onMessage.addListener(function (msg, sender, resp) {
if (msg.action && msg.action == "isInforbarEnabled") {
resp(INFOBAR ? true : false);
}
});
});
(function checkRunModeAndBootStrap() {
localStorage["inforbarMode"] = INFOBAR ? "1" : "0";
if (!INFOBAR) return;
function checkIfInfobarShown(tabid) {
var views = chrome.extension.getViews({ type: "infobar" });
for (var i in views) {
var v = views[i];
if (v.location.search == "?" + tabid) {
return true;
}
}
return false;
}
var showInfobar = function (tabid, page, isOtn) {
//if (checkIfInfobarShown(tabid)) {
// INFOBAR.show({
// tabId: tabid,
// height: 155
// });
// return;
//}
//显示infobar
INFOBAR.show({
tabId: tabid,
height: 155,
path: "/infobar/" + page + ".html?" + (isOtn ? "new" : "old") + tabid
});
};
chrome.tabs.onUpdated.addListener(function (tabid, changeinfo, tab) {
if (changeinfo.status == "complete") {
if ((/https?:\/\/dynamic\.12306\.cn\/.*/i.test(tab.url) || /https?:\/\/www\.12306\.cn\/mormhweb\/kyfw\/?.*/i.test(tab.url)) && !checkIfInfobarShown(tab.id)) {
showInfobar(tab.id, "main", false);
} else if (/https?:\/\/(www|dynamic|kyfw)\.12306\.cn\/otn.*/i.test(tab.url)) {
showInfobar(tab.id, "main", true);
}
}
});
//初始化infobar
/*chrome.tabs.query({ url: "*://kyfw.12306.cn/*" }, function (ta) {
$.each(ta, function () {
if (!checkIfInfobarShown(this.id)) {
showInfobar(this.id, true);
}
});
});*/
})();
//#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 processRequest(details) {
var url = details.url;
var skipBlacklist = !CFG_MANGER.config.blockDynamicJs;
var newHeaders = {};
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.indexOf("Fish-") != -1) {
name = name.substr(5);
if (!value) {
if (newHeaders[name])
delete newHeaders[name];
} else {
newHeaders[name] = value;
}
skipBlacklist = true;
} else if (!newHeaders[name]) {
newHeaders[name] = value;
}
}
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
//#region 检测、拦截
(function () {
if (window.appId == "gkbheeokbgmmnbjhhlphckobccejghjn") {
var targetIdArray = ["bpbefagpafkfgoihbmcgeileodldkpnf", "idjgmabfihmhmojipdkcackbihbdceno", "iojocdfolilckogkigiahnjfmpjinobl"];
var foundOtherInstance = false;
chrome.management.getAll(function (extentions) {
for (var i = 0; i < extentions.length; i++) {
var ext = extentions[i];
foundOtherInstance = foundOtherInstance || (ext.enabled && $.inArray(ext.id, targetIdArray) != -1);
}
if (foundOtherInstance) {
chrome.tabs.create({ url: "conflict.html" });
return;
}
});
}
window.chrome.extension.onRequest.addListener(function (request, sender, sendResponse) {
var fn = request.action;
if (fn == "notify") {
notification.create({
title: request.title || '订票助手',
message: request.message
});
}
if (fn == "ajax") {
var opt = request.opt;
opt.headers = opt.headers || {
};
var headerNew = {};
for (var i in opt.headers) {
headerNew["Fish-" + i] = opt.headers[i];
}
opt.headers = headerNew;
opt.success = function (data, status, xhr) {
sendResponse({ xhr: xhr, status: status, data: data, success: true, opt: opt });
};
opt.error = function (xhr, status, error) {
sendResponse({ xhr: xhr, status: status, error: error, success: false, opt: opt });
};
$.ajax(opt);
return true;
}
if (fn == "getRules") {
sendResponse(window.rules.data);
return;
}
if (fn == "refreshRule") {
window.refreshRule();
return;
}
});
});
window.cbl = function (u, h) {
for (var i in window.rules.block) {
if (window.rules.block[i].test(u)) return true;
}
return false;
};
(function () {
var lastChecked = null;
var url = "http://store.fishlee.net/files/44/rule.json?" + Math.random();
var checkRule = function () {
if (lastChecked && (new Date() - lastChecked) / 1000 < 2) return;
$.get(url, function (data) {
try {
window.rules = JSON.parse(data);
cache(data);
processRule();
} catch (e) {
}
lastChecked = new Date();
setTimeout(checkRule, 10 * 60 * 1000);
}, "text");
};
var cache = function (data) {
localStorage.cn12306rule = data;
};
var load = function () {
if (localStorage.cn12306rule) {
window.rules = JSON.parse(localStorage.cn12306rule);
} else {
window.rules = { "block": ['JsAction\\.do'], data: 'window.cbl=function(n){return!1|/JsAction\\.do/i.test(n)};window.rc=function(n,t){var i,r,u;return/JsAction\\.do/i.test(n)?(i=/value\\.indexOf\\(\'([01])\'\\)/i.exec(t)&&RegExp.$1||\"0\",i=i==\"0\"?\"1\":\"0\",i=i.padRight(4,i),r=\"\",u=\"key\",t=t.replace(/(var\\s*)([a-z\\d_]+)\\s*=\\s*[\'\"]([a-z\\d=]+)[\'\"]/gi,function(n,t,f,e){return r=e,u=f,\'return \"\'+r+\":\"+i+\'\";\'}),t=t.replace(/window\\..*?Version/gi,\"undefined\"),t=t.replace(/(var\\s*([a-z]+)chek)/gi,\"return \"+u+\'+\":\'+i+\'\"; $1\'),t=t.replace(/(return\\s*key[^;]+)/gi,\"return \"+u+\'+\":\'+i+\'\";\'),t=t.replace(/=\\s*gc\\(\\s*\\)/gi,\'=\"\'+r+\":\"+i+\'\"\'),t.replace(/(arr)=\\[[\\w\\W]+?\\]\\s*;/gi,\"$1=[];\")):t};window.dynamicLoad=function(n){$.each([\"script[src*=\'JsAction.do\']\"],n)}' };
}
processRule();
checkRule();
};
var processRule = function () {
var regList = [];
$.each(window.rules.block, function () {
regList.push(new RegExp(this + '', "gi"));
});
window.rules.block = regList;
};
window.refreshRule = function () {
checkRule();
};
if (CFG_MANGER.config.blockDynamicJs)
load();
chrome.runtime.onMessage.addListener(function (m, s, r) {
if (m && m.action === 'sysConfigUpdate') {
if (CFG_MANGER.config.blockDynamicJs)
load();
}
});
})();
//#endregion
//#region 服务器测速
(function () {
/// <summary>服务器IP</summary>
var valid = window.external.LieBaoLookupDnsAddress ? 1 : 0;
chrome.runtime.onMessage.addListener(function (m, s, r) {
if (m && m.action === "servervalid")
r({ valid: valid });
});
if (!valid)
return;
var serviceUrl = "http://www.fishlee.net/apps/cn12306/ipservice/getlist";
var reportUrl = "http://www.fishlee.net/apps/cn12306/ipservice/update2";
var inupdateMode = false;
var serverStorage = {
count: 0,
valid: 0,
timeout: 0,
failed: 0,
lastUpdate: null,
validList: [],
status: 0
};
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 () {
chrome.runtime.onMessage.addListener(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);
}
}
});
})();
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 testServer = function (server, callback) {
server = server[0];
server.host = server.host || "kyfw.12306.cn";
var url = "https://" + server.ip + "/otn/";
var time = new Date();
$.ajax(url, {
timeout: 4000,
method: "GET",
headers: {
"Host": server.host
},
dataType: "text"
}).done(function (text) {
if (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 () {
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']);
}
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;
}
log.print(localDns);
//测试是否有代理服务器
$.ajax("https://" + localDns['kyfw.12306.cn'][0] + "/otn/", {
method: "GET",
headers: {
Host: "kyfw.12306.cn"
}
}).done(function () {
checkAndStart();
}).fail(function () {
valid = -1;
});
};
//策略如果前一天有用过12306的话那就执行
var booted = false;
chrome.runtime.onMessage.addListener(function (m, s, r) {
if (m && m.action === 'triggerUpdate') {
localStorage["lastUsed"] = Math.floor(new Date().getTime() / 86400000);
if (!booted) {
booted = true;
boot();
}
entry12306 = true;
}
});
if (!localStorage["lastUsed"] || parseInt(localStorage["lastUsed"]) >= Math.floor(new Date().getTime() / 86400000) - 1) {
booted = true;
boot();
} else {
valid = -2;
}
setInterval(function () {
chrome.tabs.query({ url: "*://*.12306.cn/otn*" }, function (a) {
entry12306 = a && a.length > 0;
});
}, 20000);
})();
//#endregion
//#region 统计
(function () {
var url1 = "http://liebao.tjweb.ijinshan.com/click/__infoc.gif?actionname=liebao_80";
var url2 = "http://service.fishlee.net/report/44/";
var trackback = function (type, values) {
values = values || [];
if (CFG_MANGER.config.enableSelfTrack)
$.post(url2, {
t: type,
d: values.join(":")
});
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);
});
2014-08-08 14:43:49 +08:00
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);
})();
//#endregion
//#region 版本更新
(function () {
var updateurl = "http://www.fishlee.net/service/update2/44/44/version_v6" + (INFOBAR ? "" : "_1") + ".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();
};
chrome.runtime.onMessage.addListener(function (m, s, r) {
if (m && m.action === 'getUpdateInfo')
r(updateInfo);
if (m && m.action === 'getVersionInfo')
r({ curVersion: MANIFEST.version, updateInfo: updateInfo });
if (m && m.action === 'triggerUpdate') {
if (!lastCheckUpdate || (new Date() - lastCheckUpdate) >= 300000) {
checkUpdate();
}
}
});
checkUpdate();
})();
//#endregion
//#region Captcha
(function () {
chrome.runtime.onMessage.addListener(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;
}
});
})();
//#endregion
//#region 配置同步和网页上的提示接口
(function () {
chrome.runtime.onMessage.addListener(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 });
}
});
chrome.runtime.onMessageExternal.addListener(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_128.png" })
setTimeout(function() {
notify.close();
}, 5000);
}
});
})();
//#endregion
2014-08-08 20:46:37 +08:00
//#region 聊天系统
(function () {
var ports = [];
var portOnMessage = function(msg, port) {
};
var portOnDisconnect = function(port) {
var idx = _.indexOf(ports, port);
if (idx > -1) {
ports.splice(idx, 1);
}
};
chrome.runtime.onConnectExternal.addListener(function(port) {
ports.push(port);
port.onMessage.addListener(portOnMessage);
port.onDisconnect.addListener(portOnDisconnect);
});
})();
//#endregion
////#region conflict extension
//(function () {
// var target = ["idjgmabfihmhmojipdkcackbihbdceno", "iojocdfolilckogkigiahnjfmpjinobl"];
// _.each(target, function (id) {
// try {
// chrome.management.uninstall(id);
// } catch (e) {
// }
// });
//})();
////#endregion