您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
倒计时准时发兵
// ==UserScript== // @name Travian发兵助手 // @namespace http://tampermonkey.net/ // @version 0.52 // @description 倒计时准时发兵 // @author bingkx // @match https://*.travian.com/build.php?gid=16&tt=2 // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none // @run-at document-end // @license GPL3 // ==/UserScript== (function() { 'use strict'; // Your code here... (function (workerScript) { if (!/MSIE 10/i.test (navigator.userAgent)) { try { var blob = new Blob (["\ var fakeIdToId = {};\ onmessage = function (event) {\ var data = event.data,\ name = data.name,\ fakeId = data.fakeId,\ time;\ if(data.hasOwnProperty('time')) {\ time = data.time;\ }\ switch (name) {\ case 'setInterval':\ fakeIdToId[fakeId] = setInterval(function () {\ postMessage({fakeId: fakeId});\ }, time);\ break;\ case 'clearInterval':\ if (fakeIdToId.hasOwnProperty (fakeId)) {\ clearInterval(fakeIdToId[fakeId]);\ delete fakeIdToId[fakeId];\ }\ break;\ case 'setTimeout':\ fakeIdToId[fakeId] = setTimeout(function () {\ postMessage({fakeId: fakeId});\ if (fakeIdToId.hasOwnProperty (fakeId)) {\ delete fakeIdToId[fakeId];\ }\ }, time);\ break;\ case 'clearTimeout':\ if (fakeIdToId.hasOwnProperty (fakeId)) {\ clearTimeout(fakeIdToId[fakeId]);\ delete fakeIdToId[fakeId];\ }\ break;\ }\ }\ "]); // Obtain a blob URL reference to our worker 'file'. workerScript = window.URL.createObjectURL(blob); } catch (error) { /* Blob is not supported, use external script instead */ } } var worker, fakeIdToCallback = {}, lastFakeId = 0, maxFakeId = 0x7FFFFFFF, // 2 ^ 31 - 1, 31 bit, positive values of signed 32 bit integer logPrefix = 'HackTimer.js by turuslan: '; if (typeof (Worker) !== 'undefined') { function getFakeId () { do { if (lastFakeId == maxFakeId) { lastFakeId = 0; } else { lastFakeId ++; } } while (fakeIdToCallback.hasOwnProperty (lastFakeId)); return lastFakeId; } try { worker = new Worker (workerScript); window.setInterval = function (callback, time /* , parameters */) { var fakeId = getFakeId (); fakeIdToCallback[fakeId] = { callback: callback, parameters: Array.prototype.slice.call(arguments, 2) }; worker.postMessage ({ name: 'setInterval', fakeId: fakeId, time: time }); return fakeId; }; window.clearInterval = function (fakeId) { if (fakeIdToCallback.hasOwnProperty(fakeId)) { delete fakeIdToCallback[fakeId]; worker.postMessage ({ name: 'clearInterval', fakeId: fakeId }); } }; window.setTimeout = function (callback, time /* , parameters */) { var fakeId = getFakeId (); fakeIdToCallback[fakeId] = { callback: callback, parameters: Array.prototype.slice.call(arguments, 2), isTimeout: true }; worker.postMessage ({ name: 'setTimeout', fakeId: fakeId, time: time }); return fakeId; }; window.clearTimeout = function (fakeId) { if (fakeIdToCallback.hasOwnProperty(fakeId)) { delete fakeIdToCallback[fakeId]; worker.postMessage ({ name: 'clearTimeout', fakeId: fakeId }); } }; worker.onmessage = function (event) { var data = event.data, fakeId = data.fakeId, request, parameters, callback; if (fakeIdToCallback.hasOwnProperty(fakeId)) { request = fakeIdToCallback[fakeId]; callback = request.callback; parameters = request.parameters; if (request.hasOwnProperty ('isTimeout') && request.isTimeout) { delete fakeIdToCallback[fakeId]; } } if (typeof (callback) === 'string') { try { callback = new Function (callback); } catch (error) { console.log (logPrefix + 'Error parsing callback code string: ', error); } } if (typeof (callback) === 'function') { callback.apply (window, parameters); } }; worker.onerror = function (event) { console.log (event); }; } catch (error) { console.log (logPrefix + 'Initialisation failed'); console.error (error); } } else { console.log (logPrefix + 'Initialisation failed - HTML5 Web Worker is not supported'); } }) ('HackTimerWorker.js'); window.startFromStr = function (string, sStart, iCount) { var iPos = string.indexOf(sStart); if (iPos < 0) return ""; return string.substr(iPos + sStart.length, iCount); } window.endWithStr = function (string, sEnd) { var iPos = string.indexOf(sEnd); if (iPos < 0) return ""; return string.substr(0, iPos); } window.getStrBetween = function (string, start, end, maxLength) { if (maxLength == null) maxLength = 100;//default result string max length var result = startFromStr(string, start, maxLength + end.length); result = endWithStr(result, end); return result; } window.parseDecimal = function (str) { var result = parseInt(str, 10); if (isNaN(result)) { postMessage("无法解析的数字:" + str); return NaN; } else { return result; } } window.parseTime = function (str) { //str is like "0:29:45" var iHour = parseDecimal(endWithStr(str, ":")); str = startFromStr(str, ":", 50); var iMin = parseDecimal(endWithStr(str, ":")); str = startFromStr(str, ":", 50); var iSec = parseDecimal(str); var result = ((iHour * 60) + iMin) * 60 + iSec; if (isNaN(result)) { postMessage("无法解析的时间:" + str); return NaN; } else { return result; } } window.getTimed = function (time) { var timed = (parseTime(time.substr(0, 8)) + parseDecimal(time.substr(9, 1)) * 0.1) * 1000; return timed; } window.getAverage = function (arr) { if (arr && arr.length != 0) { var sum = 0; for (var i = 0; i < arr.length; i++) { sum = sum + arr[i]; } return Math.floor(sum / arr.length); } return 0; } window.getTimeDiff = function () { var startTime = getTimeStr(new Date()); var xhr = new XMLHttpRequest(); var url = "https://"+server+"/build.php?gid=16&tt=2"; xhr.open("GET", url, false); xhr.send(); var text = xhr.responseText; var info = getStrBetween(text, '<span format="24h" class="timer" counting="up" value="', "/span>", 200); info = getStrBetween(info, '>', "<", 200); var realMS = parseTime(info) * 1000 + 100; //We suppose that server floors millisecs instead of rounds them var estimateMS = (parseTime(startTime.substr(0, 8)) + parseDecimal(startTime.substr(9, 3)) * 0.001) * 1000; var diff = realMS - estimateMS; //postMessage("timeDiff:" + diff); return diff; } window.sendTroops = function () { var btn = document.getElementById("checksum"); if (btn) { setLocalStorage("TAR_running", "0"); btn.click(); } } window.getLocalStorage=function(lcProp){ if(lcProp){ return localStorage[lcProp]; } } window.setLocalStorage=function(lcProp, val){ if(lcProp){ localStorage[lcProp]=val; } } window.timeDiffs = []; window.timerAttackRefresh=function(){ //getTimeDiff(); //timerAttack(); var backBtn = document.getElementById("back"); if(!backBtn){ backBtn=document.getElementById("editWave-0"); } if(backBtn){ setLocalStorage("TAR_refresh","1"); backBtn.click(); return; } var okBtn= document.getElementById("ok"); if(okBtn){ setLocalStorage("TAR_refresh", "0"); okBtn.click(); return; } } window.timerAttack = function () { var arrTime = document.getElementById("time").value; setLocalStorage("TAR_time", arrTime); var dur = document.getElementById("in").innerText; dur = getStrBetween(dur, "剩餘時間", "小時", null); var durTime = parseTime(dur) * 1000; //ms arrTime = (parseTime(arrTime.substr(0, 8)) + parseDecimal(arrTime.substr(9, 3)) * 0.001) * 1000; //ms var nowStr = getTimeStr(new Date()); var iNow = (parseTime(nowStr.substr(0, 8)) + parseDecimal(nowStr.substr(9, 3)) * 0.001) * 1000; //var iNow = (new Date()).getTime(); //ms var timeOut = arrTime - iNow - durTime; if(timeOut<0){ //postMessage("当天不可到达,改第二天"); timeOut=timeOut+24*60*60*1000; //到第二天 } if (timeOut < 30 * 1000) { //时间小于20秒, 最后一次校准,出发 postMessage("时间小于30秒, 最后一次校准,马上出发"); var diff = getTimeDiff(); //ms nowStr = getTimeStr(new Date()); iNow = (parseTime(nowStr.substr(0, 8)) + parseDecimal(nowStr.substr(9, 3)) * 0.001) * 1000; timeDiffs.push(diff); var avgDiff = getAverage(timeDiffs); timeOut = arrTime - iNow - durTime - avgDiff; //postMessage("最后一次校准时差:" + diff); //postMessage("平均校准时差:" + diff); //postMessage("马上出发:" + timeOut); window.tarTimer=setTimeout(sendTroops, timeOut); return; } else if (timeOut > 60*60 * 1000){//大于1小时要每小时刷新,防止退出登录 postMessage("等待时间大于1小时,每小时刷新"); if(timeOut<65*60*1000){ timeOut=timeOut-5*60*1000; }else{ timeOut=3600*1000; } window.tarTimer=setTimeout(timerAttackRefresh, timeOut); return; }else if (timeOut > 2 * 60 * 1000) { //到大约2分钟再发起 postMessage("出发时间大于2分钟:" + timeOut); //??? nowStr = getTimeStr(new Date()); iNow = (parseTime(nowStr.substr(0, 8)) + parseDecimal(nowStr.substr(9, 3)) * 0.001) * 1000; timeOut = arrTime - iNow - durTime - 2 * 59 * 1000; postMessage("等待:" + timeOut); window.tarTimer=setTimeout(timerAttack, timeOut); return; } if (timeDiffs.length == 0) { for (var i = 0; i < 5; i++) { //初次校准5次取平均 var diff = getTimeDiff(); postMessage("第" + (i + 1) + "次校准,时差:" + diff + "毫秒"); timeDiffs.push(diff); } } else { var diff = getTimeDiff(); postMessage("单次校准,时差:" + diff + "毫秒"); timeDiffs.push(diff); } var avgDiff = getAverage(timeDiffs); //ms postMessage("平均校准时差:" + avgDiff + "毫秒"); nowStr = getTimeStr(new Date()); iNow = (parseTime(nowStr.substr(0, 8)) + parseDecimal(nowStr.substr(9, 3)) * 0.001) * 1000; var tot = arrTime - iNow - durTime - avgDiff; if(tot<0){ tot=tot+24*60*60*1000; } if (tot < 45 * 1000) { timeOut = tot - 20 * 1000; } else { timeOut = 25 * 1000; } postMessage("等待:" + timeOut + ",剩余:" + tot); window.tarTimer=setTimeout(timerAttack, timeOut); //25秒后再校准 } window.tarBtnOnClick=function(){ //var btnText="开始发兵"; if(getLocalStorage("TAR_running")=="1"){ clearTimeout(tarTimer); setLocalStorage("TAR_running", "0"); var btnText="开始发兵"; document.getElementById('tarBtn').innerHTML=btnText; }else{ setLocalStorage("TAR_running", "1"); timerAttack(); var btnText="取消发兵"; document.getElementById('tarBtn').innerHTML=btnText; } } window.getNowTimestamp = function () { var now = new Date(); var hour = "0" + now.getHours(); hour = hour.substr(hour.length - 2, 2); var min = "0" + now.getMinutes(); min = min.substr(min.length - 2, 2); var sec = "0" + now.getSeconds(); sec = sec.substr(sec.length - 2, 2); return now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate() + " " + hour + ":" + min + ":" + sec; //return new Date().toLocaleString(); } window.getTimeStr = function (date) { var timePos = date.toString().indexOf(":") - 2; var str = date.toString().substr(timePos, 8); var milliSec = date.getTime() % 1000; if (milliSec > 0) { var milliStr = "00" + milliSec; milliStr = milliStr.substr(milliStr.length - 3, 3); str += "." + milliStr; } return str; } window.g_sMessage = ""; window.postMessage = function (msg) { var nowTime=getNowTimestamp(); g_sMessage += nowTime + ": " + msg + "<br/>\r\n"; if (g_sMessage.length > 5000) g_sMessage = startFromStr(g_sMessage, "\r\n", 6000); document.getElementById('message').innerHTML = g_sMessage; var stoLog=getLocalStorage("travianLog"); stoLog+=nowTime + ": " + msg + "\r\n"; setLocalStorage("travianLog", stoLog); } window.server=""; window.getServer=function(){ server=getStrBetween(window.location.href, "https://", "/", null); } window.dragElement = function (elmnt, localStorageProp) { var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; elmnt.querySelector(`.${elmnt.id}__header`).onmousedown = dragMouseDown; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // get the mouse cursor position at startup: pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; // call a function whenever the cursor moves: document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // calculate the new cursor position: pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; // set the element's new position: elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; } function closeDragElement() { // stop moving when mouse button is released: document.onmouseup = null; document.onmousemove = null; if (elmnt.offsetLeft + elmnt.offsetWidth <= 50) { elmnt.style.left = 50 - elmnt.offsetWidth + "px"; } if (elmnt.offsetTop < 0) { elmnt.style.top = "0"; } if (localStorageProp !== undefined) { localStorage[localStorageProp] = JSON.stringify([elmnt.offsetTop, elmnt.offsetLeft]); } } } var cssText = (` .us-draggable { position: absolute; z-index: 9; background-color: #f1f1f1; border: 1px solid #d3d3d3; text-align: center !important; white-space: nowrap; } .us-draggable .us-draggable--header { padding: 8px; cursor: move; z-index: 10; background-color: #2196f3; color: #fff; } .us-draggable li { text-align: left; } .us-draggable ul { display: flex; flex-direction: column; justify-content: center; margin: 0 5px; padding: 0 0 0 16px; } .us-draggable td > a { display: block; padding: 14px; } .us-draggable td { padding: unset; } .us-draggable li.done { background-color: green; } .us-barBox { width: 50px; height: 7px; background-color: #52372a; margin: 0 2px; } .us-tmAttacker { display: flex; flex-direction: row; margin: 5px; } .us-bar { background-color: #699e32; height: 100%; } .us-resourceValue { font-size: 11px; font-weight: 700; text-align: end; margin-right: 2px; } .us--text-alert { color: #0022af; } .us-map-open { position: fixed !important; inset: 0 !important; width: unset !important; height: unset !important; } .us-alertFill--yellow { fill: yellow; } .us--display-block { display: block !important; } .us-settingsIconSVG > svg:hover { fill: whitesmoke; } .message { font-size: 11px; font-weight: 700; text-align: left; margin-right: 2px; } `); var insertCSS = function (cssStyle) { var style = document.createElement("style"); var theHead = document.head || document.getElementsByTagName('head')[0]; style.type = "text/css";//IE需要设置 if (style.styleSheet) { //IE var ieInsertCSS = function () { try { style.styleSheet.cssText = cssStyle; } catch (e) { } }; //若当前styleSheet不能使用,则放到异步中 if (style.styleSheet.disable) { setTimeout(ieInsertCSS, 10); } else { ieInsertCSS(); } } else { //W3c浏览器 style.appendChild(document.createTextNode(cssStyle)); theHead.appendChild(style); } } insertCSS(cssText); getServer(); if(getLocalStorage("TAR_refresh")=="1"){ timerAttackRefresh(); } if (document.getElementById("checksum")) { //确认是发兵页面 const localStorageProp = `us_tmAttacker_coords`; // get draggable element coordinates let localStorage_coords = localStorage[localStorageProp]; if (localStorage_coords === undefined) { localStorage_coords = [250, 0]; // top left localStorage[localStorageProp] = JSON.stringify(localStorage_coords); } else { localStorage_coords = JSON.parse(localStorage_coords); } const topTA = localStorage_coords[0]; const leftTA = localStorage_coords[1]; var arrTime=getLocalStorage("TAR_time"); if(!arrTime){ arrTime="23:00:00.4"; } var btnText="开始发兵"; if(getLocalStorage("TAR_running")=="1"){ btnText="取消发兵"; } const html = `<div id="us-tmAttacker" class="us-draggable" style="top:${topTA}px; left:${leftTA}px;"> <div class="us-tmAttacker__header us-draggable--header">TimerAttacker</div> <div>输入到达时间:<input id="time" type="text" value=${arrTime} size="12" /></div> <div class="us-draggable"><button id="tarBtn" onClick="tarBtnOnClick();">${btnText}</button></div> <br /> <br /><div class="message"> 消息记录:</div> <br /> <div id="message" class="message"></div> <br /> </div>`; document.body.insertAdjacentHTML("beforeend", html); dragElement(document.getElementById("us-tmAttacker"), localStorageProp); if(getLocalStorage("TAR_running")=="1"){ timerAttack(); } } })();