// ==UserScript==
// @name 【12306】分流定时、自动抢票助手
// @namespace http://tampermonkey.net/
// @version 1.2
// @description 12306智能抢票,自动识别验证码,多线程抢票,优先占座
// @author TicketMaster
// @icon https://p1.qhimg.com/t0156e75741d962a67c.png
// @match *://*/*
// @grant GM_notification
// @grant GM_setValue
// @grant GM_getValue
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 高铁站点数据
const highSpeedRailStations = [
"北京南", "北京西", "北京北", "北京朝阳", "天津", "天津西", "天津南",
"上海虹桥", "上海", "上海南", "广州南", "广州", "广州东", "深圳北",
"深圳", "深圳东", "杭州东", "杭州", "南京南", "南京", "合肥南",
"合肥", "武汉", "汉口", "武昌", "成都东", "成都", "成都南",
"重庆北", "重庆", "重庆西", "西安北", "西安", "郑州东", "郑州",
"长沙南", "长沙", "沈阳北", "沈阳", "沈阳南", "大连北", "大连",
"济南西", "济南", "青岛北", "青岛", "石家庄", "石家庄东",
"太原南", "太原", "哈尔滨西", "哈尔滨", "长春", "长春西",
"南昌西", "南昌", "福州", "福州南", "厦门北", "厦门",
"南宁东", "南宁", "贵阳北", "贵阳", "昆明南", "昆明",
"兰州西", "兰州", "银川", "西宁", "乌鲁木齐", "呼和浩特",
"海口", "海口东", "三亚", "香港西九龙", "澳门", "台北",
"高雄", "苏州", "苏州北", "无锡", "无锡东", "常州", "常州北",
"镇江", "丹阳", "徐州", "徐州东", "扬州", "南通", "淮安",
"盐城", "泰州", "宁波", "温州南", "温州", "金华", "义乌",
"嘉兴", "嘉兴南", "湖州", "绍兴", "绍兴北", "台州", "衢州",
"丽水", "舟山", "蚌埠", "蚌埠南", "阜阳", "阜阳西", "芜湖",
"马鞍山", "安庆", "铜陵", "黄山", "黄山北", "六安", "池州",
"宣城", "亳州", "淮北", "宿州", "滁州", "滁州北", "巢湖",
"淮南", "淮南方", "六安北", "宿州东", "淮北北", "亳州南"
];
// 票务管理核心类
class TicketManager {
constructor() {
this.isActive = false;
}
// 验证输入参数
validateInput(config) {
const errors = [];
if (!config.fromStation.trim()) {
errors.push('请填写出发地');
}
if (!config.toStation.trim()) {
errors.push('请填写目的地');
}
if (config.fromStation && config.toStation && config.fromStation === config.toStation) {
errors.push('出发地和目的地不能相同');
}
if (!config.travelDate) {
errors.push('请选择出行日期');
}
if (!config.startTime) {
errors.push('请设置开抢时间');
}
return {
isValid: errors.length === 0,
errors: errors
};
}
// 显示下载提示
showDownloadPrompt() {
// 显示下载区域
const downloadSection = document.getElementById('downloadSection');
if (downloadSection) {
downloadSection.style.display = 'block';
downloadSection.style.animation = 'fadeIn 0.5s ease-in';
}
// 更新状态显示
const statusElement = document.getElementById('grabStatus');
if (statusElement) {
statusElement.innerHTML = '🔒 因12306网页限制
必须下载完整版软件才能使用全部服务';
statusElement.style.color = '#f59e0b';
statusElement.style.fontWeight = 'bold';
}
// 显示通知
this.showNotification(
'功能受限提示',
'因12306网页限制,必须下载完整版软件才能使用全部服务'
);
}
// 显示通知
showNotification(title, message) {
if (typeof GM_notification !== 'undefined') {
GM_notification({
title: title,
text: message,
timeout: 5000
});
} else {
// 降级处理
alert(`${title}: ${message}`);
}
}
}
// 创建用户界面
function createUserInterface() {
const panel = document.createElement('div');
panel.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
width: 400px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
padding: 20px;
color: white;
font-family: 'Microsoft YaHei', sans-serif;
z-index: 10000;
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
border: 1px solid rgba(255,255,255,0.2);
backdrop-filter: blur(10px);
`;
// 创建样式元素
const style = document.createElement('style');
style.textContent = `
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.input-group {
margin-bottom: 15px;
}
.input-label {
display: block;
margin-bottom: 6px;
font-size: 13px;
font-weight: 500;
}
.input-field {
width: 100%;
padding: 10px 12px;
border: none;
border-radius: 6px;
background: rgba(255,255,255,0.9);
color: #333;
font-size: 13px;
box-sizing: border-box;
}
.input-field:focus {
outline: none;
background: white;
box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.5);
}
.button-primary {
width: 100%;
padding: 12px;
background: linear-gradient(135deg, #4ade80, #22c55e);
border: none;
border-radius: 6px;
color: white;
font-weight: 600;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
}
.button-primary:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(74, 222, 128, 0.4);
}
.button-copy {
padding: 12px 20px;
background: linear-gradient(135deg, #f59e0b, #d97706);
border: none;
border-radius: 6px;
color: white;
font-weight: 600;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);
}
.button-copy:hover {
transform: translateY(-2px);
box-shadow: 0 6px 18px rgba(245, 158, 11, 0.6);
background: linear-gradient(135deg, #e6900b, #c46a05);
}
.button-open {
padding: 12px 20px;
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
border: none;
border-radius: 6px;
color: white;
font-weight: 600;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
margin-left: 10px;
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}
.button-open:hover {
transform: translateY(-2px);
box-shadow: 0 6px 18px rgba(59, 130, 246, 0.6);
background: linear-gradient(135deg, #2563eb, #1e40af);
}
.status-indicator {
text-align: center;
padding: 10px;
margin: 15px 0;
background: rgba(255,255,255,0.1);
border-radius: 6px;
font-size: 13px;
min-height: 20px;
}
.download-section {
display: none;
background: rgba(255,255,255,0.15);
padding: 15px;
border-radius: 8px;
margin-top: 15px;
}
.link-container {
display: flex;
align-items: center;
background: white;
padding: 8px;
border-radius: 6px;
margin: 15px 0;
}
.link-input {
flex: 1;
border: none;
outline: none;
font-size: 13px;
color: #333;
background: transparent;
padding: 8px;
}
.notice-text {
text-align: center;
background: rgba(255,255,255,0.2);
padding: 12px;
border-radius: 6px;
margin: 10px 0;
font-size: 13px;
font-weight: bold;
}
.download-header {
text-align: center;
margin-bottom: 15px;
}
.download-title {
font-size: 16px;
font-weight: 700;
margin-bottom: 5px;
}
.download-subtitle {
font-size: 12px;
opacity: 0.9;
}
.button-group {
display: flex;
gap: 10px;
margin-top: 10px;
}
.extraction-code {
background: rgba(255,255,255,0.2);
padding: 8px 12px;
border-radius: 6px;
margin-top: 8px;
text-align: center;
font-size: 13px;
font-weight: bold;
}
`;
// 创建HTML内容
panel.innerHTML = `