您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Ver 1.6b Highlights planes and strips on mouseover and allows multiple commands to be issued in one line. Adds ability to assign routes to planes
// ==UserScript== // @name ATC-SIM Helper for Chrome // @namespace atchelper // @include http://www.atc-sim.com/atc.php // @include http://atc-sim.com/atc.php // @include http://www.atc-sim.com/simulator // @include http://atc-sim.com/simulator // @version 1.7 // @description Ver 1.6b Highlights planes and strips on mouseover and allows multiple commands to be issued in one line. Adds ability to assign routes to planes // ==/UserScript== // Notes // v1.7 fixed URL issue // v1.6a // fixed bug that did not show "simple" command results in status bar // v1.6 // Edited for use in chrome using tampermonkey // Added a statusbar since chrome does not have one // v1.5 // Fixed bug that did not properly clear out a plane's route if you commanded a different route before the first one was complete. // v1.4 // added ablity to specify a vector as the last waypoint in a route // fixed bug that kept script from working when using the non www URL // v1.3 // Corrected readback function for all commands. Now reads back results of all commands in a combo command // added ability to issue multipe waypoint clearance (V command) to planes and they will fly to the points in order // added up arrow now repeats the previous command with the plane you just clicked // L and R commands after a heading work now // v1.2 // Fixed bug that stopped readback working on single commands // v1.1 // added ability to issue multiple "C" commands on one line // Fixed bug that confused speed and heading // v1.0 // Highlights plane on mouseover of progress strip, highlight progress strip on mouseover of plane unsafeWindow.g_fn = new Array(); unsafeWindow.g_fnPl = new Array(); unsafeWindow.g_routes = new Array(); unsafeWindow.g_lastcmd = ""; unsafeWindow.fnAddMoStripEvent = function() { var objProgressStrips = unsafeWindow.frames["ProgressStrips"].document.getElementById("strips"); var id,cnt; divs = unsafeWindow.frames["ProgressStrips"].document.getElementsByTagName("div"); txt = divs.length; for(var i = 0; i < divs.length; i++) { id = divs[i].id; if(unsafeWindow.g_fn[id] != true) { txt += id + ":true, "; unsafeWindow.g_fn[id] = true; divs[i].addEventListener( "mouseover", function() {fnPlaneHighlite(id);}, false); divs[i].addEventListener( "mouseout", function() {fnPlaneLowlite(id);}, false); } else txt += id + ":false, "; } } unsafeWindow.fnAddMoPlaneEvent = function() { var objProgressStrips = unsafeWindow.document.getElementById("strips"); var id,cnt; divs = unsafeWindow.document.getElementsByClassName("SanSerif12"); txt = divs.length; for(var i = 0; i < divs.length; i++) { id = divs[i].id; if(unsafeWindow.g_fnPl[id] != true) { txt += id + ":true, "; unsafeWindow.g_fnPl[id] = true; divs[i].addEventListener( "mouseover", function() {fnStripHighlite(id);}, false); divs[i].addEventListener( "mouseout", function() {fnStripLowlite(id);}, false); } else txt += id + ":false, "; } } function fnPlaneHighlite(id) { var pln = unsafeWindow.document.getElementById(id); pln.style.color = "yellow"; pln.style.fontWeight = "bold"; } function fnPlaneLowlite(id) { var pln = unsafeWindow.document.getElementById(id); pln.style.color = "white"; pln.style.fontWeight = "normal"; } function fnStripHighlite(id) { var pln = unsafeWindow.frames["ProgressStrips"].document.getElementById(id); pln.style.border = "1px solid red"; } function fnStripLowlite(id) { var pln = unsafeWindow.frames["ProgressStrips"].document.getElementById(id); pln.style.border = "1px solid white"; } // *************************** // intercept the form submit and parse the commands ourself // *************************** function fnReProcess(e) { var x,cnt,y,v,i,w,z; var txt = new Array(); var found ; var test; var r = new Array(); w=""; var waypoints = false; if(e.keyCode == 38) { // up arrow... repeat previous command unsafeWindow.document.frmClearance.txtClearance.value += unsafeWindow.g_lastcmd.substr(unsafeWindow.g_lastcmd.indexOf(" ")) ; } if(e.keyCode == 27) { // esc unsafeWindow.document.frmClearance.txtClearance.value = ""; } if(e.keyCode == 13) { v = unsafeWindow.document.frmClearance.txtClearance.value; unsafeWindow.g_lastcmd = v; var inArr = v.toUpperCase().split(/\s+/); // split it up into separate commands. if(inArr[1] == "C") { // is it C cnt = 0; // we know next var goes with the C, whether it is a speed, dir, or waypoint for(x=2;x < inArr.length;x++) { if(inArr[x] != "") { // not blank if((inArr[x] != "S") && (inArr[x] != "X") && (inArr[x] != "EX") && (inArr[x] != "T") && (inArr[x] != "H") && (inArr[x] != "V")) { if(waypoints == true) { // we are reading waypoints into the route y=0; found = false; w = " Routed via: "; for(z=x;z < inArr.length;z++) { // store the route if(!isNaN(inArr[z]) && (inArr[z].length == 3) ) { // its a vector if((z+1)!=inArr.length) { // we aren't at the last entry in the route, throw an error myStatusBar.innerHTML = "Vector must be last entry in route."; unsafeWindow.document.frmClearance.txtClearance.value = ""; e.preventDefault(); return false; } r[y] = inArr[z]; // store the vector y++; w += inArr[z]; if((z+1)<inArr.length) w += "->"; } else { // its a waypoint for (i = 0; i < unsafeWindow.G_arrNavObjects.length; i++) { if ((unsafeWindow.G_arrNavObjects[i][0] == inArr[z]) && (unsafeWindow.G_arrNavObjects[i][1] > 0)) { // found the nav id and it's not a runway r[y] = inArr[z]; // store the NAVID y++; found = true; w += inArr[z]; if((z+1)<inArr.length) w += "->"; } } if(found == false) { // throw an error myStatusBar.innerHTML = inArr[z] + " is not a valid NAVID"; unsafeWindow.document.frmClearance.txtClearance.value = ""; e.preventDefault(); return false; } } found = false; } x=z; // dont process any more // if we get here, then all the NAVIDs were valid // declare the route var //alert(typeof unsafeWindow.g_routes[inArr[0]]); if(typeof unsafeWindow.g_routes[inArr[0]] === "undefined") { unsafeWindow.g_routes[inArr[0]] = {'rindx':0, 'route':Array()}; } for(z=0;z < r.length;z++) { // set the route for this plane. We double buffer in case the navid list has an error, it will not overwrite existing route unsafeWindow.g_routes[inArr[0]]['route'][z] = r[z]; } unsafeWindow.g_routes[inArr[0]]['rindx'] = 0; // set the waypoint to the first one in the list txt[cnt] = inArr[0] + " C " + unsafeWindow.g_routes[inArr[0]]['route'][0]; cnt++; } else { // not a waypoint // check to see if we should cancel a route clearance if(isNaN(inArr[x]) || (inArr[x].length == 3)) { // its a waypoint or vector if(typeof unsafeWindow.g_routes[inArr[0]] !== "undefined") { delete unsafeWindow.g_routes[inArr[0]]; w += " Route Clearance Canceled"; } } if(inArr.length > (x+1)) { // if theres something after this command // see if there is a trailing L or R if((inArr[x+1] == "L") || (inArr[x+1] == "R")) { txt[cnt] = inArr[0] + " " + inArr[1] + " " + inArr[x] + " " + inArr[x+1]; // [PLANEID] C [whatever the next command is] [L|R] cnt++; x++; } else { txt[cnt] = inArr[0] + " " + inArr[1] + " " + inArr[x]; // [PLANEID] C [whatever the next command is] cnt++; } } else { // nothing after this command so just put out the command txt[cnt] = inArr[0] + " " + inArr[1] + " " + inArr[x]; // [PLANEID] C [whatever the next command is] cnt++; } } } else { if(inArr[x] == "S") { // speed command if(inArr.length > (x+1)) { // make sure theres something after the S txt[cnt] = inArr[0] + " S " + inArr[x+1]; // [PLANEID] S [whatever the next command is] cnt++; x++; } } if((inArr[x] == "X") || (inArr[x] == "EX")) { // Expidite all commands for(y=0;y<txt.length;y++) { txt[y] += " X"; } } if(inArr[x] == "T") { // takeoff command txt[cnt] = inArr[0] + " T"; // [PLANEID] T cnt++; } if(inArr[x] == "H") { // hold command txt[cnt] = inArr[0] + " H"; // [PLANEID] H cnt++; } if(inArr[x] == "V") { // Next entries in the command are waypoints. waypoints = true; } } } } // send all the commands var winl,stat; for(y=0;y<(txt.length);y++) { unsafeWindow.document.frmClearance.txtClearance.value = txt[y]; unsafeWindow.fnParseInput(); if(y == 0) { //alert(window.status); winl = window.status + " "; } else { stat = window.status; winl += stat.substr(stat.indexOf(" ")) + " "; } } unsafeWindow.document.frmClearance.txtClearance.value = ""; myStatusBar.innerHTML = winl + w; e.preventDefault(); } else { // just a simple command //alert(window.status); unsafeWindow.fnParseInput(); //alert(window.status); myStatusBar.innerHTML = window.status; e.preventDefault(); } } return false; } function fnMyDistance(strFlightID, intObjectID) { if(typeof unsafeWindow.G_arrNavObjects[intObjectID] !== "undefined") { return Math.sqrt(Math.pow((unsafeWindow.G_objPlanes[strFlightID][2] + unsafeWindow.intXoffset - unsafeWindow.G_arrNavObjects[intObjectID][2]),2) + Math.pow((unsafeWindow.G_objPlanes[strFlightID][3] + unsafeWindow.intYoffset - unsafeWindow.G_arrNavObjects[intObjectID][3]),2)); } else { return "x"; } } unsafeWindow.fnWPCheck = function() { var cnt,ID,txt,d; var cnt =""; d = new String(); for(ID in unsafeWindow.G_objPlanes) { if(typeof unsafeWindow.g_routes[ID] !== "undefined") { // this plane has a route if((unsafeWindow.G_objPlanes[ID][7] == 0) && unsafeWindow.G_objPlanes[ID][11] === null) { // we've reached a waypoint. if(unsafeWindow.g_routes[ID]['route'].length > unsafeWindow.g_routes[ID]['rindx']+1) { // theres another waypoint in the route unsafeWindow.g_routes[ID]['rindx']++; txt = unsafeWindow.document.frmClearance.txtClearance.value; unsafeWindow.document.frmClearance.txtClearance.value = ID + " C " + unsafeWindow.g_routes[ID]['route'][unsafeWindow.g_routes[ID]['rindx']]; unsafeWindow.fnParseInput(); unsafeWindow.document.frmClearance.txtClearance.value = txt; } } } } if(cnt) myStatusBar.innerHTML = cnt } unsafeWindow.fnCleanup = function() { // cleans up vars created in GM when planes are no longer on screen var ID,cnt; // planes for(ID in unsafeWindow.g_fnPl) { if(!unsafeWindow.document.getElementById(ID)) { delete unsafeWindow.g_fnPl[ID] } } // progress strips for(ID in unsafeWindow.g_fn) { if(!unsafeWindow.frames["ProgressStrips"].document.getElementById(ID)) { delete unsafeWindow.g_fn[ID] } } // routes for(ID in unsafeWindow.g_routes) { if(!unsafeWindow.document.getElementById(ID)) { delete unsafeWindow.g_routes[ID] } } } var canvasbody, myStatusBar; canvasbody = document.getElementById('canvas'); if (canvasbody) { // create our own "status bar" myStatusBar = document.createElement('div'); myStatusBar.innerHTML = "Welcome to ATC-SIM"; myStatusBar.setAttribute("id", "myStatus"); myStatusBar.style.position="fixed"; myStatusBar.style.bottom="0"; myStatusBar.style.left="0"; myStatusBar.style.padding= "1px 4px 1px 3px"; myStatusBar.style.fontSize="12px"; myStatusBar.style.backgroundColor = "#cccccc"; canvasbody.insertBefore(myStatusBar, canvasbody.firstChild); } setInterval ( "fnAddMoStripEvent()", 2000 ); setInterval ( "fnAddMoPlaneEvent()", 2000 ); setInterval ( "fnWPCheck()", 2000 ); setInterval ( "fnCleanup()", 5000 ); unsafeWindow.document.frmClearance.txtClearance.addEventListener( "keydown", fnReProcess, false);