Hello There, Guest! Register

Share your scripts!
#4
Automated Report Sorting

[Image: report-1.png]
[Image: report-2.png]
[Image: report3.png]

Code:
javascript:const DEBUG = false;

const scriptConfig = {
   scriptData: {
       prefix: 'automateReports',
       name: 'Automate Reports',
       version: 'v1.0.0',
       author: 'Chase',
       authorUrl: '',
       helpLink: '',
   },
   allowedMarkets: [],
   allowedScreens: ['report'],
   allowedModes: ['all'],
   isDebug: DEBUG,
   enableCountApi: true,
};

let playerDatabase = {};

const extractUnitData = (doc, tableId) => {
   const table = doc.getElementById(tableId);
   if (!table) return null;

   const rows = table.querySelectorAll('tr');
   const unitTypes = Array.from(rows[0].querySelectorAll('td img')).map(img => img.title.toLowerCase().replace(/ /g, '_'));
   const quantities = Array.from(rows[1].querySelectorAll('td')).slice(1).map(td => parseInt(td.textContent, 10) || 0);

   const unitsData = {};
   unitTypes.forEach((unitType, index) => {
       unitsData[unitType] = quantities[index];
   });

   return unitsData;
};

const extractUnitsOutsideVillage = (doc) => {
   const thElements = doc.querySelectorAll('th');
   for (let th of thElements) {
       if (th.textContent.trim() === 'Units outside village:') {
           const table = th.parentElement.nextElementSibling.querySelector('table');
           if (!table) return null;

           const rows = table.querySelectorAll('tr');
           const unitTypes = Array.from(rows[0].querySelectorAll('th img')).map(img => img.title.toLowerCase().replace(/ /g, '_'));
           const quantities = Array.from(rows[1].querySelectorAll('td')).map(td => parseInt(td.textContent, 10) || 0);

           const unitsData = {};
           unitTypes.forEach((unitType, index) => {
               unitsData[unitType] = quantities[index];
           });

           return unitsData;
       }
   }
   return null;
};

const fetchReportData = async (url, retryCount = 3) => {
   if (!url.startsWith('http')) {
       console.error(`Invalid URL: ${url}`);
       return null;
   }
   try {
       const response = await fetch(url);
       if (!response.ok) {
           if (response.status === 520 && retryCount > 0) {
               console.warn(`Encountered 520 error, retrying... (${3 - retryCount + 1})`);
               await new Promise(res => setTimeout(res, 2000));
               return fetchReportData(url, retryCount - 1);
           }
           throw new Error(`HTTP error! Status: ${response.status}`);
       }
       const text = await response.text();
       const parser = new DOMParser();
       const doc = parser.parseFromString(text, 'text/html');

       const findPlayerData = (label) => {
           const thElements = doc.querySelectorAll('th');
           for (let th of thElements) {
               if (th.textContent.trim() === label) {
                   const playerLink = th.nextElementSibling.querySelector('a[href*="screen=info_player"]');
                   const villageLink = th.closest('table').querySelector('a[href*="screen=info_village"]');
                   const playerName = playerLink ? playerLink.textContent.trim() : 'Unknown';
                   const villageCoords = villageLink ? villageLink.textContent.trim().match(/\d+\|\d+/)[0] : 'Unknown';
                   return { playerName, villageCoords };
               }
           }
           return null;
       };

       const attacker = findPlayerData('Attacker:');
       const defender = findPlayerData('Defender:');
       const attackerUnits = extractUnitData(doc, 'attack_info_att_units');
       const defenderUnits = extractUnitData(doc, 'attack_info_def_units');
       const unitsOutside = extractUnitsOutsideVillage(doc);

       return {
           attacker: { ...attacker, units: attackerUnits },
           defender: { ...defender, units: defenderUnits },
           unitsOutside,
           reportPageLink: url,
       };
   } catch (error) {
       console.error('Error fetching report data:', error);
       return null;
   }
};

const classifyUnits = (units, unitsOutside) => {
   const offensiveUnits = ['axe', 'light_cavalry'];
   const defensiveUnits = ['spear', 'sword', 'heavy_cavalry'];

   let offensiveCount = 0;
   let defensiveCount = 0;

   const countUnits = (units) => {
       if (!units) return;
       for (const [unitType, count] of Object.entries(units)) {
           if (offensiveUnits.includes(unitType)) {
               offensiveCount += count;
           } else if (defensiveUnits.includes(unitType)) {
               defensiveCount += count;
           }
       }
   };

   countUnits(units);
   countUnits(unitsOutside);

   if (offensiveCount > defensiveCount) {
       return 'offensive';
   } else if (defensiveCount > offensiveCount) {
       return 'defensive';
   } else {
       return 'unknown';
   }
};

const countVillages = () => {
   for (const playerName in playerDatabase) {
       const playerData = playerDatabase[playerName];
       let offensiveCount = 0;
       let defensiveCount = 0;

       for (const villageCoords in playerData.villages) {
           const villageData = playerData.villages[villageCoords];
           if (villageData.classification === 'offensive') {
               offensiveCount++;
           } else if (villageData.classification === 'defensive') {
               defensiveCount++;
           }
       }

       playerData.offensiveCount = offensiveCount;
       playerData.defensiveCount = defensiveCount;
   }
};

const processReports = async () => {
   const reportLinks = document.querySelectorAll('a[href*="view="]');
   const validReportLinks = Array.from(reportLinks).filter(link => link.href.startsWith('http'));
   const reportPromises = validReportLinks.map(async (link) => {
       const reportPageLink = link.href;
       const reportData = await fetchReportData(reportPageLink);
       if (reportData) {
           const { attacker, defender, unitsOutside } = reportData;

           if (attacker && attacker.units) {
               const classification = classifyUnits(attacker.units, unitsOutside);
               if (!playerDatabase[attacker.playerName]) {
                   playerDatabase[attacker.playerName] = { villages: {} };
               }
               playerDatabase[attacker.playerName].villages[attacker.villageCoords] = {
                   classification,
                   reportLink: reportPageLink,
                   units: attacker.units,
                   unitsOutside,
               };
           }

           if (defender && defender.units) {
               const classification = classifyUnits(defender.units, unitsOutside);
               if (!playerDatabase[defender.playerName]) {
                   playerDatabase[defender.playerName] = { villages: {} };
               }
               playerDatabase[defender.playerName].villages[defender.villageCoords] = {
                   classification,
                   reportLink: reportPageLink,
                   units: defender.units,
                   unitsOutside,
               };
           }
       }
   });

   await Promise.all(reportPromises);
   countVillages();
   updatePlayerList();
};

const generateNotebookEntry = () => {
   let notebookEntry = '';

   Object.keys(playerDatabase).forEach(playerName => {
       const playerData = playerDatabase[playerName];
       notebookEntry += `[player]${playerName}[/player]\n`;

       const villages = [];

       Object.keys(playerData.villages).forEach(villageCoords => {
           const villageData = playerData.villages[villageCoords];
           const classification = villageData.classification === 'offensive' ? '[color=#ae0e0e]OFFENSIVE[/color]' : '[color=#0e0eae]DEFENSE[/color]';
           villages.push(`[village]${villageCoords}[/village] - ${classification}`);
       });

       notebookEntry += villages.join('\n') + '\n\n';
   });

   return notebookEntry;
};

const copyNotebookEntryToClipboard = () => {
   const notebookEntry = generateNotebookEntry();
   const tempTextArea = document.createElement('textarea');
   tempTextArea.value = notebookEntry;
   document.body.appendChild(tempTextArea);
   tempTextArea.select();
   document.execCommand('copy');
   document.body.removeChild(tempTextArea);
   alert('Notebook entry copied to clipboard!');
};

const updatePlayerList = () => {
   const playerListContainer = document.querySelector('#playerListContainer');
   playerListContainer.innerHTML = '';
   for (const playerName in playerDatabase) {
       const playerData = playerDatabase[playerName];
       const playerButton = document.createElement('button');
       playerButton.textContent = `${playerName} (O: ${playerData.offensiveCount}, D: ${playerData.defensiveCount})`;
       playerButton.onclick = () => showPlayerData(playerName);
       playerListContainer.appendChild(playerButton);
   }
};

const showPlayerData = (playerName) => {
   const playerData = playerDatabase[playerName];
   const offensiveVillages = [];
   const defensiveVillages = [];

   for (const villageCoords in playerData.villages) {
       const villageData = playerData.villages[villageCoords];
       if (villageData.classification === 'offensive') {
           offensiveVillages.push(villageCoords);
       } else if (villageData.classification === 'defensive') {
           defensiveVillages.push(villageCoords);
       }
   }

   const offensiveCount = playerData.offensiveCount || 0;
   const defensiveCount = playerData.defensiveCount || 0;

   const popupContent = `
       <div>
           <h3>${playerName}</h3>
           <p>Total Offensive Villages: ${offensiveCount}</p>
           <p>Total Defensive Villages: ${defensiveCount}</p>
           <textarea id="offensiveCoords" rows="10" cols="60">${offensiveVillages.join('\n')}</textarea>
           <button onclick="copyToClipboard('offensiveCoords')">Copy Offensive Coordinates</button>
           <textarea id="defensiveCoords" rows="10" cols="60">${defensiveVillages.join('\n')} </textarea>
           <button onclick="copyToClipboard('defensiveCoords')">Copy Defensive Coordinates</button>
       </div>
   `;

   const popup = window.open('', 'Player Data', 'width=800,height=600,scrollbars=yes');
   popup.document.write(popupContent);
   popup.document.close();
};

const copyToClipboard = (elementId) => {
   const textarea = document.getElementById(elementId);
   textarea.select();
   document.execCommand('copy');
   alert('Coordinates copied to clipboard!');
};

const exportData = () => {
   const dataStr = JSON.stringify(playerDatabase, null, 2);
   const dataBlob = new Blob([dataStr], { type: 'application/json' });
   const url = URL.createObjectURL(dataBlob);
   const a = document.createElement('a');
   a.href = url;
   a.download = 'playerDatabase.json';
   a.click();
   URL.revokeObjectURL(url);
};

const viewData = () => {
   const popup = window.open('', 'Player Data', 'width=800,height=600,scrollbars=yes');
   const dataStr = JSON.stringify(playerDatabase, null, 2);
   popup.document.write('<pre>' + dataStr + '</pre>');
   popup.document.close();
};

const isValidScreen = location.search.includes('screen=report');
const isValidMode = location.search.includes('mode=all');
if (isValidScreen && isValidMode) {
   const content = `
       <div class="ra-mb15">
           <a href="javascript:void(0);" id="raProcessReportsBtn" class="btn">Automate Reports</a>
           <a href="javascript:void(0);" id="raCopyNotebookEntryBtn" class="btn">Copy to Clipboard</a>
           <a href="javascript:void(0);" id="raExportDataBtn" class="btn">Export Data</a>
           <a href="javascript:void(0);" id="raViewDataBtn" class="btn">View Data</a>
       </div>
       <div id="playerListContainer" class="ra-mb15"></div>
   `;
   const widget = document.createElement('div');
   widget.innerHTML = content;
   const contentValue = document.getElementById('content_value');
   contentValue.insertBefore(widget, contentValue.firstChild);

   document.querySelector('#raProcessReportsBtn').addEventListener('click', processReports);
   document.querySelector('#raCopyNotebookEntryBtn').addEventListener('click', copyNotebookEntryToClipboard);
   document.querySelector('#raExportDataBtn').addEventListener('click', exportData);
   document.querySelector('#raViewDataBtn').addEventListener('click', viewData);
} else {
   console.log('Redirecting...');
   location.href = 'https://w1.infernal-wars.com/game.php?village=21&screen=report&mode=all';
}
[Image: Chase-Banner.png]
Reply


Messages In This Thread
Share your scripts! - by Chase - 12-07-2024, 10:51
RE: Share your scripts! - by Chase - 14-07-2024, 04:46
RE: Share your scripts! - by Chase - 14-07-2024, 05:07
RE: Share your scripts! - by Chase - 17-07-2024, 13:24

Forum Jump:


Users browsing this thread: 1 Guest(s)
Current time: 22-10-2024, 08:33