您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
testie
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/539479/1607869/defens%20finder.js
Tabs.Defend = { tabOrder: 1000, tabLabel: 'Defend', tabDisabled: false, myDiv: null, timer: null, defendingCities: [], mapScanInProgress: false, mapScanX: 0, mapScanY: 0, mapScanRadius: 10, mapScanDelay: 500, // ms between map tile checks init: function(div) { var t = Tabs.Defend; t.myDiv = div; div.innerHTML = '<DIV class=divHeader align=center>' + tx('Defending Cities Scanner') + '</DIV>' + '<DIV id=btDefendMain class=btPopMain style="height:100%">' + '<CENTER><BR><DIV id=btDefendStatus style="min-width:400px;height:20px;font-weight:bold;"></DIV></CENTER>' + '<DIV id=btDefendOptions>' + '<TABLE width=100% class=xtab><TR>' + '<TD><B>Scan Center:</B> X: <INPUT id=btDefendScanX type=text size=3 maxlength=3 value="' + uW.currentcityid.x + '" /> ' + 'Y: <INPUT id=btDefendScanY type=text size=3 maxlength=3 value="' + uW.currentcityid.y + '" /></TD>' + '<TD>Radius: <INPUT id=btDefendScanRadius type=text size=2 maxlength=2 value="10" /></TD>' + '<TD align=right><INPUT id=btDefendScanMap type=button value="Scan Map" /></TD>' + '</TR></TABLE>' + '<HR>' + '<TABLE width=100% class=xtab><TR>' + '<TD><INPUT id=btDefendShowOwn type=checkbox checked /> Show my cities</TD>' + '<TD><INPUT id=btDefendShowAlliance type=checkbox checked /> Show alliance cities</TD>' + '<TD><INPUT id=btDefendShowOthers type=checkbox checked /> Show enemy cities</TD>' + '</TR></TABLE>' + '</DIV>' + '<DIV id=btDefendProgress style="width:100%;height:20px;margin-top:5px;display:none;">' + '<DIV style="width:100%;height:10px;background-color:#ddd;border:1px solid #888;">' + '<DIV id=btDefendProgressBar style="width:0%;height:10px;background-color:#00a;"></DIV>' + '</DIV>' + '<DIV id=btDefendProgressText style="text-align:center;font-size:10px;margin-top:2px;"></DIV>' + '</DIV>' + '<DIV id=btDefendCityList style="max-height:400px; overflow-y:auto;margin-top:10px;"></DIV>' + '</DIV>'; // Event listeners ById('btDefendScanMap').addEventListener('click', t.startMapScan, false); ById('btDefendShowOwn').addEventListener('change', t.filterResults, false); ById('btDefendShowAlliance').addEventListener('change', t.filterResults, false); ById('btDefendShowOthers').addEventListener('change', t.filterResults, false); // Initial message ById('btDefendStatus').innerHTML = 'Ready to scan for defending cities on the map'; }, show: function() { var t = Tabs.Defend; // Update center coordinates to current city when tab is shown if (uW.currentcityid) { ById('btDefendScanX').value = uW.currentcityid.x; ById('btDefendScanY').value = uW.currentcityid.y; } }, hide: function() { var t = Tabs.Defend; // Stop any ongoing scan when tab is hidden t.stopMapScan(); }, startMapScan: function() { var t = Tabs.Defend; if (t.mapScanInProgress) { t.stopMapScan(); return; } // Get scan parameters t.mapScanX = parseInt(ById('btDefendScanX').value); t.mapScanY = parseInt(ById('btDefendScanY').value); t.mapScanRadius = parseInt(ById('btDefendScanRadius').value); // Validate inputs if (isNaN(t.mapScanX) || isNaN(t.mapScanY) || isNaN(t.mapScanRadius)) { ById('btDefendStatus').innerHTML = '<SPAN style="color:#800;">Invalid coordinates or radius!</SPAN>'; return; } if (t.mapScanRadius < 1) t.mapScanRadius = 1; if (t.mapScanRadius > 35) t.mapScanRadius = 35; // Limit to reasonable size // Reset results t.defendingCities = []; t.mapScanInProgress = true; ById('btDefendScanMap').value = "Stop Scan"; // Show progress bar ById('btDefendProgress').style.display = ''; ById('btDefendProgressBar').style.width = '0%'; ById('btDefendProgressText').innerHTML = 'Preparing scan...'; ById('btDefendStatus').innerHTML = 'Scanning map for defending cities...'; // Create list of coordinates to scan t.scanCoords = []; for (var x = t.mapScanX - t.mapScanRadius; x <= t.mapScanX + t.mapScanRadius; x++) { for (var y = t.mapScanY - t.mapScanRadius; y <= t.mapScanY + t.mapScanRadius; y++) { // Check if coordinates are within map bounds if (x >= 0 && x <= 749 && y >= 0 && y <= 749) { // Calculate distance from center var dist = Math.sqrt(Math.pow(x - t.mapScanX, 2) + Math.pow(y - t.mapScanY, 2)); if (dist <= t.mapScanRadius) { t.scanCoords.push({x: x, y: y}); } } } } t.totalTiles = t.scanCoords.length; t.tilesScanned = 0; // Start scanning t.scanNextTile(); }, scanNextTile: function() { var t = Tabs.Defend; if (!t.mapScanInProgress || t.scanCoords.length === 0) { t.finishMapScan(); return; } // Get next coordinate to scan var coord = t.scanCoords.shift(); t.tilesScanned++; // Update progress var progress = Math.floor((t.tilesScanned / t.totalTiles) * 100); ById('btDefendProgressBar').style.width = progress + '%'; ById('btDefendProgressText').innerHTML = 'Scanning: ' + t.tilesScanned + ' / ' + t.totalTiles + ' tiles'; // Check map data for this tile uW.cm.MapController.fetchTileData(coord.x, coord.y, function(result) { if (result && result.tileInfo) { var tile = result.tileInfo; // Check if it's a city and if it's defending if (tile.tileType == 51 && tile.cityInfo) { // 51 is city tile type var cityInfo = tile.cityInfo; // Check if city is defending (look for defense status or defense boost) var isDefending = false; // Method 1: Check defense status directly if available if (cityInfo.defStatus && cityInfo.defStatus == 1) { isDefending = true; } // Method 2: Check for defense boost effects if (cityInfo.effects) { for (var i = 0; i < cityInfo.effects.length; i++) { var effect = cityInfo.effects[i]; // Defense boost effects typically have IDs in certain ranges // This is an approximation - actual IDs may vary if (DefenceEffects.indexOf(effect.effectId) >= 0) { isDefending = true; break; } } } if (isDefending) { // Determine ownership type var ownerType = "enemy"; if (cityInfo.playerId == uW.tvuid) { ownerType = "own"; } else if (cityInfo.allianceId && cityInfo.allianceId == uW.seed.allianceInfo.allianceId) { ownerType = "alliance"; } t.defendingCities.push({ x: coord.x, y: coord.y, name: cityInfo.cityName || "Unknown City", ownerName: cityInfo.playerName || "Unknown Player", ownerType: ownerType, might: cityInfo.totalMight || 0 }); } } } // Schedule next tile scan with delay to prevent server overload setTimeout(t.scanNextTile, t.mapScanDelay); }); }, stopMapScan: function() { var t = Tabs.Defend; t.mapScanInProgress = false; ById('btDefendScanMap').value = "Scan Map"; ById('btDefendStatus').innerHTML = 'Scan stopped. Found ' + t.defendingCities.length + ' defending cities.'; }, finishMapScan: function() { var t = Tabs.Defend; t.mapScanInProgress = false; ById('btDefendScanMap').value = "Scan Map"; ById('btDefendStatus').innerHTML = 'Scan complete! Found ' + t.defendingCities.length + ' defending cities.'; ById('btDefendProgress').style.display = 'none'; // Display results t.displayResults(); }, filterResults: function() { var t = Tabs.Defend; t.displayResults(); }, displayResults: function() { var t = Tabs.Defend; // Get filter settings var showOwn = ById('btDefendShowOwn').checked; var showAlliance = ById('btDefendShowAlliance').checked; var showOthers = ById('btDefendShowOthers').checked; // Filter cities based on settings var filteredCities = t.defendingCities.filter(function(city) { if (city.ownerType === "own" && !showOwn) return false; if (city.ownerType === "alliance" && !showAlliance) return false; if (city.ownerType === "enemy" && !showOthers) return false; return true; }); var m = '<TABLE width=100% class=xtab><TR class="xtabHD">' + '<TD width=15%>Coordinates</TD>' + '<TD width=25%>City Name</TD>' + '<TD width=25%>Owner</TD>' + '<TD width=15%>Might</TD>' + '<TD width=20%>Actions</TD></TR>'; if (filteredCities.length === 0) { m += '<TR><TD colspan=5 align=center><BR><SPAN style="color:#800;">No defending cities found matching your filters.</SPAN></TD></TR>'; } else { // Sort cities by distance from scan center filteredCities.sort(function(a, b) { var distA = Math.sqrt(Math.pow(a.x - t.mapScanX, 2) + Math.pow(a.y - t.mapScanY, 2)); var distB = Math.sqrt(Math.pow(b.x - t.mapScanX, 2) + Math.pow(b.y - t.mapScanY, 2)); return distA - distB; }); for (var i = 0; i < filteredCities.length; i++) { var city = filteredCities[i]; var rowClass = i % 2 ? 'evenRow' : 'oddRow'; var ownerColor = '#000'; // Color-code by owner type if (city.ownerType === "own") { ownerColor = '#080'; // Green for own cities } else if (city.ownerType === "alliance") { ownerColor = '#008'; // Blue for alliance cities } else { ownerColor = '#800'; // Red for enemy cities } m += '<TR class="' + rowClass + '">' + '<TD>(' + city.x + ',' + city.y + ')</TD>' + '<TD>' + city.name + '</TD>' + '<TD style="color:' + ownerColor + ';">' + city.ownerName + '</TD>' + '<TD>' + addCommas(city.might) + '</TD>' + '<TD>' + '<INPUT type=button value="View" class="btDefendViewMap" x="' + city.x + '" y="' + city.y + '" /> '; // Add attack button for enemy cities if (city.ownerType === "enemy") { m += '<INPUT type=button value="Attack" class="btDefendAttack" x="' + city.x + '" y="' + city.y + '" />'; } m += '</TD></TR>'; } } m += '</TABLE>'; ById('btDefendCityList').innerHTML = m; // Add event listeners to buttons var mapButtons = document.getElementsByClassName('btDefendViewMap'); for (var i = 0; i < mapButtons.length; i++) { mapButtons[i].addEventListener('click', function() { var x = parseInt(this.getAttribute('x')); var y = parseInt(this.getAttribute('y')); uW.cm.MapController.centerMapOnCoord(x, y); }, false); } var attackButtons = document.getElementsByClassName('btDefendAttack'); for (var i = 0; i < attackButtons.length; i++) { attackButtons[i].addEventListener('click', function() { var x = parseInt(this.getAttribute('x')); var y = parseInt(this.getAttribute('y')); t.prepareAttack(x, y); }, false); } }, prepareAttack: function(x, y) { var t = Tabs.Defend; // Center map on target uW.cm.MapController.centerMapOnCoord(x, y); // Open attack dialog setTimeout(function() { // Find the city tile and click it var cityDiv = document.querySelector('div[data-tileclass="city"][data-x="' + x + '"][data-y="' + y + '"]'); if (cityDiv) { nHtml.Click(cityDiv); // Wait for city info popup to appear setTimeout(function() { // Find and click the attack button var attackBtn = document.querySelector('.cityInfoAttackButton'); if (attackBtn) { nHtml.Click(attackBtn); } else { actionLog('Could not find attack button for city at ' + x + ',' + y, 'DEFEND'); } }, 1000); } else { actionLog('Could not find city at ' + x + ',' + y + ' on the map', 'DEFEND'); } }, 1000); }, // Helper function to detect if a city is defending isCityDefending: function(cityInfo) { // This is a more comprehensive check for defending status // Check direct defense status if available if (cityInfo.defStatus && cityInfo.defStatus == 1) { return true; } // Check for defense-related effects if (cityInfo.effects) { for (var i = 0; i < cityInfo.effects.length; i++) { var effectId = cityInfo.effects[i].effectId; // Check against known defense effect IDs if (DefenceEffects.indexOf(effectId) >= 0) { return true; } // Additional checks for specific defense effects // These IDs may need to be adjusted based on the game's current effect system if ([2, 18, 25, 30, 35, 40, 45, 51].indexOf(effectId) >= 0) { return true; } } } // Check for defense boost items if (cityInfo.activeItems) { for (var i = 0; i < cityInfo.activeItems.length; i++) { var item = cityInfo.activeItems[i]; // Shield items typically have IDs like 362, 363, etc. if ([362, 363, 364, 365, 366].indexOf(item.itemId) >= 0) { return true; } } } return false; } };
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址