文件路径 F:\Users\venus\AppData\Local\liebao\User Data\Default\Extensions\iojocdfolilckogkigiahnjfmpjinobl\4.3.3_0
本地安装的猎豹浏览器版本为:4.3.3_0
manifest.json :
{
"content_scripts": [ {
"all_frames": true,
"exclude_globs": [ ],
"exclude_matches": [ ],
"include_globs": [ ],
"js": [ "12306_ticket_helper.user.js" ],
"matches": [ "http://dynamic.12306.cn/otsweb/*", "https://dynamic.12306.cn/otsweb/*", "https://www.12306.cn/*" ],
"run_at": "document_idle"
} ],
"content_security_policy": "script-src 'self' https://github.com; object-src 'self';",
"converted_from_user_script": true,
"description": "\u5E2E\u60A8\u8BA2\u7968\u7684\u5C0F\u52A9\u624B by \u6728\u9C7C :-)",
"homepage_url": "http://www.fishlee.net/",
"icons": {
"16": "icons/icon_16.png",
"32": "icons/icon_32.png",
"48": "icons/icon_48.png"
},
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8B5NJl8hQY93eC7Mzpb6zk/aJ8ZlZH6zFGXuZ5HzQIup6pR4du8F4Mt6Y0Dq22IRrFG5lSK5mmTApcgYrCrYMW23jkdsVAy9KnQers4CvIPqNYKl77JnIpg6+a4c+hvjLA3m5Q+R2Pum/ubg4ykrSnfWgIsA3V6uJ1IkcRsDnbQIDAQAB",
"manifest_version": 2,
"name": "12306 \u8BA2\u7968\u52A9\u624B (\u730E\u8C79\u6D4F\u89C8\u5668\u4E13\u7248)",
"permissions": [ "http://www.12306.cn/", "https://*.12306.cn/*", "notifications" ],
"update_url": "http://www.fishlee.net/service/update/44/update_liebao.xml",
"version": "4.3.3"
}
12306_ticket_helper.user.js:
//=======START=======
var version = "4.3.3";
var updates = [
"为了保证大家订票安全,临时和谐了所有和提交订单有关系的功能",
"其它更新了什么?你懂的"
];
var faqUrl = "http://www.fishlee.net/soft/44/faq.html";
//标记
var utility_emabed = false;
//#region -----------------UI界面--------------------------
function initUIDisplay() {
injectStyle();
}
/**
* 将使用的样式加入到当前页面中
*/
function injectStyle() {
var s = document.createElement("style");
s.id = "12306_ticket_helper";
s.type = "text/css";
s.textContent = ".fish_running, .fish_clock, .fish_error, .fish_ok {\
line-height:20px;\
text-indent:18px;\
background-repeat:no-repeat;\
background-position:2px 50%;\
font-size:12px;\
}\
.fish_running{background-image:url(data:image/gif;base64,R0lGODlhEAAQALMPAHp6evf394qKiry8vJOTk83NzYKCgubm5t7e3qysrMXFxe7u7pubm7S0tKOjo////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCAAPACwAAAAAEAAQAAAETPDJSau9NRDAgWxDYGmdZADCkQnlU7CCOA3oNgXsQG2FRhUAAoWDIU6MGeSDR0m4ghRa7JjIUXCogqQzpRxYhi2HILsOGuJxGcNuTyIAIfkECQgADwAsAAAAABAAEAAABGLwSXmMmjhLAQjSWDAYQHmAz8GVQPIESxZwggIYS0AIATYAvAdh8OIQJwRAQbJkdjAlUCA6KfU0VEmyGWgWnpNfcEAoAo6SmWtBUtCuk9gjwQKeQAeWYQAHIZICKBoKBncTEQAh+QQJCAAPACwAAAAAEAAQAAAEWvDJORejGCtQsgwDAQAGGWSHMK7jgAWq0CGj0VEDIJxPnvAU0a13eAQKrsnI81gqAZ6AUzIonA7JRwFAyAQSgCQsjCmUAIhjDEhlrQTFV+lMGLApWwUzw1jsIwAh+QQJCAAPACwAAAAAEAAQAAAETvDJSau9L4QaBgEAMWgEQh0CqALCZ0pBKhRSkYLvM7Ab/OGThoE2+QExyAdiuexhVglKwdCgqKKTGGBgBc00Np7VcVsJDpVo5ydyJt/wCAAh+QQJCAAPACwAAAAAEAAQAAAEWvDJSau9OAwCABnBtQhdCQjHlQhFWJBCOKWPLAXk8KQIkCwWBcAgMDw4Q5CkgOwohCVCYTIwdAgPolVhWSQAiN1jcLLVQrQbrBV4EcySA8l0Alo0yA8cw+9TIgAh+QQFCAAPACwAAAAAEAAQAAAEWvDJSau9WA4AyAhWMChPwXHCQRUGYARgKQBCzJxAQgXzIC2KFkc1MREoHMTAhwQ0Y5oBgkMhAAqUw8mgWGho0EcCx5DwaAUQrGXATg6zE7bwCQ2sAGZmz7dEAAA7); color: green;}\
.fish_clock{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAG/SURBVHjapJM/S8NQFMVvpaVfoEKojWL9U3DLIqjoooJDu/sFmnQoiIujQz+Aix3a1FUQXIR2UFA6+WeRUhBprERroGTopg6lSeo7iY1pq4sNHPpy3+8c7n0v9XW7XRrl8SFAlmVvbYFpmynOJHzXKkwlphOmxx4oiiL5sbAsi1KpFOVyuWQwGMzEYjEuGo0Sx3E2qOu6oKqqoChKst1u7zO2wNifDrLZLNbJUCgkLy2vEM/zv7araRrd3lxTq9US2WshnU7TGDZM01zwBwKZxaVlCkd4MtmxQDXlyVbvHXtgwMIDrx3Q6XS2Z2bnufDEJJkWuWIt2/LWwICFxw0wDCM+PTPXB0K4IGiwDhYeeP3fHQjjXIQMq3/mev3J/l0fqIOFxxtAxi+fg/rsBOztSE7QVpwpQT2PN6Dy1mgIYX7KNZcvipQ5yA+Fosum1rA93jMo1R6q7oxX50Va20wMzd4TWHi8t3BSvb/T1bpz4qsbf5vBgIXHDWB3+vj58b5fPj9jc9fcex8U9sCAhcc7Au1mDgtN7VU8Oz7SL0un9PbyTBYzQVijhj0wYOFxP2VJkv71Z8rn807AKM+XAAMArp1CsEFrDIIAAAAASUVORK5CYII=); color: blue;}\
.fish_error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJFSURBVHjapJO/T1pRFMe/Dx7ypEXri4lUGUhsHF40hODSpQ61cTH+2HSoZaF1dHSxpU7+Ca04NE7dyuBiapcuLFokTdD4A01awNdBSkAf8ut5zhUoxq3e5OS+nPv5nnvuyfdJpmniPksSBd68aM1pFDMU4xS+ei5GsUHxmSLRJD9+hcx7rVqFZWwMtc3NIGy2Zam31yX19ABdXTdgNuszdd1nptNBlMtviQ0TC0ujg1LgGWNByelctQ4M4G8qhfN4HLmDA6HvpJzq9eJRXx+qlDPz+deUDrd9+i6KoFouazVg2erx4M/uLn5FItGLk5NX/qUliYO+I2o2C4vLBWaYZQ1rRYFyqTQDVXXl02mcb29HbXb7S+/CwjqKRSAaDXlHRqYwOoqdxUUww6zQNApUSqVxuaMDF8kk2hTlgxYIHMMwaHSxEB2/a4g7u7sjzDDLmn8dXF35ZJsNVWrzycTEOtxuYH//lpjWezqbZoZZ1rQ+AXyj3eEQO7a27oj9s7OhVkZoWjqIFXUdD1QVub29L3fEk5MhXF7y2RwzzLKmdQYb+UwGiqLwO6duiVdWxM2GrvfTfOaZYZY1TScmvE7NKsvf3B6PyzE8jB9ra6DJR2TTnBYXSNIcbfN021Mjl8Pv09OzaqXyXIvnE6LAT00RRlLa21cfk1kesgNpULBab5xITiUHokADzJDJioYhjDSUKNafUKlgaHAwXCCHJQ8Pz1JHRyhQm2RhEfzNOT5jhlnWNJ+w0y/918/kPzbrf+M91rUAAwCuQDz94e2kLwAAAABJRU5ErkJggg==); color: blue;}\
.fish_ok{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHsSURBVHjapFNBSBtBFH2xgoqmKipEC6XkYqhUWXOxUAQhpyJ4Wgi0l0rNsdBbL/WgF2/eV8hNSBF68uhFkOrFhCAGS8mWgmYjG9lCKVGTuP1vsrvuIac68HZm/n/vz5/9fyKu6+IhI8IA5k4kbHsuSAsWBZpnKwh2BTlBySfGdTmcAX7kOJc5r5hfhyw7/86t21/EVVbgmjb6yPG4SqsyONtWGaz0Dk8aYzMf0R+b65ju3+oR7OImrp3vGdluJd646KKj1ZK0H0XXRqfeo390Emg6HUEfOeQqjQwVoNFAOvpkPjYw8kw2NRgfFtQchm8jh1xqggDNJhYHY3Jy41IhmXodrDvZyKWG2m4vA23gcR9wa6m7Jue1YO2PsI1casIB5GPBWM8ilZLyvFzu+BPNwyz29oDM5+W2JhSg8NsqaRSTMHycxfg4MDHRJlUqgCWHO/IvyRGu0gQB5D671Z+mlpiZFXEejjSInrw/OS4wjiWwNFx8ehZnRVNpwlXI/SrXqvbFOfS3TxWRAtNpwxfTRw651AQZSE1Lrfrd6mmhZky96IGejuJgX5rL9HpbrvBKbHbFxunJDa6F67e0X0YsLWHr6uouc/StXi3m/yCRkNTjbXBNG33kkEtN8Jh2Pv3fY9I3vLfwkPFPgAEApRUigcIVl3AAAAAASUVORK5CYII=); color: purple;}\
.outerbox{border:5px solid #EAE3F7;}\
.box{border:1px solid #6E41C2;color:#444;margin:auto;}\
.box .title{padding:5px;line-height:20px;background-color:#B59DE2;color:#fff;}\
.box .title a {color:white;}\
.box .content{padding:5px;background-color:#fff;}\
.box table{border-collapse:collapse; width:98%;}\
.box table td{padding:5px;}\
.box input[type=button],.fish_button {padding:5px;}\
.box .name ,.box .caption,.box .caption td { background-color:#EAE3F7; font-weight:bold;-webkit-transition:all linear 0.2s;-moz-transition:all linear 0.2s;}\
.fish_sep td {border-top:1px solid #A688DD;}\
.lineButton { cursor:pointer; border: 1px solid green; border-radius:3px; font-size:12px; line-height: 16px; padding:3px; backround-color: lightgreen; color: green;-webkit-transition:all linear 0.2s;-moz-transition:all linear 0.2s;}\
.lineButton:hover { color: white; background-color: green;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s; }\
.fishTab {border: 5px solid #E5D9EC;font-size: 12px;}\
.fishTab .innerTab {border-width: 1px;border-style: solid;border-color: #C7AED5;background-color: #fff;}\
.fishTab .tabNav {font-weight:bold;color:#F5F1F8;background-color: #C7AED5;line-height:25px;overflow:hidden;margin:0px;padding:0px;}\
.fishTab .tabNav li {float:left;list-style:none;cursor:pointer;padding-left: 20px;padding-right: 20px;}\
.fishTab .tabNav li:hover {background-color:#DACAE3;}\
.fishTab .tabNav li.current {background-color:#fff;color: #000;}\
.fishTab .tabContent {padding:5px;display:none;}\
.fishTab .tabContent p{margin:10px 0px 10px 0px;}\
.fishTab div.current {display:block;}\
.fishTab div.control {text-align:center;line-height:25px;background-color:#F0EAF4;}\
.fishTab input[type=button] { padding: 5px; }\
.hide {display:none;}\
.fish_button {background-color:#7077DA;font-size:12px; font-family:微软雅黑; color:#fff; border: 1px solid #7077DA;margin-left:5px;margin-right:5px;-webkit-transition:all linear 0.2s;-moz-transition:all linear 0.2s;border-radius:3px;font-size:12px;}\
.fish_button:hover{background:#fff;color:#7077DA;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s;cursor:pointer;}\
tr.steps td{background-color:#E8B7C2!important;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s;}\
tr.stepsok td{background-color:#BDE5BD!important;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s;}\
tr.steps span.indicator {display:inline-block!important;}\
tr.stepsok span.indicator {display:inline-block!important;}\
.highlightrow td { background-color:#D0C0ED!important; color:red; }\
#randCodeTxt{ font-weight: bold; font-size: 18px; text-align: center; padding: 3px 10px 3px 10px; font-family: verdana!important; text-transform: uppercase; }";
document.head.appendChild(s);
}
function injectDom() {
var html = [];
html.push('<div id="fishOption" style="width: 600px; display:none; box-shadow: 7px 7px 10px #A67EBC;">');
html.push('<div class="innerTab">');
html.push('<ul class="tabNav" default="tabVersion">');
html.push('<li tab="tabLogin">常规设置</li>');
html.push('<li tab="tabReg">注册</li>');
html.push('<li tab="tabFaq">常见问题</li>');
html.push('<li tab="tabVersion">版本信息</li>');
html.push('<li tab="tabLog">运行日志</li>');
html.push('<li tab="tabLoginIE">登录到IE</li>');//获取登录到IE的代码 Add By XPHelper
html.push('</ul>');
html.push('<div class="tabContent tabLogin">');
html.push('<table>');
html.push('<tr>');
html.push('<td>重试时间 ');
html.push('<td>');
html.push('<td><input type="text" name="login.retryLimit" size="6" value="2000" />');
html.push('(ms)</td>');
html.push('<td>');
html.push('</td>');
html.push('<td></td>');
html.push('</tr>');
html.push('</table>');
html.push('</div>');
html.push('<div class="tabContent tabReg" style="text-indent: 20px">');
html.push('<p>为了阻止地球人他喵地拿作者无偿奉献的助手去卖钱钱,请注册唷。<strong>完全免费申请</strong>。</p>');
html.push('<p style="color: red;"> <strong style="font-size:16px;">啊嘞……看这里!本助手完全免费啊诸位大人!</strong>任何在第三方网站上出售的软件全他喵的是侵权出售啊!!看到的时候请亲务必记得退款退货打差评向青天大老爷举报啊!!</p>');
html.push('<p style="color:purple;"> 回家是一个单纯而简单的心愿,希望我们不会变得太复杂……</p>');
html.push('<p>任何版本之间,功能上没有任何区别,So……不要问作者万一资助的话会有神马新功能,木有的说…… (= ̄ω ̄=) </p>');
html.push('<p class="registered" style="display:none;">很高兴认识你,,<strong>[email protected]</strong>,谢谢你的出现~~~~已注册版本:<strong>正式版</strong>【<a href="javascript:;" id="unReg">重新注册</a>】</p>');
html.push('<table class="regTable" style="display:none;width:98%;">');
html.push('<tr>');
html.push('<td>请粘贴注册码 【<a href="http://www.fishlee.net/Apps/Cn12306/GetNormalRegKey?v=1" target="_blank" style="color:blue;font-weight:bold;text-decoration:underline;">戳我直接申请注册码啊!为什么你们舍不得戳我啊 ╮(╯▽╰)╭</a>】</td>');
html.push('</tr><tr>');
html.push('<td style="text-align:center;"><textarea id="regContent" style="width:98%; height:50px;"></textarea></td>');
html.push('</tr><tr>');
html.push('<td><input type="button" id="regButton" value="注册" /></td>');
html.push('</tr>');
html.push('</table>');
html.push('</div>');
html.push('<div class="tabContent tabVersion" style="text-indent: 20px">');
html.push('<h4 style="font-size:18px; font-weight:bold; margin: 0px; line-height: 26px; border-bottom: 1px dotted #ccc;">12306 订票助手 (猎豹浏览器专版) <small>ver ' + window.helperVersion + '</small></h4>');
html.push('<p> 12306 订票助手(猎豹浏览器专版)是一款用于订票的助手软件,专门为猎豹浏览器定制,无需注册。希望在快速的猎豹浏览器的支持下,诸位客官能用得更加顺手 =。= <strong>助手完全免费,无需付费使用,仅接受捐助。</strong> </p>');
html.push('<p style="color: red;"> <strong style="font-size:16px;">啊嘞……看这里!本助手完全免费啊诸位大人!猎豹浏览器也是免费的啊!!</strong>任何在第三方网站上打包出售的软件全他喵的是侵权出售啊!!看到的时候请亲务必记得退款退货打差评向青天大老爷举报啊!!</p>');
html.push('<p style="color:purple;"> 回家是一个单纯而简单的心愿,希望我们不会变得太复杂……</p>');
html.push('<p> 有很多朋友资助作者,正在木有暖气的南方饱受煎熬的作者感激涕零 ≥ω≤。<a href="http://www.fishlee.net/soft/44/donate.html" target="_blank">戳这里了解捐助详情</a>。 </p>');
html.push('<p style="color: blue;"> <strong style="">那个,诸位票贩子们,放过本助手吧!!你们都去用什么自动识别验证码的好啦!还有铁道部的爷爷们,拜托你们改进下的用户体验吧!你们的订票足够好用的话虽还来用脚本啊!!!!</strong></p>');
html.push('<p style="font-weight:bold;">当前版本更新内容</p>');
html.push('<ol>');
$.each(utility.getPref("updates").split('\t'), function (i, n) {
html.push("<li style='padding-left:20px;list-style:disc inside;'>" + n + "</li>");
});
html.push('</ol>');
html.push('</div>');
html.push('<div class="tabContent tabFaq">');
html.push('<table>');
html.push('<tr>');
html.push('<td colspan="4"> 你在订票过程中可能……会遇到各种问题,由于介个12306网站本身呢……木有没有任何介绍 ╮(╯▽╰)╭ ,所以老衲整理了相关问题,供客官参考。如果还有不明白的问题,加群讨论呗 (= ̄ω ̄=) 。 <br /><br />');
html.push('1.放票非正点也,So在将近放票的时候,务必保持刷新状态哈,而且……当整点没有放票时,不要放弃继续刷新喔;<br />\
2.动车都是11点放票撒,切记切记;<br />\
3.第一波放票悲催地木有订到时,请耐心等待,因为现在放票有N多节点,随时会有票出来,晚很久才放票也正常,铁老大经常秀下限嘀;<br />\
4.如果您的车票很难买,请尽量发动你的七大姑八大姨神马的一堆朋友过来集体帮忙,同时建议用多个浏览器刷票,因为缓存的关系不同的浏览器出现票的时间可能不同;<br />\
5.最新版3.9.0中的预先选择铺位功能有点淡化了……要用的话,使用优选席别,第一个优选的将会被自动选中 ^_^<br />\
<br />\
好了,废话说完鸟,祝大家买票顺利,贫僧只希望不会帮倒忙就好了 ╮(╯▽╰)╭<br />\
如果您还有问题的话,<a href="http://www.fishlee.net/soft/44/tour.html" target="_blank">建议点击这里查看教程~~~~</a>\
');
html.push('</td></tr>');
html.push('<tr style="display:none;">');
html.push('<td><a href="http://www.fishlee.net/soft/44/12306faq.html" target="_blank">订票常见问题</a></td>');
html.push('<td><a href="http://www.fishlee.net/soft/44/faq.html" target="_blank">助手运行常见问题</a></td>');
html.push('</tr>');
html.push('</table>');
html.push('</div><div class="tabLog tabContent"><div>下面是当前页面的记录。如果您的助手遇到功能上的问题,请全部复制后发成邮件给作者:[email protected] 以便于老衲解决问题。<span style="color:red;font-weight:bold;">请在发送前务必剔除记录中包含的个人隐私如密码等信息。</span></div><textarea id="runningLog" style="width:100%;height:200px;"></textarea></div>');
//获取登录到IE的代码 Add By XPHelper
html.push('<div class="tabLoginIE tabContent"><div><strong>先在IE中打开 https://dynamic.12306.cn/otsweb,</strong>再将以下代码复制到IE浏览器的地址栏。确认地址栏最前面有“javascript:”字样,没有请手动加上(IE10会自动删除这样的代码),然后敲回车,等待页面刷新后,即可自动登录。</div><textarea id="LoginIECode" style="width:100%;height:200px;"></textarea></div>');
html.push('<div class="control">');
html.push('<input type="button" class="close_button" value="关闭" />');
html.push('</div>');
html.push('</div>');
html.push('</div>');
$("body").append(html.join(""));
var opt = $("#fishOption");
$("#regButton").click(function () {
var sn = $.trim($("#regContent").val());
var rt = utility.verifySn(false, "", sn);
if (rt.result != 0) {
alert("很抱歉, 注册失败. 代码 " + rt.result + ", " + rt.msg);
} else {
utility.setSnInfo("", sn);
alert("注册成功, 请刷新浏览器。\n注册给 - " + rt.name + " , 注册类型 - " + rt.typeDesc.replace(/<[^>]*>/gi, ""));
try {
utility.getTopWindow().location.reload();
} catch (e) {
alert("权限不足无法刷新页面, 请手动刷新当前页!");
}
}
});
$("#unReg, a.reSignHelper").live("click", function () {
if (utility.regInfo.result == 0) {
if (!confirm("确定要重新注册吗?")) return;
utility.setSnInfo("", "");
utility.getTopWindow().location.reload();
} else {
utility.getTopWindow().utility.showOptionDialog("tabReg");
}
});
//初始化设置
utility.configTab = utility.fishTab(opt);
opt.find("input[name]").each(function () {
var el = $(this);
var key = el.attr("name");
var value = window.localStorage.getItem(key);
if (!value) return;
if (el.attr("type") == "checkbox") {
el.attr("checked", value == "1");
} else {
el.val(value);
}
}).change(function () {
var el = $(this);
var key = el.attr("name");
if (el.attr("type") == "checkbox") {
window.localStorage.setItem(key, el[0].checked ? 1 : 0);
} else {
window.localStorage.setItem(key, el.val());
}
});
$("#configLink, .configLink").live("click", function () {
var el = $(this);
var dp = el.attr("tab");
utility.getTopWindow().utility.showLoginIE();
utility.getTopWindow().utility.showOptionDialog(dp || "");
});
//新版本更新显示提示
if (utility.getPref("helperVersion") != window.helperVersion) {
//检测老版本设置
if (utility.getAudioUrl().indexOf("github") != -1 || utility.getAudioUrl().indexOf("resbak.") != -1) {
utility.resetAudioUrl();
}
utility.setPref("helperVersion", window.helperVersion);
//仅顶层页面显示
try {
if (parent == self)
utility.showOptionDialog("tabVersion");
} catch (ex) {
//跨域了,也是顶级
utility.showOptionDialog("tabVersion");
}
}
//注册
var result = utility.verifySn(true);
if (result.result == 0) {
var info = opt.find(".registered").show().find("strong");
info.eq(0).html(result.name);
info.eq(1).html(result.typeDesc);
} else {
opt.find(".regTable").show();
}
utility.regInfo = result;
}
//#endregion
//#region -----------------执行环境兼容----------------------
var utility = {
configTab: null,
icon: "http://www.12306.cn/mormhweb/images/favicon.ico",
notifyObj: null,
timerObj: null,
regInfo: null,
isWebKit: function () {
return navigator.userAgent.indexOf("WebKit") != -1;
},
trim: function (data) {
if (typeof ($) != 'undefined') return $.trim(data);
return data.replace(/(^\s+|\s+$)/g, "");
},
getTopWindow: function () {
try {
if (parent == self) return self;
else return parent.window.utility.getTopWindow();
} catch (e) {
//跨域的话,也是顶层
return self;
}
},
init: function () {
$.extend({
any: function (array, callback) {
var flag = false;
$.each(array, function (i, v) {
flag = callback.call(this, i, v);
if (flag) return false;
});
return flag;
},
first: function (array, callback) {
var result = null;
$.each(array, function (i, v) {
result = callback.call(this, i, v);
if (result) return false;
});
return result;
}
});
(function (n) { var t = /["\\\x00-\x1f\x7f-\x9f]/g, i = { "\b": "\\b", "\t": "\\t", "\n": "\\n", "\f": "\\f", "\r": "\\r", '"': '\\"', "\\": "\\\\" }, r = Object.prototype.hasOwnProperty; n.toJSON = typeof JSON == "object" && JSON.stringify ? JSON.stringify : function (t) { var i, a, l, v, p, y, f; if (t === null) return "null"; if (i = typeof t, i === "undefined") return undefined; if (i === "number" || i === "boolean") return "" + t; if (i === "string") return n.quoteString(t); if (i === "object") { if (typeof t.toJSON == "function") return n.toJSON(t.toJSON()); if (t.constructor === Date) { var e = t.getUTCMonth() + 1, o = t.getUTCDate(), w = t.getUTCFullYear(), s = t.getUTCHours(), h = t.getUTCMinutes(), c = t.getUTCSeconds(), u = t.getUTCMilliseconds(); return e < 10 && (e = "0" + e), o < 10 && (o = "0" + o), s < 10 && (s = "0" + s), h < 10 && (h = "0" + h), c < 10 && (c = "0" + c), u < 100 && (u = "0" + u), u < 10 && (u = "0" + u), '"' + w + "-" + e + "-" + o + "T" + s + ":" + h + ":" + c + "." + u + 'Z"' } if (t.constructor === Array) { for (a = [], l = 0; l < t.length; l++) a.push(n.toJSON(t[l]) || "null"); return "[" + a.join(",") + "]" } y = []; for (f in t) if (r.call(t, f)) { if (i = typeof f, i === "number") v = '"' + f + '"'; else if (i === "string") v = n.quoteString(f); else continue; (i = typeof t[f], i !== "function" && i !== "undefined") && (p = n.toJSON(t[f]), y.push(v + ":" + p)) } return "{" + y.join(",") + "}" } }, n.evalJSON = typeof JSON == "object" && JSON.parse ? JSON.parse : function (src) { return eval("(" + src + ")") }, n.secureEvalJSON = typeof JSON == "object" && JSON.parse ? JSON.parse : function (src) { var filtered = src.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""); if (/^[\],:{}\s]*$/.test(filtered)) return eval("(" + src + ")"); throw new SyntaxError("Error parsing JSON, source is not valid."); }, n.quoteString = function (n) { return n.match(t) ? '"' + n.replace(t, function (n) { var t = i[n]; return typeof t == "string" ? t : (t = n.charCodeAt(), "\\u00" + Math.floor(t / 16).toString(16) + (t % 16).toString(16)) }) + '"' : '"' + n + '"' } })(jQuery)
},
runningQueue: null,
appendLog: function (settings) {
/// <summary>记录日志</summary>
if (!utility.runningQueue) utility.runningQueue = [];
var log = { url: settings.url, data: settings.data, response: null, success: null };
if (log.url.indexOf("Passenger") != -1) return; //不记录对乘客的请求
utility.runningQueue.push(log);
settings.log = log;
},
showLog: function () {
if (!utility.runningQueue) {
alert("当前页面尚未产生日志记录。");
return;
}
var log = [];
$.each(utility.runningQueue, function () {
log.push("成功:" + (this.success ? "是" : "否") + "\r\n地址:" + this.url + "\r\n提交数据:" + utility.formatData(this.data) + "\r\n返回数据:" + utility.formatData(this.response));
});
$("#runningLog").val(log.join("\r\n----------------------------------\r\n"));
utility.showOptionDialog("tabLog");
},
//获取登录到IE的代码 Add By XPHelper
showLoginIE: function () {
var strCookie = document.cookie;
var arrCookie = strCookie.split("; ");
var IECode = "javascript:";
var cookie = [];
for (var i = 0; i < arrCookie.length; i++) {
var arr = arrCookie[i].split("=");
if (arr.length < 2 || arr[0].indexOf("helper.") != -1) continue;
cookie.push("document.cookie=\"" + arr[0] + "=" + arr[1] + "\";");
}
IECode += cookie.join("");
IECode += "self.location.reload();";
$("#LoginIECode").val(IECode);
},
formatData: function (data) {
if (!data) return "(null)";
if (typeof (data) == "string") return data;
var html = [];
for (var i in data) {
html.push('"' + i + '":\"' + (this[i] + "").replace(/(\r|\n|")/g, function (a) { "\\" + a; }) + '\"');
}
return "{" + html.join(",") + "}";
},
notify: function (msg, timeout) {
console.log("信息提示: " + msg);
if (window.webkitNotifications) {
if (window.webkitNotifications.checkPermission() == 0) {
utility.closeNotify();
if (utility.notifyObj == null)
utility.notifyObj = webkitNotifications.createNotification(utility.icon, '订票', msg);
utility.notifyObj.show();
if (!timeout || timeout != 0) utility.timerObj = setTimeout(utility.closeNotify, timeout || 5000);
} else {
alert("【啊喂!!桌面通知还木有开启!请戳界面中的『点击启用桌面通知』按钮来开启!】\n\n" + msg);
}
} else {
if (typeof (GM_notification) != 'undefined') {
GM_notification(msg);
} else {
console.log("主页面中脚本信息, 无法提示, 写入通知区域.");
utility.notifyOnTop(msg);
}
}
},
notifyOnTop: function (msg) {
window.localStorage.setItem("notify", msg);
},
closeNotify: function () {
if (!utility.notifyObj) return;
utility.notifyObj.cancel();
if (utility.timerObj) {
clearTimeout(utility.timerObj);
}
utility.timerObj = null;
utility.notifyObj = null;
},
setPref: function (name, value) {
window.localStorage.setItem(name, value);
},
getPref: function (name) {
return window.localStorage.getItem(name);
},
unsafeCallback: function (callback) {
if (typeof (unsafeInvoke) == "undefined") callback();
else unsafeInvoke(callback);
},
getTimeInfo: function () {
var d = new Date();
return d.getHours() + ":" + (d.getMinutes() < 10 ? "0" : "") + d.getMinutes() + ":" + (d.getSeconds() < 10 ? "0" : "") + d.getSeconds();
},
savePrefs: function (obj, prefix) {
var objs = obj.find("input");
objs.change(function () {
var type = this.getAttribute("type");
if (type == "text") utility.setPref(prefix + "_" + this.getAttribute("id"), $(this).val());
else if (type == "checkbox") utility.setPref(prefix + "_" + this.getAttribute("id"), this.checked ? 1 : 0);
})
},
reloadPrefs: function (obj, prefix) {
var objs = obj.find("input");
prefix = prefix || "";
objs.each(function () {
var e = $(this);
var type = e.attr("type");
var id = e.attr("id");
var value = utility.getPref(prefix + "_" + id);
if (typeof (value) == "undefined" || value == null) return;
if (type == "text") e.val(value);
else if (type == "checkbox") this.checked = value == "1";
e.change();
});
utility.savePrefs(obj, prefix);
},
getErrorMsg: function (msg) {
/// <summary>获得给定信息中的错误信息</summary>
var m = msg.match(/var\s+message\s*=\s*"([^"]*)/);
return m && m[1] ? m[1] : "<未知信息>";
},
delayInvoke: function (target, callback, timeout) {
target = target || "#countEle";
var e = typeof (target) == "string" ? $(target) : target;
if (timeout <= 0) {
e.html("正在执行").removeClass("fish_clock").addClass("fish_running");
callback();
} else {
var str = (Math.floor(timeout / 100) / 10) + '';
if (str.indexOf(".") == -1) str += ".0";
e.html(str + " 秒后再来!...").removeClass("fish_running").addClass("fish_clock");
setTimeout(function () {
utility.delayInvoke(target, callback, timeout - 500);
}, 500);
}
},
saveList: function (name) {
/// <summary>将指定列表的值保存到配置中</summary>
var dom = document.getElementById(name);
window.localStorage["list_" + name] = utility.getOptionArray(dom).join("\t");
},
loadList: function (name) {
/// <summary>将指定的列表的值从配置中加载</summary>
var dom = document.getElementById(name);
var data = window.localStorage["list_" + name];
if (!data) return;
if (data.indexOf("\t") != -1)
data = data.split('\t');
else data = data.split('|');
$.each(data, function () {
dom.options[dom.options.length] = new Option(this, this);
});
},
addOption: function (dom, text, value) {
/// <summary>在指定的列表中加入新的选项</summary>
dom.options[dom.options.length] = new Option(text, value);
},
getOptionArray: function (dom) {
/// <summary>获得选项的数组格式</summary>
return $.map(dom.options, function (o) { return o.value; });
},
inOptionList: function (dom, value) {
/// <summary>判断指定的值是否在列表中</summary>
for (var i = 0; i < dom.options.length; i++) {
if (dom.options[i].value == value) return true;
}
return false;
},
getAudioUrl: function () {
/// <summary>获得音乐地址</summary>
return window.localStorage["audioUrl"] || (navigator.userAgent.indexOf("Firefox") != -1 ? "http://static.liebao.cn/resources/audio/song.ogg" : "http://static.liebao.cn/resources/audio/song.ogg");
},
getFailAudioUrl: function () {
return (utility.isWebKit() ? "http://static.liebao.cn/resources/audio/" : "http://static.liebao.cn/resources/audio/") + "music3.ogg";
},
playFailAudio: function () {
if (!window.Audio) return;
new Audio(utility.getFailAudioUrl()).play()
},
resetAudioUrl: function () {
/// <summary>恢复音乐地址为默认</summary>
window.localStorage.removeItem("audioUrl");
},
parseDate: function (s) { /(\d{4})[-/](\d{1,2})[-/](\d{1,2})/.exec(s); return new Date(RegExp.$1, RegExp.$2 - 1, RegExp.$3); },
getDate: function (s) {
/// <summary>获得指定日期的天单位</summary>
return new Date(s.getFullYear(), s.getMonth(), s.getDate());
},
formatDate: function (d) {
/// <summary>格式化日期</summary>
var y = d.getFullYear();
return y + "-" + utility.formatDateShort(d);
},
formatDateShort: function (d) {
/// <summary>格式化日期</summary>
var mm = d.getMonth() + 1;
var d = d.getDate();
return (mm > 9 ? mm : "0" + mm) + "-" + (d > 9 ? d : "0" + d);
},
formatTime: function (d) {
function padTo2Digit(digit) {
return digit < 10 ? '0' + digit : digit;
}
return utility.formatDate(d) + " " + padTo2Digit(d.getHours()) + ":" + padTo2Digit(d.getMinutes()) + ":" + padTo2Digit(d.getSeconds());
},
addTimeSpan: function (date, y, mm, d, h, m, s) {
/// <summary>对指定的日期进行偏移</summary>
return new Date(date.getFullYear() + y, date.getMonth() + mm, date.getDate() + d, date.getHours() + h, date.getMinutes() + m, date.getSeconds() + s);
},
serializeForm: function (form) {
/// <summary>序列化表单为对象</summary>
var v = {};
var o = form.serializeArray();
for (var i in o) {
if (typeof (v[o[i].name]) == 'undefined') v[o[i].name] = o[i].value;
else v[o[i].name] += "," + o[i].value;
}
return v;
},
getSecondInfo: function (second) {
var show_time = "";
var hour = parseInt(second / 3600); //时
if (hour > 0) {
show_time = hour + "小时";
second = second % 3600;
}
var minute = parseInt(second / 60); //分
if (minute >= 1) {
show_time = show_time + minute + "分";
second = second % 60;
} else if (hour >= 1 && second > 0) {
show_time = show_time + "0分";
}
if (second > 0) {
show_time = show_time + second + "秒";
}
return show_time;
},
post: function (url, data, dataType, succCallback, errorCallback) {
$.ajax({
url: url,
data: data,
timeout: 10000,
type: "POST",
success: succCallback,
error: errorCallback,
dataType: dataType
});
},
get: function (url, data, dataType, succCallback, errorCallback) {
$.ajax({
url: url,
data: data,
timeout: 10000,
type: "GET",
success: succCallback,
error: errorCallback,
dataType: dataType
});
},
showDialog: function (object, optx) {
/// <summary>显示对话框。其中带有 close_button 样式的控件会自动作为关闭按钮</summary>
return (function (opt) {
var dataKey = "fs_dlg_opt";
if (this.data(dataKey)) {
//this.data(dataKey).closeDialog();
return;
}
opt = $.extend({ bindControl: null, removeDialog: this.attr("autoCreate") == "1", onClose: null, animationMove: 20, speed: "fast", fx: "linear", show: "fadeInDown", hide: "fadeOutUp", onShow: null, timeOut: 0 }, opt);
this.data("fs_dlg_opt", opt);
var top = "0px";
var left = "50%";
this.css({
"position": opt.parent ? "absolute" : "fixed",
"left": left,
"top": top,
"margin-left": "-" + (this.width() / 2) + "px",
"margin-top": "0px",
"z-index": "9999"
});
var obj = this;
this.changeLoadingIcon = function (icon) {
/// <summary>更改加载对话框的图标</summary>
obj.removeClass().addClass("loadingDialog loadicon_" + (icon || "tip"));
return obj;
};
this.autoCloseDialog = function (timeout) {
/// <summary>设置当前对话框在指定时间后自动关闭</summary>
setTimeout(function () { obj.closeDialog(); }, timeout || 2500);
return obj;
};
this.setLoadingMessage = function (msgHtml) {
obj.find("div").html(msgHtml);
return obj;
};
this.closeDialog = function () {
/// <summary>关闭对话框</summary>
obj.removeData(dataKey);
obj.animate({ "marginTop": "+=" + opt.animationMove + "px", "opacity": "hide" }, opt.speed, opt.fx, function () {
if (opt.bindControl) opt.bindControl.enable();
if (opt.onClose) opt.onClose.call(obj);
if (opt.removeDialog) obj.remove();
})
return obj;
};
$('.close_button', this).unbind("click").click(obj.closeDialog);
//auto close
if (opt.timeOut > 0) {
var handler = opt.onShow;
opt.onShow = function () {
setTimeout(function () { $(obj).closeDialog(); }, opt.timeOut);
if (handler != null) handler.call(this);
};
}
//show it
if (opt.bindControl) opt.bindControl.disable();
this.animate({ "marginTop": "+=" + opt.animationMove + "px", "opacity": "show" }, opt.speed, opt.fx, function () { opt.onShow && opt.onShow.call(obj); })
this.data(dataKey, this);
return this;
}).call(object, optx);
},
fishTab: function (obj, opt) {
return (function (opt) {
var self = this;
opt = $.extend({ switchOnHover: false, switchOnClick: true }, opt);
this.addClass("fishTab");
this.showTab = function (tabid) {
self.find(".current").removeClass("current");
self.find("ul.tabNav li[tab=" + tabid + "], div." + tabid).addClass("current");
};
self.find(".tabNav li").hover(function () {
if (!opt.switchOnHover) return;
self.showTab($(this).attr("tab"));
}).click(function () {
if (!opt.switchOnClick) return;
self.showTab($(this).attr("tab"));
});
this.showTab(self.find(".tabNav").attr("default") || self.find(".tabNav li:eq(0)").attr("tab"));
return this;
}).call(obj, opt);
},
getLoginRetryTime: function () {
return parseInt(window.localStorage.getItem("login.retryLimit")) || 2000;
},
showOptionDialog: function (tab) {
if (tab) utility.configTab.showTab(tab);
utility.showDialog($("#fishOption"));
},
addCookie: function (name, value, expDays) {
var cook = name + "=" + value + "; path=/; domain=.12306.cn";
if (expDays > 0) {
cook += "; expires=" + new Date(new Date().getTime() + expDays * 3600 * 1000 * 24).toGMTString();
}
document.cookie = cook;
},
getCookie: function (name) {
var cook = document.cookie;
var arr = cook.split("; ");
for (var i = 0; i < arr.length; i++) {
var arg = arr[i].split('=');
if (arg[0] == name) return arg[1];
}
},
setSnInfo: function (name, sn) {
utility.setPref("helper.regUser", name);
utility.setPref("helper.regSn", sn);
utility.addCookie("helper.regUser", name, 999);
utility.addCookie("helper.regSn", sn, 999);
},
verifySn: function (skipTimeVerify, name, sn) {
name = name || utility.getPref("helper.regUser") || utility.getCookie("helper.regUser");
sn = sn || utility.getPref("helper.regSn") || utility.getCookie("helper.regSn");
if (!name && sn) return utility.verifySn2(skipTimeVerify, sn);
if (!name || !sn) return { result: -4, msg: "未注册", name: "猎豹浏览器用户", typeDesc: "正式版" };
utility.setSnInfo(name, sn);
var args = sn.split(',');
if (!skipTimeVerify) {
if ((new Date() - args[0]) / 60000 > 5) {
return { result: -1, msg: "序列号注册已失效" };
}
}
var dec = [];
var encKey = args[0] + args[1];
var j = 0;
for (var i = 0; i < args[2].length; i += 4) {
dec.push(String.fromCharCode(parseInt(args[2].substr(i, 4), 16) ^ encKey.charCodeAt(j)));
j++;
if (j >= encKey.length) j = 0;
}
var data = dec.join("");
data = { result: null, type: data.substring(0, 4), name: data.substring(4) };
data.result = data.name == name ? 0 : -3;
data.msg = data.result == 0 ? "成功验证" : "注册无效"
data.typeDesc = data.type == "NRML" ? "正式版" : (data.type == "GROP" ? "内部版, <span style='color:blue;'>感谢您参与我们之中</span>!" : "<span style='color:red;'>捐助版, 非常感谢您的支持</span>!");
return data;
},
verifySn2: function (skipTimeVerify, data) {
data = utility.trim(data);
try {
var nameLen = parseInt(data.substr(0, 2), 16);
var name = data.substr(2, nameLen);
data = data.substring(2 + nameLen);
var arr = [];
for (var i = 0; i < data.length; i++) {
var c = data.charCodeAt(i);
if (c >= 97) arr.push(String.fromCharCode(c - 49));
else arr.push(data.charAt(i));
}
data = arr.join("");
var ticket = parseInt(data.substr(0, 14), 16);
var key = parseInt(data.substr(14, 1), 16);
var encKey = ticket.toString(16).toUpperCase() + key.toString().toUpperCase();
data = data.substring(15);
var dec = [];
var j = 0;
for (var i = 0; i < data.length; i += 4) {
dec.push(String.fromCharCode(parseInt(data.substr(i, 4), 16) ^ encKey.charCodeAt(j)));
j++;
if (j >= encKey.length) j = 0;
}
dec = dec.join("").split('|');
var regVersion = dec[0].substr(0, 4);
var regName = dec[0].substring(4);
var bindAcc = dec.slice(1, dec.length);
if (!bindAcc && !skipTimeVerify && (new Date() - ticket) / 60000 > 5) {
return { result: -1, msg: "注册码已失效, 请重新申请" };
}
if (regName != name) {
return { result: -3, msg: "注册失败,用户名不匹配" };
}
var data = { name: name, type: regVersion, bindAcc: bindAcc, ticket: ticket, result: 0, msg: "成功注册" };
switch (data.type) {
case "NRML": data.typeDesc = "正式版"; break;
case "GROP": data.typeDesc = "内部版, <span style='color:blue;'>感谢您参与我们之中</span>!"; break;
case "DONT": data.typeDesc = "<span style='color:red;'>捐助版, 非常感谢您的支持</span>!"; break;
case "PART": data.typeDesc = "合作版,欢迎您的使用";
}
data.regTime = new Date(ticket);
data.regVersion = 2;
return data;
} catch (e) {
return { result: -4, msg: "数据错误" };
}
},
allPassengers: null,
getAllPassengers: function (callback, ignoreLocalCache) {
if (!utility.allPassengers && window.localStorage["pas"] && !ignoreLocalCache) {
utility.allPassengers = eval("(" + window.localStorage["pas"] + ")");
}
if (utility.allPassengers) {
callback(utility.allPassengers);
return;
}
var tw = utility.getTopWindow();
if (tw != self) return tw.utility.getAllPassengers(callback, ignoreLocalCache);
//开始加载所有乘客
utility.allPassengers = [];
var pageIndex = 0;
function loadPage() {
utility.post("/otsweb/passengerAction.do?method=getPagePassengerAll", { pageSize: 10, pageIndex: pageIndex }, "json", function (json) {
$.each(json.rows, function () { utility.allPassengers.push(this); });
if (utility.allPassengers.length >= json.recordCount) {
callback(utility.allPassengers);
} else {
pageIndex++;
setTimeout(loadPage, 1000);
}
}, function () {
setTimeout(loadPage, 3000);
});
}
loadPage();
},
regCache: {},
getRegCache: function (value) {
return utility.regCache[value] || (utility.regCache[value] = new RegExp("^(" + value + ")$", "i"));
},
preCompileReg: function (optionList) {
var data = $.map(optionList, function (e) {
return e.value;
});
return new RegExp("^(" + data.join("|") + ")$", "i");
},
enableLog: function () {
$("body").append('<button style="width:100px;position:fixed;right:0px;top:0px;height:35px;" onclick="utility.showLog();">显示运行日志</button>');
$(document).ajaxSuccess(function (a, b, c) {
if (!c.log) return;
c.log.response = b.responseText;
c.log.success = true;
}).ajaxSend(function (a, b, c) {
utility.appendLog(c);
}).ajaxError(function (a, b, c) {
if (!c.log) return;
c.log.response = b.responseText;
});
},
//获取登录到IE的代码 Add By XPHelper
enableLoginIE: function () {
$("body").append('<button style="width:150px;position:fixed;right:0px;top:0px;height:35px;" class="configLink" tab="tabLoginIE">获取登录到IE的代码</button>');
},
analyzeForm: function (html) {
var data = {};
//action
var m = /<form.*?action="([^"]+)"/.exec(html);
data.action = m ? RegExp.$1 : "";
//inputs
data.fields = {};
var inputs = html.match(/<input\s*(.|\r|\n)*?>/gi);
$.each(inputs, function () {
if (!/name=['"]([^'"]+?)['"]/.exec(this)) return;
var name = RegExp.$1;
data.fields[RegExp.$1] = !/value=['"]([^'"]+?)['"]/.exec(this) ? "" : RegExp.$1;
});
//tourflag
m = /submit_form_confirm\('confirmPassenger','([a-z]+)'\)/.exec(html);
if (m) data.tourFlag = RegExp.$1;
return data;
},
selectionArea: function (opt) {
var self = this;
this.options = $.extend({ onAdd: function () { }, onRemove: function () { }, onClear: function () { }, onRemoveConfirm: function () { return true; }, syncToStorageKey: "", defaultList: null, preloadList: null }, opt);
this.append('<div style="padding: 5px; border: 1px dashed gray; background-color: rgb(238, 238, 238); width:120px;">(还没有添加任何项)</div>');
this.datalist = [];
this.add = function (data) {
if ($.inArray(data, self.datalist) > -1) return;
var text = typeof (data) == "string" ? data : data.text;
var html = $('<input type="button" class="lineButton" value="' + text + '" title="点击删除" />');
self.append(html);
html.click(self.removeByButton);
self.datalist.push(data);
self.syncToStorage();
self.checkEmpty();
self.options.onAdd.call(self, data, html);
};
this.removeByButton = function () {
var obj = $(this);
var idx = obj.index() - 1;
var value = self.datalist[idx];
if (!self.options.onRemoveConfirm.call(self, value, obj, idx)) {
return;
}
obj.remove();
self.datalist.splice(idx, 1);
self.syncToStorage();
self.checkEmpty();
self.options.onRemove.call(self, value, obj);
};
this.emptyList = function () {
self.datalist = [];
self.find("input").remove();
self.syncToStorage();
self.checkEmpty();
self.options.onClear.call(self);
};
this.isInList = function (data) {
/// <summary>判断指定的值是否在列表中</summary>
return $.inArray($.inArray(data, self.datalist)) > -1;
};
this.isInRegList = function (data) {
/// <summary>判断指定的值是否在列表中。这里假定是字符串,使用正则进行判断</summary>
for (var i = 0; i < self.datalist.length; i++) {
if (utility.getRegCache(self.datalist[i]).test(data)) return true;
}
return false;
};
this.syncToStorage = function () {
if (!self.options.syncToStorageKey) return;
window.localStorage.setItem(self.options.syncToStorageKey, self.datalist.join("\t"));
};
this.checkEmpty = function () {
if (self.find("input").length) {
self.find("div").hide();
} else {
self.find("div").show();
}
};
if (self.options.syncToStorageKey) {
var list = self.options.preloadList;
if (!list) {
var list = window.localStorage.getItem(this.options.syncToStorageKey);
if (!list) list = this.options.defaultList;
else list = list.split('\t');
}
if (list) {
$.each(list, function () { self.add(this + ""); });
}
}
return this;
},
getUpdateUrl: function () {
return "http://static.liebao.cn/_softdownload/12306_ticket_helper_for_liebaobrowser.crx";
}
}
function unsafeInvoke(callback) {
/// <summary>非沙箱模式下的回调</summary>
var cb = document.createElement("script");
cb.type = "text/javascript";
cb.textContent = buildCallback(callback);
document.head.appendChild(cb);
}
function buildCallback(callback) {
var content = "";
if (!utility_emabed) {
content += "window.helperVersion='" + version + "'; if(typeof(window.utility)!='undefined' && navigator.userAgent.indexOf('Maxthon')==-1){ alert('我勒个去! 检测到您似乎同时运行了两只助手! 请转到『附加组件管理『(Firefox)或『扩展管理』(Chrome)中卸载老版本的助手!');}; \r\nwindow.utility=" + buildObjectJavascriptCode(utility) + "; window.utility.init();\r\n";
utility_emabed = true;
}
content += "window.__cb=" + buildObjectJavascriptCode(callback) + ";\r\n\
if(typeof(jQuery)!='undefined')window.__cb();\r\n\
else{\
var script=document.createElement('script');\r\nscript.src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';\r\n\
script.type='text/javascript';\r\n\
script.addEventListener('load', window.__cb);\r\n\
document.head.appendChild(script);\r\n\
}";
return content;
}
function buildObjectJavascriptCode(object) {
/// <summary>将指定的Javascript对象编译为脚本</summary>
if (!object) return null;
var t = typeof (object);
if (t == "string") {
return "\"" + object.replace(/(\r|\n|\\)/gi, function (a, b) {
switch (b) {
case "\r":
return "\\r";
case "\n":
return "\\n";
case "\\":
return "\\\\";
}
}) + "\"";
}
if (t != "object") return object + "";
var code = [];
for (var i in object) {
var obj = object[i];
var objType = typeof (obj);
if ((objType == "object" || objType == "string") && obj) {
code.push(i + ":" + buildObjectJavascriptCode(obj));
} else {
code.push(i + ":" + obj);
}
}
return "{" + code.join(",") + "}";
}
var isChrome = navigator.userAgent.indexOf("AppleWebKit") != -1;
var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
if (location.host == "dynamic.12306.cn" || (location.host == "www.12306.cn" && location.protocol == "https:")) {
//记录更新
utility.setPref("updates", updates.join("\t"));
initUIDisplay();
unsafeInvoke(injectDom);
entryPoint();
}
//#endregion
//#region -----------------入口----------------------
function entryPoint() {
var location = window.location;
var path = location.pathname;
utility.regInfo = utility.verifySn(true);
//
unsafeInvoke(autoReloadIfError);
if ((path == "/otsweb/loginAction.do" && location.search != '?method=initForMy12306') || path == "/otsweb/login.jsp") {
//登录页
unsafeInvoke(initLogin);
}
if (path == "/otsweb/order/querySingleAction.do") {
if (location.search == "?method=init" && document.getElementById("submitQuery")) {
unsafeInvoke(initTicketQuery);
unsafeInvoke(initDirectSubmitOrder);
}
if (location.search == "?method=submutOrderRequest") {
unsafeInvoke(initSubmitOrderQuest);
}
}
if (path == "/otsweb/order/orderAction.do") {
if (location.search.indexOf("method=cancelMyOrderNotComplete") != -1 && document.getElementById("submitQuery")) {
unsafeInvoke(initTicketQuery);
unsafeInvoke(initDirectSubmitOrder);
}
}
if (path == "/otsweb/order/payConfirmOnlineSingleAction.do") {
if (location.search.indexOf("method=cancelOrder") != -1 && document.getElementById("submitQuery")) {
unsafeInvoke(initTicketQuery);
unsafeInvoke(initDirectSubmitOrder);
}
}
if (path == "/otsweb/order/myOrderAction.do") {
if (location.search.indexOf("method=resign") != -1 && document.getElementById("submitQuery")) {
unsafeInvoke(initTicketQuery);
unsafeInvoke(initDirectSubmitOrder);
}
}
if (path == "/otsweb/order/confirmPassengerAction.do") {
if (location.search == "?method=init") {
unsafeInvoke(initAutoCommitOrder);
unsafeInvoke(autoCommitOrderInSandbox);
}
if (location.search.indexOf("?method=payOrder") != -1) {
unsafeInvoke(initPagePayOrder);
//获取登录到IE的代码 Add By XPHelper
unsafeInvoke(utility.enableLoginIE);
}
}
if (path == "/otsweb/order/myOrderAction.do") {
if (location.search.indexOf("?method=laterEpay") != -1 || location.search.indexOf("?method=queryMyOrderNotComplete") != -1) {
unsafeInvoke(initNotCompleteOrderPage);
unsafeInvoke(initPayOrder);
//获取登录到IE的代码 Add By XPHelper
unsafeInvoke(utility.enableLoginIE);
}
}
if (path == "/otsweb/passengerAction.do") {
if (location.search.indexOf("?method=initUsualPassenger") != -1) {
unsafeInvoke(storePasToLocal);
}
}
if (path == "/otsweb/main.jsp" || path == "/otsweb/") {
//主框架
console.log("正在注入主框架脚本。");
//跨页面弹窗提示,防止因为页面跳转导致对话框不关闭
console.log("启动跨页面信息调用检查函数");
window.setInterval(function () {
var msg = window.localStorage["notify"];
if (typeof (msg != 'undefined') && msg) {
console.log("主窗口拦截提示请求: " + msg);
window.localStorage.removeItem("notify");
utility.notify(msg);
}
}, 100);
unsafeInvoke(injectMainPageFunction);
}
}
//#endregion
//#region 保存联系人
function storePasToLocal() {
var isNew = !window.localStorage["pas"];
utility.getAllPassengers(function (list) {
window.localStorage.setItem("pas", $.toJSON(list));
if (isNew) {
alert("恭喜,联系人已经缓存到本地,现在可以去查票咯!");
self.location = "/otsweb/order/querySingleAction.do?method=init";
}
}, true);
}
//#endregion
//#region 未完成订单查询页面
function initNotCompleteOrderPage() {
return;
//处理显示时间的
(function () {
var tagInputs = $("input[name=cache_tour_flag]");
var flags = $.map(tagInputs, function (e, i) { return e.value; });
$.each(flags, function () { $("#showTime_" + this).hide().after("<span id='status_" + this + "'>正在查询...</span>"); });
function doCheck() {
var flag = flags.shift();
flags.push(flag);
utility.get("https://dynamic.12306.cn/otsweb/order/myOrderAction.do?method=queryOrderWaitTime&tourFlag=" + flag, null, "json", function (data) {
var obj = $("#status_" + flag);
if (data.waitTime == 0 || data.waitTime == -1) {
obj.css({ "color": "green" }).html("订票成功!");
utility.notifyOnTop("订票成功!请尽快付款!");
parent.playAudio();
self.location.reload();
return;
}
if (data.waitTime == -2) {
utility.notifyOnTop("出票失败!请重新订票!" + data.msg);
parent.playFailAudio();
obj.css({ "color": "red" }).html("出票失败!" + data.msg);
return;
}
if (data.waitTime == -3) {
utility.notifyOnTop("订单已经被取消!");
parent.playFailAudio();
obj.css({ "color": "red" }).html("订单已经被取消!!");
return;
}
if (data.waitTime == -4) {
utility.notifyOnTop("正在处理中....");
obj.css({ "color": "blue" }).html("正在处理中....");
}
if (data.waitTime > 0) {
obj.css({ "color": "red" }).html("排队中<br />排队数【" + (data.waitCount || "未知") + "】<br />预计时间【" + utility.getSecondInfo(data.waitTime) + "】<br />不过这时间不<br />怎么靠谱 ╮(╯▽╰)╭");
} else {
obj.css({ "color": "red" }).html("奇怪的状态码 [" + data.waitTime + "]....");
}
setTimeout(doCheck, 2000);
}, function () {
utility.notifyOnTop("查询状态错误,正在刷新页面!");
self.location.reload();
});
}
if (flags.length > 0) doCheck();
})();
}
//#endregion
//#region 提交页面出错
function initSubmitOrderQuest() {
if ($("div.error_text").length > 0) {
parent.window.resubmitForm();
}
}
//#endregion
//#region 订票页面,声音提示
function initPagePayOrder() {
new Audio(utility.getAudioUrl()).play();
}
//#endregion
//#region -----------------出错自动刷新----------------------
function autoReloadIfError() {
if ($.trim($("h1:first").text()) == "错误") {
$("h1:first").css({ color: 'red', 'font-size': "18px" }).html(">_< 啊吖!,敢踹我出门啦。。。2秒后我一定会回来的 ╮(╯▽╰)╭");
setTimeout(function () {
self.location.reload();
}, 2000);
}
}
//#endregion
//#region -----------------主框架----------------------
function injectMainPageFunction() {
//资源
var main = $("#main")[0];
main.onload = function () {
var location = null;
try {
location = main.contentWindow.location + '';
} catch (e) {
//出错了,跨站
}
if (!location || location == "http://www.12306.cn/mormhweb/logFiles/error.html") {
resubmitForm();
}
}
if (window.webkitNotifications && window.webkitNotifications.checkPermission() != 0) {
if (confirm("喂!快戳『点击启用桌面通知』,不然提示会阻碍操作,导致运行变慢,然后就没票了!\n\n如果是第一次看到介句话,点击『取消』并按提示操作。如果反复邂逅这个对话框,就戳『确定』以打开助手主页的常见问题并查找解决办法。\n\n搜狗高速浏览器暂不支持保存此权限,每次访问时可能都会邂逅这个对话框……")) {
window.open("http://www.fishlee.net/soft/44/faq.html");
}
}
window.resubmitForm = function () {
var form = $("#orderForm");
if (form.length == 0 || form.attr("success") != "0") return;
utility.notify("页面出错了!正在重新预定!");
setTimeout(function () { document.getElementById("orderForm").submit(); }, 3000);
}
window.playAudio = function () {
new Audio(utility.getAudioUrl()).play();
};
window.playFailAudio = function () {
utility.playFailAudio();
};
}
//#endregion
//#region -----------------自动提交----------------------
function initAutoCommitOrder() {
var count = 0;
var breakFlag = 0;
var randCode = "";
var submitFlag = false;
var tourFlag = 'dc';
var randEl = $("#rand");
//启用日志
utility.enableLog();
//#region 如果系统出错,那么重新提交
if ($(".error_text").length > 0 && parent.$("#orderForm").length > 0) {
parent.resubmitForm();
return;
}
//#endregion
//获得tourflag
(function () {
/'(dc|fc|wc|gc)'/.exec($("div.tj_btn :button:eq(2)")[0].onclick + '');
tourFlag = RegExp.$1;
})();
function stop(msg) {
setCurOperationInfo(false, "错误 - " + msg);
setTipMessage(msg);
$("div.tj_btn button, div.tj_btn input").each(function () {
this.disabled = false;
$(this).removeClass().addClass("long_button_u");
});
$("#btnCancelAuto").hide();
}
var reloadCode = function () {
$("#img_rrand_code").click();
$("#rand").val("")[0].select();
};
var getSleepTime = function () {
return 1000 * Math.max(parseInt($("#pauseTime").val()), 1);
};
//订单等待时间过久的警告
var waitTimeTooLong_alert = false;
function submitForm() {
randEl[0].blur();
stopCheckCount();
if (!window.submit_form_check || !submit_form_check("confirmPassenger")) {
setCurOperationInfo(false, "您的表单没有填写完整!");
stop("请填写完整表单");
return;
}
count++;
setCurOperationInfo(true, "第 " + count + " 次提交");
if (breakFlag) {
stop("已取消自动提交");
breakFlag = 0;
return;
}
$("#btnCancelAuto").show().removeClass().addClass("long_button_u_down")[0].disabled = false; //阻止被禁用
breakFlag = 0;
waitTimeTooLong_alert = false;
$("#confirmPassenger").ajaxSubmit({
url: 'confirmPassengerAction.do?method=checkOrderInfo&rand=' + $("#rand").val(),
type: "POST",
data: { tFlag: tourFlag },
dataType: "json",
timeout: 10000,
success: function (data) {
if ('Y' != data.errMsg || 'N' == data.checkHuimd || 'N' == data.check608) {
setCurOperationInfo(false, data.msg || data.errMsg);
stop(data.msg || data.errMsg);
reloadCode();
}
else {
queryQueueCount();
}
},
error: function (msg) {
setCurOperationInfo(false, "当前请求发生错误");
utility.delayInvoke(null, submitForm, 1000);
}
});
}
function queryQueueCount() {
var queryLeftData = {
train_date: $("#start_date").val(),
train_no: $("#train_no").val(),
station: $("#station_train_code").val(),
seat: $("#passenger_1_seat").val(),
from: $("#from_station_telecode").val(),
to: $("#to_station_telecode").val(),
ticket: $("#left_ticket").val()
};
utility.get("/otsweb/order/confirmPassengerAction.do?method=getQueueCount", queryLeftData, "json", function (data) {
console.log(data);
if (data.op_2) {
var errmsg = "排队人数过多,系统禁止排队,稍等自动重试 (排队人数=" + data.count + ")";
setCurOperationInfo(true, errmsg);
stop(errmsg);
utility.delayInvoke(null, queryQueueCount, 1000);
return;
}
setTimeout(submitConfirmOrder, 2000 + Math.random() * 1000);
}, function () { utility.delayInvoke(null, queryLeftTickets, 2000); });
}
function submitConfirmOrder() {
var url;
if (tourFlag == 'dc') {
// 异步下单-单程
url = 'confirmPassengerAction.do?method=confirmSingleForQueueOrder';
} else if (tourFlag == 'wc') {
// 异步下单-往程
url = 'confirmPassengerAction.do?method=confirmPassengerInfoGoForQueue';
} else if (tourFlag == 'fc') {
// 异步下单-返程
url = 'confirmPassengerAction.do?method=confirmPassengerInfoBackForQueue';
} else if (tourFlag == 'gc') {
// 异步下单-改签
url = 'confirmPassengerResignAction.do?method=confirmPassengerInfoResignForQueue';
}
jQuery.ajax({
url: url,
data: $('#confirmPassenger').serialize(),
type: "POST",
timeout: 10000,
dataType: 'json',
success: function (msg) {
console.log(msg);
var errmsg = msg.errMsg;
if (errmsg != 'Y') {
if (errmsg.indexOf("包含未付款订单") != -1) {
alert("您有未支付订单! 等啥呢, 赶紧点确定支付去.");
window.location.replace("/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y");
return;
}
if (errmsg.indexOf("重复提交") != -1) {
stop("重复提交错误,已刷新TOKEN,请重新输入验证码提交");
reloadToken();
reloadCode();
return;
}
if (errmsg.indexOf("后台处理异常") != -1 || errmsg.indexOf("非法请求") != -1) {
if (lastform) {
utility.notifyOnTop("后台处理异常,已自动重新提交表单,请填写验证码并提交!");
lastform.submit();
} else {
stop("后台处理异常,请返回查询页重新预定!");
}
return;
}
if (errmsg.indexOf("包含排队中") != -1) {
console.log("惊现排队中的订单, 进入轮询状态");
waitingForQueueComplete();
return;
}
setCurOperationInfo(false, errmsg);
stop(errmsg);
reloadCode();
} else {
utility.notifyOnTop("订单提交成功, 正在等待队列完成操作,请及时注意订单状态");
waitingForQueueComplete();
}
},
error: function (msg) {
setCurOperationInfo(false, "当前请求发生错误");
utility.delayInvoke(null, submitForm, 3000);
}
});
}
function reloadToken(submit) {
setCurOperationInfo(true, "正在刷新TOKEN....");
utility.post("/otsweb/order/confirmPassengerAction.do?method=init", null, "text", function (text) {
if (!/TOKEN"\s*value="([a-f\d]+)"/i.test(text)) {
setCurOperationInfo(false, "无法获得TOKEN,正在重试");
utility.delayInvoke("#countEle", reloadToken, 1000);
} else {
var token = RegExp.$1;
setCurOperationInfo(false, "已获得TOKEN - " + token);
console.log("已刷新TOKEN=" + token);
$("input[name=org.apache.struts.taglib.html.TOKEN]").val(token);
}
}, function () { utility.delayInvoke("#countEle", reloadToken, 1000); });
}
function waitingForQueueComplete() {
setCurOperationInfo(true, "订单提交成功, 正在等待队列完成操作....");
$.ajax({
url: '/otsweb/order/myOrderAction.do?method=queryOrderWaitTime&tourFlag=' + tourFlag + '&' + Math.random(),
data: {},
type: 'GET',
timeout: 10000,
dataType: 'json',
success: function (json) {
console.log(json);
if (json.waitTime == -1 || json.waitTime == 0) {
utility.notifyOnTop("订票成功!");
if (json.orderId)
window.location.replace("/otsweb/order/confirmPassengerAction.do?method=payOrder&orderSequence_no=" + json.orderId);
else window.location.replace('/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y');
} else if (json.waitTime == -3) {
var msg = "很抱歉, 铁道部无齿地撤销了您的订单, 赶紧重新下!";
utility.notify(msg);
setCurOperationInfo(false, msg);
stop(msg);
reloadCode();
} else if (json.waitTime == -2) {
var msg = "很抱歉, 铁道部说您占座失败 : " + json.msg + ', 赶紧重新来过!';
reloadToken();
utility.notify(msg);
setCurOperationInfo(false, msg);
stop(msg);
reloadCode();
}
else if (json.waitTime < 0) {
var msg = '很抱歉, 未知的状态信息 : waitTime=' + json.waitTime + ', 可能已成功,请验证未支付订单.';
setTipMessage(msg);
utility.notifyOnTop(msg);
location.href = '/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y';
} else {
var msg = "订单需要 " + utility.getSecondInfo(json.waitTime) + " 处理完成, 请等待,不过你知道的,铁道部说的一直不怎么准。(排队人数=" + (json.waitCount || "未知") + ")";
if (json.waitTime > 1800) {
msg += "<span style='color:red; font-weight: bold;'>警告:排队时间大于30分钟,请不要放弃电话订票或用小号重新排队等其它方式继续订票!</span>";
}
setTipMessage(msg);
if (json.waitTime > 1800 && !waitTimeTooLong_alert) {
waitTimeTooLong_alert = true;
utility.notifyOnTop("警告!排队时间大于30分钟,成功率较低,请尽快电话订票或用小号重新排队!");
}
utility.delayInvoke("#countEle", waitingForQueueComplete, 3000);
}
},
error: function (json) {
utility.notifyOnTop("请求发生异常,可能是登录状态不对,请验证。如果没有问题,请手动进入未完成订单页面查询。");
self.location.reload();
}
});
}
//$("div.tj_btn").append("<button class='long_button_u_down' type='button' id='btnAutoSubmit'>自动提交</button> <button class='long_button_u_down' type='button' id='btnCancelAuto' style='display:none;'>取消自动</button>");
$("#btnAutoSubmit").click(function () {
count = 0;
breakFlag = 0;
submitFlag = true;
submitForm();
});
$("#btnCancelAuto").click(function () {
$(this).hide();
breakFlag = 1;
submitFlag = false;
});
randEl.keyup(function (e) {
return;
if (document.getElementById("autoStartCommit").checked && !breakFlag) {
if (e.charCode == 13 || randEl.val().length == 4) submitForm();
}
});
//清除上次保存的预定信息
var lastform = null;
if (parent) {
lastform = parent.$("#orderForm");
lastform.attr("success", "1");
}
//进度提示框
//$("table.table_qr tr:last").before("<tr style='display:none;'><td style='border-top:1px dotted #ccc;height:100px;' colspan='9' id='orderCountCell'></td></tr><tr><td style='border-top:1px dotted #ccc;' colspan='9'><ul id='tipScript'>" +
//"<li class='fish_clock' id='countEle' style='font-weight:bold;'>等待操作</li>" +
//"<li style='color:green;'><strong>操作信息</strong>:<span>休息中</span></li>" +
//"<li style='color:green;'><strong>最后操作时间</strong>:<span>--</span></li></ul></td></tr>");
var tip = $("#tipScript li");
var errorCount = 0;
//以下是函数
function setCurOperationInfo(running, msg) {
var ele = $("#countEle");
ele.removeClass().addClass(running ? "fish_running" : "fish_clock").html(msg || (running ? "正在操作中……" : "等待中……"));
}
function setTipMessage(msg) {
tip.eq(2).find("span").html(utility.getTimeInfo());
tip.eq(1).find("span").html(msg);
}
//提交频率差别
$(".table_qr tr:last").before("<tr><td colspan='9'><span style='display:none;'>自动提交失败时休息时间:<input type='text' size='4' class='input_20txt' style='text-align:center;' value='3' id='pauseTime' />秒 (不得低于1) <label><input type='checkbox' id='autoStartCommit' /> 输入验证码后立刻开始自动提交</label></span> <label><input type='checkbox' id='showHelp' /> 显示帮助</label></td></tr>");
document.getElementById("autoStartCommit").checked = typeof (window.localStorage["disableAutoStartCommit"]) == 'undefined';
document.getElementById("showHelp").checked = typeof (window.localStorage["showHelp"]) != 'undefined';
$("#autoStartCommit").change(function () {
if (this.checked) window.localStorage.removeItem("disableAutoStartCommit");
else window.localStorage.setItem("disableAutoStartCommit", "1");
});
$("#showHelp").change(function () {
if (this.checked) {
window.localStorage.setItem("showHelp", "1");
$("table.table_qr tr:last").show();
}
else {
window.localStorage.removeItem("showHelp");
$("table.table_qr tr:last").hide();
}
}).change();
//#region 自动刷新席位预定请求数
var stopCheckCount = null;
(function () {
var data = { train_date: $("#start_date").val(), station: $("#station_train_code").val(), seat: "", from: $("#from_station_telecode").val(), to: $("#to_station_telecode").val(), ticket: $("#left_ticket").val() };
var url = "confirmPassengerAction.do?method=getQueueCount";
var allSeats = $("#passenger_1_seat option");
var queue = [];
var checkCountStopped = false;
function beginCheck() {
if (checkCountStopped) return;
var html = [];
html.push("当前实时排队状态(每隔2秒轮询):");
allSeats.each(function () {
queue.push({ id: this.value, name: this.text });
html.push("席位【<span style='color:blue; font-weight: bold;'>" + this.text + "</span>】状态:<span id='queueStatus_" + this.value + "'>等待查询中....</span>");
});
$("#orderCountCell").html(html.join("<br />"));
if (queue.length > 0) executeQueue();
}
function checkTicketAvailable() {
var queryLeftData = {
'orderRequest.train_date': $('#start_date').val(),
'orderRequest.from_station_telecode': $('#from_station_telecode').val(),
'orderRequest.to_station_telecode': $('#to_station_telecode').val(),
'orderRequest.train_no': $('#train_no').val(),
'trainPassType': 'QB',
'trainClass': 'QB#D#Z#T#K#QT#',
'includeStudent': 00,
'seatTypeAndNum': '',
'orderRequest.start_time_str': '00:00--24:00'
};
utility.get("/otsweb/order/querySingleAction.do?method=queryLeftTicket", queryLeftData, "text", function (text) {
window.ticketAvailable = '';
if (/(([\da-zA-Z]\*{5,5}\d{4,4})+)/gi.test(text)) {
window.ticketAvailable = RegExp.$1;
}
}, function () { });
}
function executeQueue() {
if (checkCountStopped) return;
var type = queue.shift();
queue.push(type);
data.seat = type.id;
var strLeftTicket = '';
checkTicketAvailable();
if (window.ticketAvailable) {
strLeftTicket = window.ticketAvailable;
}
utility.get(url, data, "json", function (data) {
var msg = "余票:<strong>" + getTicketCountDesc(strLeftTicket, type.id) + "</strong>";
msg += ",当前排队【<span style='color:blue; font-weight: bold;'>" + data.count + "</span>】,";
if (data.op_2) {
msg += "<span style='color:blue; font-weight: red;'>排队人数已经超过余票数,可能无法提交</span>。";
} else {
if (data.countT > 0) {
msg += "排队人数已超过系统参数,<span style='color:red; font-weight: bold;'>排队有危险</span>";
//} else if (data.op_1) {
// msg += "排队人数已超过系统参数,<span style='color:red; font-weight: bold;'>排队有危险</span>";
} else {
msg += "请尽快提交";
}
}
msg += " (" + utility.getTimeInfo() + ")";
$("#queueStatus_" + type.id).html(msg);
setTimeout(executeQueue, 2000);
}, function () {
setTimeout(executeQueue, 3000);
});
}
stopCheckCount = function () {
checkCountStopped = true;
}
//beginCheck();
})();
//#endregion
//#region 自动选择联系人、自动选择上次选择的人
function autoSelectPassenger() {
var pp = localStorage.getItem("preSelectPassenger") || "";
var pseat = (localStorage.getItem("autoSelect_preSelectSeatType") || "").split('|')[0];
if (pp) {
pp = pp.split("|");
$.each(pp, function () {
if (!this) return true;
console.log("[INFO][自动选择乘客] 自动选定-" + this);
$("#" + this + "._checkbox_class").attr("checked", true).click().attr("checked", true); //为啥设置两次?我也不知道,反正一次不对。
return true;
});
if (pseat) {
$(".passenger_class").each(function () { $(this).find("select:eq(0)").val(pseat).change(); });
}
}
};
$(window).ajaxComplete(function (e, xhr, s) {
if (s.url.indexOf("getpassengerJson") != -1) {
console.log("[INFO][自动选择乘客] 系统联系人加载完成,正在检测预先选定");
autoSelectPassenger();
}
});
//如果已经加载完成,那么直接选定
if ($("#showPassengerFilter div").length) {
console.log("[INFO][自动选择乘客] OOPS,居然加载完成了?直接选定联系人");
autoSelectPassenger();
}
//#endregion
//#region 自动定位到随机码中
(function () {
var obj = document.getElementById("rand");
var oldOnload = window.onload;
window.onload = function () {
if (oldOnload) oldOnload();
obj.select();
};
obj.select();
})();
//#endregion
//#region 显示内部的选择上下铺
(function () {
//添加上下铺显示
$("tr.passenger_class").each(function () {
var tr = $(this);
var id = tr.attr("id");
tr.find("td:eq(2)").append("<select id='" + id + "_seat_detail' name='" + id + "_seat_detail'><option value='0'>随机</option><option value='2'>上铺</option><option value='2'>中铺</option><option value='1'>下铺</option></select>");
});
var seatSelector = $("select[name$=_seat]");
seatSelector.change(function () {
var self = $(this);
var val = self.val();
var l = self.next();
if (val == "2" || val == "3" || val == "4" || val == "6") {
l.show();
} else
l.hide();
var preseat = utility.getPref("preselectseatlevel");
if (preseat) {
l.val(preseat).change();
}
}).change();
})();
//#endregion
parent.$("#main").css("height", ($(document).height() + 300) + "px");
parent.window.setHeight(parent.window);
}
function autoCommitOrderInSandbox() {
//自动提示?
if (window.localStorage["bookTip"]) {
window.localStorage.removeItem("bookTip");
if (window.Audio) {
new window.Audio(utility.getAudioUrl()).play();
}
utility.notify("已经自动进入订票页面!请继续完成订单!");
}
}
//#endregion
//#region -----------------自动刷新----------------------
function initTicketQuery() {
//初始化
if (!window.localStorage["pas"]) {
alert("亲,请进入我的12306->常用联系人并稍等片刻以更新缓存~");
//self.location = "/otsweb/passengerAction.do?method=initUsualPassenger12306";
return;
}
//启用日志
utility.enableLog();
var initialized = false;
var seatLevelOrder = null;
var orderButtonClass = ".btn130_2"; //预定按钮的选择器
//#region 参数配置和常规工具界面
var queryCount = 0;
var timer = null;
var isTicketAvailable = false;
var audio = null; //通知声音
var timerCountDown = 0;
var timeCount = 0;
var autoBook = false;
//初始化表单
var form = $("form[name=querySingleForm] .cx_from:first");
form.find("tr:last").after("<tr class='append_row'><td colspan='9' id='queryFunctionRow'><label title='勾选此选项的话,每次你查询后,助手会帮你把始发站、到达站、日期等进行记录,下次进入查询页面后,将会帮您自动填写好'><input type='checkbox' id='keepinfo' checked='checked' />记住信息</label> <label title='勾选此选项后,假定查询的结果中没有符合你要求的车次,那么助手将会自动进行重新查询'><input checked='checked' type='checkbox' id='autoRequery' />自动重新查询</label>,每隔 <input style='width:50px;' type='number' min='5' value='5' size='4' id='refereshInterval' style='text-align:center;' />秒(最低5) " +
"<label title='勾选的话,当有票可定时,助手会放歌骚扰你'><input type='checkbox' checked='checked' id='chkAudioOn'>声音提示</label> <input type='button' id='chkSeatOnly' value='仅座票' class='lineButton' title='快速设置席别过滤按钮,点击后可快速勾选所有的座票,包括硬座软座一等座等等' /><input type='button' id='chkSleepOnly' value='仅卧铺' title='快速设置席别过滤按钮,点击后可快速勾选所有的卧铺,包括硬卧软卧什么的' class='lineButton' /><input type='button' id='chkAllSeat' value='全部席别' class='lineButton' title='快速勾选所有的席别' />" +
"<input type='button' id='enableNotify' onclick='window.webkitNotifications.requestPermission();' value='点击启用桌面通知' style='line-height:25px;padding:5px;' /> <span id='refreshinfo'>已刷新 0 次,最后查询:--</span> <span id='refreshtimer'></span></td></tr>" +
"<tr class='append_row'><td colspan='9'><label title='设置有票时放的歌是不是放到天荒地老至死不渝'><input type='checkbox' checked='checked' id='chkAudioLoop'>声音循环</label>" +
"<span style='font-weight:bold;margin-left:10px;color:blue;' title='点击预定按钮时,有时候等待一会儿系统会提示服务器忙;勾选此选项后,如果出现这种情况,助手将会进行自动重新预定'><label><input type='checkbox' id='chkAutoResumitOrder' checked='checked' />预定失败时自动重试</label></span>" +
"<span style='font-weight:bold;margin-left:10px;color:blue;' title='有时候系统忙,查询会提示查询失败;勾选此选项后,如果出现这种情况,助手将会进行自动刷新查询'><label><input type='checkbox' id='chkAutoRequery' checked='checked' />查询失败时自动重试</label></span>" +
"<span style='font-weight:bold;margin-left:10px;color:pruple;' title='以服务器时间为准,未获得服务器时间之前,此选项不可用。启用智能加速模式时,在非正点附近时(大于0小于59分)按照正常速度刷新;当在正点附近时(大于等于59分时),暂停刷新并等到正点即刻刷新。'><label><input disabled='disabled' type='checkbox' id='chkSmartSpeed' />智能正点刷新模式</label></span>" +
"</td></tr>" +
"<tr class='append_row'><td id='filterFunctionRow' colspan='9'>" +
"<span style='font-weight:bold;color:red;'><label title='不可以预定的车次过滤掉的选项(隐藏起来不显示,无票的车次)'><input type='checkbox' id='chkFilterNonBookable' />过滤不可预订的车次</label></span>" +
"<span style='font-weight:bold;margin-left:10px;color:red;'><label title='有时候虽然整趟车可以预定,但是有票的席别都是你不要的,如果勾选此选项,也将会过滤掉'><input type='checkbox' id='chkFilterNonNeeded' />过滤不需要的席别</label></span>" +
"<span style='font-weight:bold;margin-left:10px;color:blue;display: none;'><label><input disabled='disabled' type='checkbox' id='chkFilterByTrain' />开启按车次过滤</label></span>" +
"</td></tr>" +
"<tr><td colspan='9' id='opFunctionRow'><input type='button' class='fish_button' disabled='disabled' value='停止声音' id='btnStopSound' /><input type='button' class='fish_button' disabled='disabled' value='停止刷新' id='btnStopRefresh' /><input type='button' class='fish_button' type='button' value='设置' id='configLink' /> <input type='button' class='fish_button' id='resetSettings' value='清空助手设置' /> <input type='button' class='fish_button configLink' value='IE登录' /> 【<a href='http://www.fishlee.net/soft/44/tour.html' style='color:purple;font-weight:bold;' target='_blank'>啊嘞……遇到不明白的啦?戳这里看教程呗</a>】<span style='margin-left:20px;color:purple;font-weight:bold;' id='serverMsg'></span></td> </tr>"
);
if (!window.Audio) {
$("#chkAudioOn, #chkAudioLoop, #btnStopSound").remove();
} else {
$("#btnStopSound").click(function () {
if (audio) {
audio.pause();
}
this.disabled = true;
});
}
$("#resetSettings").click(function () {
if (confirm("确定要清空助手的所有设置吗?")) {
window.localStorage.clear();
self.location.reload();
return false;
}
});
//操作控制
$("#btnStopRefresh").click(function () { resetTimer(); });
$("#chkSmartSpeed").change(function () {
});
//#endregion
//#region 显示座级选择UI
var ticketType = new Array();
var seatOptionTypeMap = {
"3": "9",
"4": "P",
"5": "M",
"6": "O",
"7": "6",
"8": "4",
"9": "3",
"10": "2",
"11": "1",
"12": "empty",
"13": "QT"
};
$(".hdr tr:eq(2) td").each(function (i, e) {
ticketType.push(false);
if (i < 3) return;
var obj = $(this);
ticketType[i] = (window.localStorage["typefilter_" + i] || "true") == "true";
//修改文字,避免换行
obj.attr("otext", obj.text());
var cap = $.trim(obj.text());
if (cap.length > 2) {
cap = cap.replace("座", "").replace("高级软卧", "高软");
obj.html(cap);
}
//加入复选框
var c = $("<input id='seatoption_" + seatOptionTypeMap[i] + "' type='checkbox' typecode='" + seatOptionTypeMap[i] + "' name='seatoption'/>").attr("checked", ticketType[i]);
c[0].ticketTypeId = i;
c.change(
function () {
ticketType[this.ticketTypeId] = this.checked;
window.localStorage["typefilter_" + this.ticketTypeId] = this.checked;
}).appendTo(obj);
});
//座级选择
$("#chkSeatOnly").click(function () {
$(".hdr tr:eq(2) td").each(function (i, e) {
var obj = $(this);
var txt = obj.attr("otext");
obj.find("input").attr("checked", typeof (txt) != 'undefined' && txt && txt.indexOf("座") != -1).change();
});
});
$("#chkSleepOnly").click(function () {
$(".hdr tr:eq(2) td").each(function (i, e) {
var obj = $(this);
var txt = obj.attr("otext");
obj.find("input").attr("checked", typeof (txt) != 'undefined' && txt && txt.indexOf("卧") != -1).change();
});
});
$("#chkAllSeat").click(function () {
$(":checkbox[name=seatoption]").attr("checked", true).change();
});
//#endregion
//#region 显示额外的功能区
var extrahtml = [];
extrahtml.push("<div class='outerbox' id='helperbox' style='width:auto;'><div class='box'><div class='title' style='position:relative;'>辅助工具 [<a href='#querySingleForm'>返回订票列表</a>] <div style='color:#066DFF;position:absolute;background-color: #eee;border: 1px solid purple;right:0px;top:0px;padding:2px;margin:2px;' title='时间依赖于本地时间保持在线刷新时间即时计算。受限于您的网速,并不十分准确(需要扣除网速的影响)' id='servertime'>服务器时间:<strong>----</strong>,本地时间:<strong>----</strong>,服务器比本地 <strong>----</strong></div></div>\
<table id='helpertooltable' style='width:100%;'><colgroup><col style='width:110px;' /><col style='width:370px;' /><col style='width:110px;' /><col style='width:auto;' /></colgroup>\
<tr class='fish_sep musicFunc' id='helperbox_bottom'><td class='name'>自定义音乐地址</td><td colspan='3'><input type='text' id='txtMusicUrl' value='" + utility.getAudioUrl() + "' onfocus='this.select();' style='width:50%;' /> <input type='button' onclick='new Audio(document.getElementById(\"txtMusicUrl\").value).play();' value='测试'/><input type='button' onclick='utility.resetAudioUrl(); document.getElementById(\"txtMusicUrl\").value=utility.getAudioUrl();' value='恢复默认'/> (地址第一次使用可能会需要等待一会儿)</td></tr>\
<tr class='fish_sep musicFunc'><td class='name'>可用音乐地址</td><td colspan='3'>");
var host1 = "http://static.liebao.cn/resources/audio/";
//var host2 = "https://github.com/iccfish/12306_ticket_helper/raw/master/res/";
var musics = [["music1.ogg", "超级玛丽"], ["music2.ogg", "蓝精灵"]];
$.each(musics, function () {
extrahtml.push("<a href='javascript:;' url='" + host1 + this[0] + "' class='murl'>" + this[1] + "</a> ");
//extrahtml.push("<a href='javascript:;' url='" + host2 + this[0] + "' class='murl'>" + this[1] + "</a>(HTTPS) ");
});
extrahtml.push("</td></tr><tr class='fish_sep'><td colspan='4'><input type='button' value='添加自定义车票时间段' id='btnDefineTimeRange' />\
<input type='button' value='清除自定义车票时间段' id='btnClearDefineTimeRange' /></td></tr>\
<tr class='fish_sep'><td style='text-align:center;' colspan='4'><a href='http://www.fishlee.net/soft/44/' target='_blank' style='color:purple;'>12306.CN 订票助手</a> | <a href='http://www.fishlee.net/soft/44/announcement.html' style='color:blue;' target='_blank'>免责声明</a> | <a href='"+ utility.getUpdateUrl() + "' target='_blank' style='color:purple;'>下载新版</a> | <a style='font-weight:bold;color:red;' href='http://www.fishlee.net/soft/44/donate.html' target='_blank'>捐助作者</a> | 版本 v" + window.helperVersion + ",许可于 <strong>" + utility.regInfo.name + ",类型 - " + utility.regInfo.typeDesc + "</strong> 【<a href='javascript:;' class='reSignHelper'>重新注册</a>】</td></tr>\
</table></div></div>");
$("body").append(extrahtml.join(""));
$("a.murl").live("click", function () {
$("#txtMusicUrl").val(this.getAttribute("url")).change();
});
$("#stopBut").before("<div class='jmp_cd' style='text-align:center;'><button class='fish_button' id='btnFilter'>加入黑名单</button><button class='fish_button' id='btnAutoBook'>自动预定本车次</button></div>");
$("#txtMusicUrl").change(function () { window.localStorage["audioUrl"] = this.value; });
$("form[name=querySingleForm]").attr("id", "querySingleForm");
//#endregion
//#region 添加自定义时间段
function addCustomTimeRange() {
var s = parseInt(prompt("请输入自定义时间段的起始时间(请填入小时,0-23)", "0"));
if (isNaN(s) || s < 0 || s > 23) {
alert("起始时间不正确 >_<"); return;
}
var e = parseInt(prompt("请输入自定义时间段的结束时间(请填入小时,1-24)", "24"));
if (isNaN(e) || e < 0 || e > 24) {
alert("结束时间不正确 >_<"); return;
}
var range = (s > 9 ? "" : "0") + s + ":00--" + (e > 9 ? "" : "0") + e + ":00";
if (confirm("您想要记住这个时间段吗?")) {
window.localStorage["customTimeRange"] = (window.localStorage["customTimeRange"] ? window.localStorage["customTimeRange"] + "|" : "") + range;
};
addCustomeTimeRangeToList(range);
}
function addCustomeTimeRangeToList(g) {
var obj = document.getElementById("startTime");
obj.options[obj.options.length] = new Option(g, g);
obj.selectedIndex = obj.options.length - 1;
}
if (window.localStorage["customTimeRange"]) {
var ctrs = window.localStorage["customTimeRange"].split("|");
$.each(ctrs, function () { addCustomeTimeRangeToList(this); });
}
$("#btnClearDefineTimeRange").click(function () {
if (!confirm("确定要清除自定义的时间段吗?清除后请刷新页面。")) return;
window.localStorage.removeItem("customTimeRange");
});
$("#btnDefineTimeRange").click(addCustomTimeRange);
//#endregion
//#region 过滤车次
var stopHover = window.onStopHover;
window.onStopHover = function (info) {
$("#stopDiv").attr("info", $.trim($("#id_" + info.split('#')[0]).text()));
stopHover.call(this, info);
$("#onStopHover").css("overflow", "hide");
};
$("#btnFilter").click(function () {
//加入黑名单
var trainNo = $("#stopDiv").attr("info").split('#')[0];
if (!trainNo || !confirm("确定要将车次【" + trainNo + "】加入黑名单?以后的查询将不再显示此车次。")) return;
list_blacklist.add(trainNo);
});
$("#btnAutoBook").click(function () {
//加入自动预定列表
var trainNo = $("#stopDiv").attr("info").split('#')[0];
if (isTrainInBlackList(trainNo)) {
alert("指定的车次在黑名单里呢……");
return;
}
if (!trainNo || !confirm("确定要将车次【" + trainNo + "】加入自动预定列表?如果下次查询有符合要求的席别将会自动进入预定页面。")) return;
list_autoorder.add(trainNo);
});
//清除进入指定页面后提示的标记位
if (window.localStorage["bookTip"]) window.localStorage.removeItem("bookTip");
//#endregion
//#region 自动重新查询
var clickButton = null;//点击的查询按钮