twCheese
Would you like to react to this message? Create an account in a few clicks or log in to continue.
Navigation
 Portal
 Index
 Memberlist
 Profile
 FAQ
 Search

ReportReader.js

Go down

ReportReader.js Empty ReportReader.js

Post  cheesasaurus Sat Jul 10, 2010 9:36 am

version 3.0
*redesigned the concept and scrapped the old version.

version 3.0_04 July 8, 2010
*released

version 3.0_05 July 9, 2010
*removed 'alert mode' from debugger

version 3.0_06 July 11, 2010
*added checkers to all reader methods in preparation to expand the reader to be used on all reports, not just battle reports

cheesasaurus
Admin

Posts : 27
Join date : 2008-04-20

https://twcheese.board-directory.net

Back to top Go down

ReportReader.js Empty Re: ReportReader.js

Post  cheesasaurus Sat Aug 21, 2010 12:24 am

version 3.0_06
Code:
javascript:
/**
 * ReportReader.js
 * @author   Nick Toby (cheesasaurus@gmail.com)
 * @version   3.0_06
 * contains functions for reading an english Tribal Wars battle report
 */

/*==== object templates ====*/

/**
 * Reinforcements template
 * @attribute   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)   - the troop count of the army supporting
 * @attribute   village:Array(x,y,id)   - the information about the village being supported.
 */
function Reinforcements()
{
   this.troops = new Array(0,0,0,0,0,0,0,0,0,0,0,0);
   this.village = new Array(0,0,0);
}

/**
 * Report Reader template
 * @param   gameDocument:HTMLDocument
 */
function ReportReader(gameDocument)
{   
   try
   {
      this.gameDocument = gameDocument;
      this.attackerTable = gameDocument.getElementById('attack_info_att');
      this.attackerUnitsTable = gameDocument.getElementById('attack_info_att_units');
      this.defenderTable = gameDocument.getElementById('attack_info_def');
      this.defenderUnitsTable = gameDocument.getElementById('attack_info_def_units');
      this.espionageTable = gameDocument.getElementById('attack_spy');
      this.resultsTable = gameDocument.getElementById('attack_results');
      this.supportKilledTable = gameDocument.getElementById('attack_away_units');
      
      /* functions */
      
      /**
       * @return   player:Array(id,name)
       */
      this.getAttacker = function()
      {
         if(this.attackerTable)
            return getPlayerInfo(this.attackerTable.rows[0].cells[1].firstChild);
      };

      /**
       * @return   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)
       */
      this.getAttackerLosses = function()
      {
         if(this.attackerUnitsTable)
            return getTroopCount(removeTroopsLabel(this.attackerUnitsTable.rows[2]));   
      };
      
      /**
       * @return   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)
       */
      this.getAttackerQuantity = function()
      {
         if(this.attackerUnitsTable)
            return getTroopCount(removeTroopsLabel(this.attackerUnitsTable.rows[1]));   
      };
      
      /**
       * @return   village:Array(x,y,id)
       */
      this.getAttackerVillage = function()
      {
         if(this.attackerTable)
            return getVillageInfo(this.attackerTable.rows[1].cells[1].firstChild);
      };

      /**
       * @return   buildingLevels:Array()
       * if no buildings were scouted, returns boolean false
       * -------------------
       * Building      Index
       * hq:         0
       * barracks:   1
       * stable:      2
       * workshop:   3
       * church:      4
       * church_f:   5
       * academy:      6
       * smithy:      7
       * rally:      8
       * statue:      9
       * market:      10
       * timber:      11
       * clay:      12
       * iron:      13
       * farm:      14
       * warehouse:   15
       * hiding:      16
       * wall:      17
       */
      this.getBuildingLevels = function()
      {
         if(this.getEspionageLevel() >= 2)
         {
            var buildingLevels = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
            var buildingNames = new Array('village headquarters','barracks','stable','workshop','church','first church','academy','smithy','rally point','statue','market','timber camp','clay pit','iron mine','farm','warehouse','hiding place','wall');
            var buildingsStringSplit = this.espionageTable.getElementsByTagName('td')[1].innerHTML.toLowerCase().split('br');
            for(i = 0; i < buildingsStringSplit.length; i++)
            {
               for(n = 0; n < 18; n++)
               {
                  if(buildingsStringSplit[i].search(buildingNames[n]) != -1)
                  {
                     buildingLevels[n] = Number(buildingsStringSplit[i].substring(buildingsStringSplit[i].indexOf('(') + 7, buildingsStringSplit[i].indexOf(')')));
                  }
               }
            }      
            return buildingLevels;
         }   
         else
            return Boolean(false);
      };
      
      /**
       * @return   player:Array(id,name)
       */
      this.getDefender = function()
      {
         if(this.defenderTable)
         {
            if(this.defenderTable.rows[0].cells[1].innerHTML == ' (deleted)')
               return new Array(-1,' (deleted)');
            else if(this.defenderTable.rows[0].cells[1].innerHTML == '---')
               return new Array(0,'---');
            else
               return getPlayerInfo(this.defenderTable.rows[0].cells[1].firstChild);
         }
      };

      /**
       * @return   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)
       * if no information about the strength of the enemy's army could be collected, returns boolean false
       */
      this.getDefenderLosses = function()
      {
         if(this.defenderUnitsTable)
            return getTroopCount(removeTroopsLabel(this.defenderUnitsTable.rows[2]));
         else
            return false;
      };
      
      /**
       * @return   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)
       * if no information about the strength of the enemy's army could be collected, returns boolean false
       */
      this.getDefenderQuantity = function()
      {
         if(this.defenderUnitsTable)
            return getTroopCount(removeTroopsLabel(this.defenderUnitsTable.rows[1]));
         else
            return false;
      };
      
      /**
       * @return   village:Array(x,y,id)
       */
      this.getDefenderVillage = function()
      {
         if(this.defenderTable)
            return getVillageInfo(this.defenderTable.rows[1].cells[1].firstChild);
      };

      /**
       * @return   color:String - blue, green, yellow, or red
       */
      this.getDotColor = function()
      {
         var images = gameDocument.getElementsByTagName('img');
         for(var i = 0; i < images.length; i++)
         {
            if(images[i].src.search('dots') != -1)
               return images[i].src.substring(images[i].src.indexOf('dots')+5,images[i].src.indexOf('.png'));
         }
      };
      
      /**
       * @return   espionageLevel:Number
       *---------------------------
       * value   significance
       * 0      nothing scouted
       * 1      resources
       * 2      buildings
       * 3      external troops
       */
      this.getEspionageLevel = function()
      {
         if(this.espionageTable)
         {
            var thElements = this.espionageTable.getElementsByTagName('th');
            if(thElements.length < 3)
               return thElements.length;
            else
               return 3;
         }
         else
            return 0;
      };
      
      /**
       * @return   resources:Array(timber:Number,clay:Number,iron:Number)
       */
      this.getHaul = function()
      {
         if(this.resultsTable)
         {
            var thElements = this.resultsTable.getElementsByTagName('th');
            for(var i = 0; i < thElements.length; i++)
            {
               if(thElements[i].innerHTML == 'Haul:')
               {
                  return resHTMLtoNumbers(thElements[i].parentNode.cells[1].innerHTML);
               }
            }
            return false;
         }
      };
      
      /**
       * @return   luck:Number
       */
      this.getLuck = function()
      {
         if(gameDocument.getElementById('attack_luck'))
         {
            var luckString = this.gameDocument.getElementById('attack_luck').getElementsByTagName('b')[0].innerHTML;
            return new Number(luckString.substring(0,luckString.indexOf('%')));
         }
      };
      
      /**
       * @return   loyalty:Array(from:Number,to:Number)
       * if no change was detected, returns boolean false
       */
      this.getLoyalty = function()
      {
         if(this.resultsTable)
         {
            var thElements = this.resultsTable.getElementsByTagName('th');
            for(var i = 0; i < thElements.length; i++)
            {
               if(thElements[i].innerHTML == 'Loyalty:')
               {
                  var bElements = thElements[i].parentNode.getElementsByTagName('b');
                  return new Array(bElements[0].innerHTML,bElements[1].innerHTML);
               }
            }
            return false;
         }
      };

      /**
       * @return   morale:Number
       */
      this.getMorale = function()
      {
         if(gameDocument.getElementById('attack_moral'))
         {
            var moraleString = this.gameDocument.getElementById('attack_moral').getElementsByTagName('h4')[0].innerHTML;
            return new Number(moraleString.substring(moraleString.indexOf(' ')+1,moraleString.indexOf('%')));
         }
      };

      /**
       * @return   reportID:Number
       */
      this.getReportId = function()
      {
         return new Number(this.gameDocument.URL.substring(this.gameDocument.URL.indexOf('view=') + 5));
      };
      
      /**
       * @return   resources:Array(timber:Number,clay:Number,iron:Number)
       */
      this.getResources = function()
      {
         if(this.espionageTable)
            return resHTMLtoNumbers(this.espionageTable.rows[0].cells[1].innerHTML);
         else
            return false;
      };
      
      
      /**
       * @return   sent:Date
       */
      this.getSent = function()
      {
         var tdElements = this.gameDocument.getElementsByTagName('td');
         var sent = new Date();
         for(i=0; i < tdElements.length; i++)
         {
            if(tdElements[i].innerHTML == 'Sent')
            {
               var sentStrings = tdElements[i+1].innerHTML.split(' ');
               sent.setMinutes(sentStrings[2].split(':')[1]);
               sent.setHours(sentStrings[2].split(':')[0]);
               sent.setDate(sentStrings[1].split(',')[0]);
               sent.setYear(sentStrings[1].split(',')[1]);
               switch(sentStrings[0])
               {
                  case 'Jan':
                     sent.setMonth(0);
                     break;
                  case 'Feb':
                     sent.setMonth(1);
                     break;
                  case 'Mar':
                     sent.setMonth(2);
                     break;
                  case 'Apr':
                     sent.setMonth(3);
                     break;
                  case 'May':
                     sent.setMonth(4);
                     break;
                  case 'Jun':
                     sent.setMonth(5);
                     break;
                  case 'Jul':
                     sent.setMonth(6);
                     break;
                  case 'Aug':
                     sent.setMonth(7);
                     break;
                  case 'Sep':
                     sent.setMonth(8);
                     break;
                  case 'Oct':
                     sent.setMonth(9);
                     break;
                  case 'Nov':
                     sent.setMonth(10);
                     break;
                  case 'Dec':
                     sent.setMonth(11);
                     break;
               }
               return sent;
            }
         }   
      };
      
      /**
       * @return   reinforcements:Array(reinforcement0:Reinforcements, reinforcement1:Reinforcements, reinforcement2:Reinforcements...)
       * if no "Defender's troops in other villages" were killed, returns boolean false
       */
      this.getSupportKilled = function()
      {
         if(this.supportKilledTable)
         {
            var reinforcements = new Array();
            for(var i = 1; i < this.supportKilledTable.rows.length; i++)
            {
               var currentReinforcement = new Reinforcements();
               currentReinforcement.troops = getTroopCount(removeTroopsLabel(this.supportKilledTable.rows[i]));
               currentReinforcement.village = getVillageInfo(this.supportKilledTable.rows[i].cells[0].firstChild);
               reinforcements.push(currentReinforcement);
            }
            return reinforcements;
         }
         else
            return false;
      };
      
      /**
       * @return   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)
       * returns boolean false if no units In transit were detected
       */
      this.getUnitsInTransit = function()
      {
         var h4elements = gameDocument.getElementsByTagName('h4');
         for(var i = 0; i < h4elements.length; i++)
         {
            if(h4elements[i].innerHTML.search('Defender's troops, that were in transit') != -1)
               return getTroopCount(h4elements[i].nextSibling.nextSibling.rows[1]);
         }
         return false;
      };
      
      /**
       * @return   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)
       * returns boolean false if no units outside were detected
       */
      this.getUnitsOutside = function()
      {
         if(this.getEspionageLevel() == 3)
         {
            return getTroopCount(this.espionageTable.rows[3].getElementsByTagName('table')[0].rows[1]);
         }
         else
            return false;
      };
   }
   catch(err)
   {
      alert('Report Reader initialization error: \n' + err);
   }
}

/*==== debug functions ====*/

/**
 *   function for testing a Report Reader. Shows a popup with information.
 */
function testReportReader()
{
   try
   {
      var debugWindow = window.open('','Debug','height=525,width=700');
      var reportReader = new ReportReader((window.frames.length>0)?window.main.document:document);
      
      debugWindow.document.write('<title>Debug</title>');
      debugWindow.document.write('<table><tbody><tr><td>');
      debugWindow.document.write('<table border=1><tbody>');
      debugWindow.document.write('<tr><td>Attacker</td><td>' + reportReader.getAttacker() + '</td></tr>');
      debugWindow.document.write('<tr><td>Attacker Losses</td><td>' + reportReader.getAttackerLosses() + '</td></tr>');
      debugWindow.document.write('<tr><td>Attacker Quantity</td><td>' + reportReader.getAttackerQuantity() + '</td></tr>');
      debugWindow.document.write('<tr><td>Attacker Village</td><td>' + reportReader.getAttackerVillage() + '</td></tr>');
      debugWindow.document.write('<tr><td>Building Levels</td><td>' + reportReader.getBuildingLevels() + '</td></tr>');
      debugWindow.document.write('<tr><td>Defender</td><td>' + reportReader.getDefender() + '</td></tr>');
      debugWindow.document.write('<tr><td>Defender Losses</td><td>' + reportReader.getDefenderLosses() + '</td></tr>');
      debugWindow.document.write('<tr><td>Defender Quantity</td><td>' + reportReader.getDefenderQuantity() + '</td></tr>');
      debugWindow.document.write('<tr><td>Defender Village</td><td>' + reportReader.getDefenderVillage() + '</td></tr>');
      debugWindow.document.write('<tr><td>Dot</td><td>' + reportReader.getDotColor() + '</td></tr>');
      debugWindow.document.write('<tr><td>Espionage Level</td><td>' + reportReader.getEspionageLevel() + '</td></tr>');
      debugWindow.document.write('<tr><td>Haul</td><td>' + reportReader.getHaul() + '</td></tr>');
      debugWindow.document.write('<tr><td>Loyalty</td><td>' + reportReader.getLoyalty() + '</td></tr>');
      debugWindow.document.write('<tr><td>Luck</td><td>' + reportReader.getLuck() + '</td></tr>');
      debugWindow.document.write('<tr><td>Morale</td><td>' + reportReader.getMorale() + '</td></tr>');
      debugWindow.document.write('<tr><td>Report ID</td><td>' + reportReader.getReportId() + '</td></tr>');
      debugWindow.document.write('<tr><td>Resources</td><td>' + reportReader.getResources() + '</td></tr>');
      debugWindow.document.write('<tr><td>Sent</td><td>' + reportReader.getSent() + '</td></tr>');
      debugWindow.document.write('<tr><td>Units In Transit</td><td>' + reportReader.getUnitsInTransit() + '</td></tr>');
      debugWindow.document.write('<tr><td>Units Outside</td><td>' + reportReader.getUnitsOutside() + '</td></tr>');
      debugWindow.document.write('</tbody></table>');
      debugWindow.document.write('</td><td>');
      debugWindow.document.write('<b>Support Killed</b><table border=1><tbody>');
      debugWindow.document.write('<tr><td>village</td><td>troops</td></tr>');
      var supportKilled = reportReader.getSupportKilled();
      for(var i = 0; i < supportKilled.length; i++)
      {
         debugWindow.document.write('<tr><td>' + supportKilled[i].village + '</td><td>' + supportKilled[i].troops + '</td></tr>');
      }      
      debugWindow.document.write('</tbody></table>');
      debugWindow.document.write('</tbody></table>');
      
   }
   catch(err)
   {
      alert(err);
   }
}

/*==== other functions ====*/

/**
 * reads the chunk of HTML with the timber count, clay count, and iron count, and converts it to an array of Numbers
 * @param   HTML:String   -the html of the resources
 * @return   resources:Array(timber:Number,clay:Number,iron:Number)
 */
function resHTMLtoNumbers(HTML)
{
   var resNames = new Array('Wood','Clay','Iron');
   var resources = new Array(0,0,0);
   
   var resString = HTML;
   for(var i = 0; i < 3; i++)
   {
      resString = resString.replace('<span class="grey">.</span>','');
      resString = resString.replace(' alt="">','');
   }
   
   for(var i = 0; i < 3; i++)
   {
      if(resString.search(resNames[i]) != -1)
         resources[i] = Number(resString.substring(resString.indexOf(resNames[i]),resString.length).split(' ')[0].split('"')[1]);         
   }
   return resources;
}

/**
 * @param   playerLink:HTMLAnchor - a link to a player profile
 * @return   player:Array(id,name)
 */
function getPlayerInfo(playerLink)
{
   var player = new Array(0,0);
   player[0] = playerLink.href.substring(playerLink.href.indexOf('player&id=') + 11);
   player[1] = playerLink.text;
   return player;
}

/**
 * @param   troopRow:HTMLTableRowElement   - a row of cells containing troop counts
 * @return   troops:Array(spear,sword,archer,axe,scout,lcav,acav,hcav,ram,cat,paladin,noble)
 */
function getTroopCount(troopRow)
{
   var troops = new Array(0,0,0,0,0,0,0,0,0,0,0,0);
   troops[0] = Number(troopRow.cells[0].innerHTML);
   troops[1] = Number(troopRow.cells[1].innerHTML);
   
   if(troopRow.cells.length <11) /* classic */
   {
      troops[3] = Number(troopRow.cells[2].innerHTML);
      troops[4] = Number(troopRow.cells[3].innerHTML);
      troops[5] = Number(troopRow.cells[4].innerHTML);
      troops[7] = Number(troopRow.cells[5].innerHTML);
      troops[8] = Number(troopRow.cells[6].innerHTML);
      troops[9] = Number(troopRow.cells[7].innerHTML);
      
      if(troopRow.cells.length == 9) /* classic without paladin*/
      {
         troops[11] = Number(troopRow.cells[8].innerHTML);
      }
      else if(troopRow.cells.length == 10) /* classic with paladin */
      {
         troops[10] = Number(troopRow.cells[8].innerHTML);
         troops[11] = Number(troopRow.cells[9].innerHTML);
      }
   }
   else /* new units */
   {
      troops[2] = Number(troopRow.cells[2].innerHTML);
      troops[3] = Number(troopRow.cells[3].innerHTML);
      troops[4] = Number(troopRow.cells[4].innerHTML);
      troops[5] = Number(troopRow.cells[5].innerHTML);
      troops[6] = Number(troopRow.cells[6].innerHTML);
      troops[7] = Number(troopRow.cells[7].innerHTML);
      troops[8] = Number(troopRow.cells[8].innerHTML);
      troops[9] = Number(troopRow.cells[9].innerHTML);
      
      if(troopRow.cells.length == 11) /* new units without paladin */
      {
         troops[11] = Number(troopRow.cells[10].innerHTML);
      }
      else if(troopRow.cells.length == 12) /* new units with paladin */
      {         
         troops[10] = Number(troopRow.cells[10].innerHTML);
         troops[11] = Number(troopRow.cells[11].innerHTML);
      }
   }
   return troops;
}

/**
 * @param   villageLink:HTMLAnchor - a link to a village with the name and coordinates
 * @return   village:Array(x,y,id)
 */
function getVillageInfo(villageLink)
{
   var village = new Array(0,0,0);
   village[0] = Number(villageLink.text.substring(villageLink.text.lastIndexOf('(')+1,villageLink.text.lastIndexOf('|')));
   village[1] = Number(villageLink.text.substring(villageLink.text.lastIndexOf('|')+1,villageLink.text.lastIndexOf(')')));
   village[2] = Number(villageLink.href.substring(villageLink.href.indexOf('village&id=') + 11));
   return village;
}

/**
 * removes the label from a troop count row
 * @return   troopRowCopy:HTMLTableRowElement - a row of troop counts suitable for the getTroopCount function
 * @param   troopRow:HTMLTableRowElement - the row of troop counts with the label
 */
function removeTroopsLabel(troopRow)
{
   var troopRowCopy = document.createElement('tr');
   for(var i = 1; i < troopRow.cells.length; i++)
   {
      troopRowCopy.appendChild(document.createElement('td'));
      troopRowCopy.cells[i-1].innerHTML = troopRow.cells[i].innerHTML;
   }         
   return troopRowCopy;
}

var reportReaderIsLoaded = true;

cheesasaurus
Admin

Posts : 27
Join date : 2008-04-20

https://twcheese.board-directory.net

Back to top Go down

Back to top

- Similar topics

 
Permissions in this forum:
You cannot reply to topics in this forum