2014-08-08 14:33:43 +08:00
|
|
|
|
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",
|
2014-08-08 14:33:43 +08:00
|
|
|
|
//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" };
|
2014-08-08 14:33:43 +08:00
|
|
|
|
}) || 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 }
|
2014-08-08 14:33:43 +08:00
|
|
|
|
);
|
|
|
|
|
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);
|
|
|
|
|
});
|
2014-08-08 14:33:43 +08:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
2014-08-08 14:33:43 +08:00
|
|
|
|
////#region conflict extension
|
|
|
|
|
|
|
|
|
|
//(function () {
|
|
|
|
|
// var target = ["idjgmabfihmhmojipdkcackbihbdceno", "iojocdfolilckogkigiahnjfmpjinobl"];
|
|
|
|
|
|
|
|
|
|
// _.each(target, function (id) {
|
|
|
|
|
// try {
|
|
|
|
|
// chrome.management.uninstall(id);
|
|
|
|
|
// } catch (e) {
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
//})();
|
|
|
|
|
|
|
|
|
|
////#endregion
|
|
|
|
|
|