Hello There, Guest! Register

Misc Carbon's Front Line Coordinate Grabber
#1
Carbon's Front Line Coordinate Grabber
Run this script on Combined Overview
if you want all your villages Front line
 than make sure you have "All" village group selected
or if you would like the Front Line for a certain group of your 
villages front line data have that selected.

once the script is ran it will ask you for Max Noble Distance.
you have a few options with this.
you can enter the worlds max noble distance to get an idea what enemy villages
would be in range of a noble on that world.

if you want to see what villages are within a certain distance just enter that distance

if you want literally every players village coordinates set the distance to something very large like 10,000.

once it fetches all data it will display each players coordinates in the left text box
the right text box will show the coordinate and field distance.

the coordinates are nicely laid out to copy in the left text box or the right to save for later use/viewing.
Code:
javascript:(function () {

  if (!window.location.href.includes("=combined")) {
      alert("Please run this script on a page that includes '=combined' in the URL.");
      return;
  }

  const url = new URL(window.location.href);
  const server = url.hostname.split('.')[0];
  const activeVillage = url.searchParams.get('village');

  let userVillages = [];
  let playerVillages = {};
  let dataFetched = false;
  let loadingPopup = null;
  let initialPopup = null;
  let maxNobleDistance = 20;

  function calculateDistance(coord1, coord2) {
      const [x1, y1] = coord1.split('|').map(Number);
      const [x2, y2] = coord2.split('|').map(Number);
      return Math.round(Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y1 - y2, 2)));
  }

  async function fetchUserVillages() {
      const coordinates = [];
      let page = 1;

      while (true) {
          const response = await fetch(`${url.origin}${url.pathname}?village=${activeVillage}&screen=overview_villages&mode=combined`);
          const text = await response.text();
          const doc = new DOMParser().parseFromString(text, 'text/html');

          doc.querySelectorAll('a[href*="screen=overview"]')
              .forEach(link => {
                  const match = link.textContent.match(/^(\d+)\s\((\d+\|\d+)\)$/);
                  if (match) coordinates.push({ name: match[1], coords: match[2] });
              });

          if (!doc.querySelector(`a[href*="&page=${page + 1}"]`)) break;
          page++;
      }
      return coordinates;
  }

  async function fetchPlayerVillages() {
      const playerVillages = {};
      let rankingPage = 1;

      while (true) {
          const response = await fetch(`${url.origin}/game.php?village=${activeVillage}&screen=ranking&page=${rankingPage}`);
          const text = await response.text();
          const doc = new DOMParser().parseFromString(text, 'text/html');

          const playerLinks = Array.from(doc.querySelectorAll('a[href*="screen=info_player"]'));
          for (const playerLink of playerLinks) {
              const playerName = playerLink.textContent;
              const playerId = new URL(playerLink.href).searchParams.get('id');

              logLoadingMessage(`Fetching villages for ${playerName}...`);

              const fetchedVillages = await fetchVillagesForPlayer(playerId);

              const isUser = fetchedVillages.some(village => userVillages.some(u => u.coords === village));
              if (!isUser) {
                  playerVillages[playerName] = fetchedVillages;
              }
          }

          if (!doc.querySelector(`a[href*="&page=${rankingPage + 1}"]`)) break;
          rankingPage++;
      }

      return playerVillages;
  }

  async function fetchVillagesForPlayer(playerId) {
      const coordinates = [];
      let playerPage = 1;

      while (true) {
          const response = await fetch(`${url.origin}/game.php?village=${activeVillage}&screen=info_player&id=${playerId}&page=${playerPage}`);
          const text = await response.text();
          const doc = new DOMParser().parseFromString(text, 'text/html');

          doc.querySelectorAll('a[href*="screen=info_village"]')
              .forEach(link => {
                  const match = link.textContent.match(/\((\d+\|\d+)\)/);
                  if (match) coordinates.push(match[1]);
              });

          if (!doc.querySelector(`a[href*="&page=${playerPage + 1}"]`)) break;
          playerPage++;
      }

      return coordinates;
  }

  function createInitialPopup() {
      initialPopup = window.open('', '', 'width=400,height=300');
      initialPopup.document.title = "Carbon's Front Line Coordinate Grabber";
      initialPopup.document.body.style = 'font-family: Arial, sans-serif; background-color: #F4E4BC; color: #5D3E09; padding: 10px;';

      const title = initialPopup.document.createElement('h3');
      title.innerText = "Carbon's Front Line Coordinate Grabber";
      title.style = 'margin: 0; font-size: 14px; color: #5D3E09;';

      const form = initialPopup.document.createElement('form');
      form.innerHTML = `
          <label for="maxDistance" style="font-size: 13px;">Max Noble Distance:</label>
          <input type="number" id="maxDistance" min="1" max="1000" value="20" style="width: 100px; padding: 2px; margin: 5px 0; border: 1px solid #5D3E09;">
          <br><br>
          <button type="button" id="cancelButton" style="background-color: #DEC08B; color: #5D3E09; border: none; padding: 5px 10px; cursor: pointer;">Cancel</button>
          <button type="button" id="generateButton" style="background-color: #DEC08B; color: #5D3E09; border: none; padding: 5px 10px; cursor: pointer;">Generate Front Line</button>
      `;

      initialPopup.document.body.appendChild(title);
      initialPopup.document.body.appendChild(form);

      form.querySelector('#cancelButton').addEventListener('click', () => {
          initialPopup.close();
      });

      form.querySelector('#generateButton').addEventListener('click', () => {
          maxNobleDistance = parseInt(initialPopup.document.getElementById('maxDistance').value);
          initialPopup.close();
          if (!dataFetched) {
              showLoadingPopup();
          } else {
              generateFrontLinePopup();
          }
      });
  }

  function showLoadingPopup() {
      if (loadingPopup) return;
      loadingPopup = window.open('', '', 'width=300,height=200');
      loadingPopup.document.body.style = 'font-family: Arial, sans-serif; background-color: #F4E4BC; color: #5D3E09; padding: 10px;';
      loadingPopup.document.title = "Loading, This may take a while";

      const title = loadingPopup.document.createElement('h3');
      title.innerText = "Loading, This may take a while";
      title.style = 'margin: 0; font-size: 14px; color: #5D3E09;';

      const logArea = loadingPopup.document.createElement('div');
      logArea.id = 'logArea';
      logArea.style = 'white-space: pre-wrap; font-family: Arial, sans-serif; font-size: 12px; color: #5D3E09; margin-top: 10px;';

      loadingPopup.document.body.appendChild(title);
      loadingPopup.document.body.appendChild(logArea);
  }

  function logLoadingMessage(message) {
      if (!loadingPopup || !loadingPopup.document) return;
      const logArea = loadingPopup.document.getElementById('logArea');
      const currentLogs = logArea.innerText.split('\n').filter(Boolean);
      if (currentLogs.length >= 5) currentLogs.shift();
      currentLogs.push(message);
      logArea.innerText = currentLogs.join('\n');
  }

  function generateFrontLinePopup() {
      if (loadingPopup) loadingPopup.close();

      const popup = window.open('', '', 'width=800,height=600');
      popup.document.title = "Carbon's Front Line Coordinate Grabber";
      popup.document.body.style = 'font-family: Arial, sans-serif; background-color: #F4E4BC; color: #5D3E09; padding: 10px; display: flex; flex-direction: column; gap: 10px;';

      const title = popup.document.createElement('h3');
      title.innerText = "Carbon's Front Line Coordinate Grabber";
      title.style = 'margin: 0; font-size: 14px; color: #5D3E09; text-align: center;';

      popup.document.body.appendChild(title);

      for (const [player, villages] of Object.entries(playerVillages)) {
          let coordinates = '';
          let distances = [];

          for (const village of villages) {
              if (userVillages.some(v => v.coords === village)) continue;

              for (const userVillage of userVillages) {
                  const distance = calculateDistance(userVillage.coords, village);
                  if (distance <= maxNobleDistance) {
                      coordinates += village + '\n';
                      distances.push({
                          village,
                          userVillage: userVillage.name,
                          distance
                      });
                      break;
                  }
              }
          }

          distances.sort((a, b) => a.distance - b.distance);

          if (distances.length > 0) {
              const playerContainer = popup.document.createElement('div');
              playerContainer.style = 'display: flex; align-items: flex-start; gap: 10px;';

              const playerLabel = popup.document.createElement('h4');
              playerLabel.innerText = player;
              playerLabel.style = 'font-size: 14px; color: #5D3E09; margin: 0;';

              const coordBox = popup.document.createElement('textarea');
              coordBox.value = coordinates.trim();
              coordBox.readOnly = true;
              coordBox.style = 'width: 45%; height: 150px; padding: 5px; border: 1px solid #5D3E09; resize: none; font-family: Arial, sans-serif; font-size: 12px; color: #5D3E09; background-color: #FFF8E7;';

              const distanceBox = popup.document.createElement('textarea');
              distanceBox.value = distances.map(item => `${item.village} is ${item.distance} fields away from ${item.userVillage}`).join('\n');
              distanceBox.readOnly = true;
              distanceBox.style = 'width: 45%; height: 150px; padding: 5px; border: 1px solid #5D3E09; resize: none; font-family: Arial, sans-serif; font-size: 12px; color: #5D3E09; background-color: #FFF8E7;';

              coordBox.onscroll = () => (distanceBox.scrollTop = coordBox.scrollTop);
              distanceBox.onscroll = () => (coordBox.scrollTop = distanceBox.scrollTop);

              playerContainer.appendChild(playerLabel);
              playerContainer.appendChild(coordBox);
              playerContainer.appendChild(distanceBox);

              popup.document.body.appendChild(playerContainer);
          }
      }

      const instructionText = popup.document.createElement('p');
      instructionText.innerText = "Copy the Front Line Coordinates to use later.";
      instructionText.style = 'font-size: 13px; color: #5D3E09; margin-top: 10px; text-align: center;';
      popup.document.body.appendChild(instructionText);

      const closeButton = popup.document.createElement('button');
      closeButton.textContent = 'Close';
      closeButton.style = 'background-color: #DEC08B; color: #5D3E09; border: none; padding: 5px 10px; cursor: pointer; margin: 10px auto; display: block;';
      closeButton.addEventListener('click', () => {
          popup.close();
      });

      popup.document.body.appendChild(closeButton);
  }

  (function main() {
      createInitialPopup();

      Promise.all([fetchUserVillages(), fetchPlayerVillages()])
          .then(([userCoords, playerCoords]) => {
              userVillages = userCoords;
              playerVillages = playerCoords;
              dataFetched = true;

              if (loadingPopup) {
                  loadingPopup.close();
                  generateFrontLinePopup();
              }
          })
          .catch(error => {
              console.error("Error fetching data:", error);
              alert("Error fetching data. Please try again.");
              if (loadingPopup) loadingPopup.close();
          });
  })();
})();
Reply


Possibly Related Threads...
Thread Author Replies Views Last Post
  Commands Carbon's Attack Script Generator Carbon 0 210 08-10-2024, 13:44
Last Post: Carbon
  Commands Carbon's Mass Attack Planner Carbon 0 378 28-09-2024, 05:39
Last Post: Carbon
  Map/Coord Coordinate Grabber Carbon 0 242 22-09-2024, 06:27
Last Post: Carbon

Forum Jump:


Users browsing this thread: 1 Guest(s)
Current time: 23-11-2024, 12:35