前言
今天(2012-10-22)的抢书热潮算是过去了,不过很遗憾的告诉大家,我算是失败了,可惜呀可惜,博客园果然不是盖的,汤姆大叔的书果然不是卖的(是送的)呀。失败就得总结经验,根据目测用工具的人那叫一个多呀,既然大家都玩到这程度了,肯定精确到秒那是不够的了,不是还有4天吗,为了抢到书,所以咱得改进改进。
经过测试博客园的时间要晚于北京时间2到3秒,比我本地时间要晚1秒850毫秒左右,尽管精确到这个点了,还是抢不到,为什么呢,除了因为人气旺,还有一点当然是提交的延时无法咱们无法控制,博客园在压力正常的情况下,提交延时大约为90-200ms,所以咱得把这个时间算上。应一些朋友要求,加了些注释。
使用方式一样,将下来代码另存为GrabTheBook.user.js(一定要以”.user.js“为结尾),拖到google浏览器,然后进入(抢书地址)就可以了,也可以直接点击文章最下方的下载链接,有些网友反映google浏览器无法安装,大致是由于安全性导致,网友 @sati 提供了解决方法,见网址:http://www.itopdog.cn/software-tech/solution-to-chrome-blocking.html
版本
v1.1 秒级别定时抢书(刚开始还没预计到抢书大潮会如此这般汹涌)上一篇
v2.1 时间精确到了毫秒(刚需呀)(图1)
v2.2 修改了上一版本一些小BUG (图2)
v3.0 第三次改进效果(加入了任务管理机制,更方便更直观,可以很轻松实现网友 @刺猬的温驯 说的连环炮)(图3)
(图1) (图2) (图3)
第三版源码
GrabTheBookV3.user.js
// ==UserScript== // @name Grab The Book // @author Xian Hong // @namespace http://www.cnblogs.com/xianhong/ // @description 抢汤姆大叔的书咯 // @include http://www.cnblogs.com/TomXu/archive/2012/10/22/2733027.html // ==/UserScript== function withjQuery(callback, safe) { if (typeof (jQuery) == "undefined") { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"; if (safe) { var cb = document.createElement("script"); cb.type = "text/javascript"; cb.textContent = "jQuery.noConflict();(" + callback.toString() + ")(jQuery);"; script.addEventListener('load', function () { document.head.appendChild(cb); }); } else { var dollar = undefined; if (typeof ($) != "undefined") dollar = $; script.addEventListener('load', function () { jQuery.noConflict(); $ = dollar; callback(jQuery); }); } document.head.appendChild(script); } else { callback(jQuery); } }; withjQuery(function ($) { Array.prototype.remove = function () { var newArr = new Array(); var a = arguments[0]; for (var i = 0; i < this.length; i++) { if (typeof (a) == "function") { if (!a(this[i])) newArr.push(this[i]); } else if (this[i] != a) { newArr.push(this[i]); } } return newArr; }; Array.prototype.find = function () { var args = arguments[0]; for (var i = 0; i < this.length; i++) { if (typeof (args) == "function") { if (args(this[i])) { return this[i]; } } } return false; }; var div = $("<div>", { html: '.', style: 'text-align:left;position: fixed;top: 10px;right: 10px;display: block;-webkit-text-size-adjust: none;font-size: 15px; 200px;background-color:white;' }).appendTo($(document.body)); $("<div>", { html: '<div style="background-color:white;">小时:<input type="text" style="50px;" id="txtHour" value="12"/>' + '当前时<input type="checkbox" id="chkCurrentHour" checked="checked" /><br />' + '分数:<input type="text" style="50px;" id="txtMinutes" value="0"/>' + '下一分<input type="checkbox" id="chkNextMinutes" checked="checked" /><br />' + '秒数:<input type="text" style="50px;" id="txtSecond" value="4"/><br />' + '毫秒:<input type="text" style="50px;" id="txtMilliseconds" value="150"/><br />' + '间隔:<input type="text" style="50px;" id="txtInterval" value="5"/>(ms)<br />' + '内容:<textarea id="txtComment" style="height:30px;100px;"></textarea><br />' + '<input type="button" id="btnExecSettings" value="执行设定" />' + '<input type="button" id="btnExec" value="添加任务" />' + '<br /> <a id="btnRemoveAll" href="javascript:;">[X]</a> 任务:</div><div id="taskContainer" style="background-color:white;"></div>', style: 'text-align:left;position: fixed;top: 40px;right: 10px;display: block;-webkit-text-size-adjust: none;font-size: 15px; 200px;height: 50px;background-color:white;' }).appendTo($(document.body)); var settings = { minutes: 0, //初始化抢书的分数 second: 4, //初始化本地时间的抢书秒数 milliseconds: 150, //初始化本地时间的抢书毫秒数 interval: 5 }; //获取当前时间 var getCurTime = function () { var curTime = new Date(); return { hour: curTime.getHours(), minutes: curTime.getMinutes(), second: curTime.getSeconds(), milliseconds: curTime.getMilliseconds() }; }; var strContent = ""; var grabTheBook = function () { var curTime = getCurTime(); var content = $("#txtComment").val() + " 本地时间:------------" + curTime.minutes + ":" + curTime.second + ":" + curTime.milliseconds; var comment = {}; comment.postId = cb_entryId; comment.Body = content; comment.ParentCommentID = 0; var startDate = new Date(); $.ajax({ url: '/mvc/PostComment/New.aspx', data: JSON.stringify(comment), type: "post", dataType: "json", contentType: "application/json; charset=utf8", success: function (data) { if (data) { var dt = (new Date()).getTime() - startDate; strContent += "提交耗时:" + dt + " 提交内容:" + content + "<br />"; ShowCommentMsg(strContent); } else { var errorMsg = "抱歉!评论提交失败!"; ShowCommentMsg(errorMsg); } }, error: function (xhr) { ShowCommentMsg("error:" + xhr.responseText); } }); }; var taskArray = []; var renderHtml = function () { $("#taskContainer").empty(); $(taskArray).each(function (i) { var task = this; if (typeof (this.h) != "function") { var removeE = $("<a>", { html: ' [X] ', href: 'javascript:;' }); var span = $('<span>', { html: '(' + (i + 1) + ')<<' + task.h + ":" + task.m + ":" + task.s + ":" + task.ms }); span.appendTo($("#taskContainer")); removeE.click(function () { task.breakFlag = true; taskArray = taskArray.remove(function (t) { return t.id == task.id; }); renderHtml(); }).appendTo(span); span.append("<br />"); } }); }; var id = 0; var templateFun = function (h, m, s, ms) { if (h && typeof (h) != "number") return; id++; m = m || settings.minutes; s = s || settings.second; ms = ms || settings.milliseconds; var task = { id: id, h: h, m: m, s: s, ms: ms, breakFlag: false }; taskArray.push(task); renderHtml(); var f = function () { if (task.breakFlag) return; var curTime = getCurTime(); div.html(curTime.hour + ':' + curTime.minutes + ":" + curTime.second + ":" + curTime.milliseconds); if (curTime.hour == h && curTime.minutes == m && curTime.second == s && curTime.milliseconds >= ms) { task.breakFlag = true; grabTheBook(); taskArray = taskArray.remove(function (t) { return t.id == task.id; }); renderHtml(); } else { setTimeout(f, settings.interval); //每间隔?毫秒执行一次 } }; return f; }; var settingFun = function () { var curTime = getCurTime(); settings.minutes = parseInt($("#txtMinutes").val()); settings.second = parseInt($("#txtSecond").val()); settings.milliseconds = parseInt($("#txtMilliseconds").val()); settings.interval = parseInt($("#txtInterval").val()); }; var removeAll = function () { $(taskArray).each(function () { var task = this; task.breakFlag = true; taskArray = taskArray.remove(function (t) { return t.id == task.id; }); renderHtml(); }); }; $("#btnRemoveAll").click(removeAll); $("#btnExecSettings").click(function () { settingFun(); removeAll(); templateFun(10)(); templateFun(12)(); templateFun(14)(); templateFun(16)(); templateFun(18)(); templateFun(20)(); }); $("#btnExec").click(function () { //点击按钮,重新为抢书秒数和抢书毫秒数赋值 settingFun(); var curTime = getCurTime(); var minite = $("#chkNextMinutes").attr("checked") ? curTime.minutes + 1 : parseInt($("#txtMinutes").val()); var hour = $("#chkCurrentHour").attr("checked") ? curTime.hour : parseInt($("#txtHour").val()); templateFun(hour, minite, parseInt($("#txtSecond").val()), parseInt($("#txtMilliseconds").val()))(); }); }, true);