Esempio n. 1
0
 function parse($checkauth = true)
 {
     $qry = DBFactory::getDBQuery();
     $timestamp = substr($this->killmail_, 0, 16);
     $timestamp = str_replace('.', '-', $timestamp);
     //trim out any multiple spaces that may exist -
     //$this->killmail_ = preg_replace('/ +/', ' ', $this->killmail_);
     // header section
     $involvedpos = strpos($this->killmail_, "Involved parties:");
     if ($involvedpos == 0) {
         $this->error("Mail lacks Involved parties header.");
         return 0;
     }
     $header = substr($this->killmail_, 0, $involvedpos);
     $timestamp = substr($header, 0, 16);
     $victim = explode("\n", trim(substr($this->killmail_, 0, $involvedpos)));
     $upper_limit = count($victim);
     $victimname = "Unknown";
     //lovely default values
     $factionname = "None";
     $alliancename = "None";
     $corpname = "Unknown";
     $shipname = "Unknown";
     $systemname = "Unknown";
     $systemsec = "0.0";
     $dmgtaken = '0';
     $this->dmgtaken = '0';
     $pos = 0;
     $moon = "";
     for ($counter = 0; $counter <= $upper_limit; $counter++) {
         if (preg_match("/Victim: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 $victimname = $matches[1];
             }
         } elseif (preg_match("/Corp: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 $corpname = $matches[1];
             }
         } elseif (preg_match("/Alliance: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 $alliancename = $matches[1];
             }
             if ($alliancename == "Unknown") {
                 $alliancename = "None";
             }
         } elseif (preg_match("/Faction: (.*)/", $victim[$counter], $matches)) {
             if (strlen($matches[1]) > 5 && $matches[1] != "Unknown") {
                 //catches faction mails from -A-
                 $factionname = $matches[1];
             } else {
                 $factionname = "None";
             }
         } elseif (preg_match("/Destroyed: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 $shipname = $matches[1];
             }
         } elseif (preg_match("/System: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 //bad assumption here - moon has to come before security.
                 $systemname = $matches[1];
                 if (strcmp($moon, 'Unknown') == 0 && $pos == 1) {
                     $moon = $matches[1];
                     $victimname = $matches[1];
                 }
             }
         } elseif (preg_match("/Security: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 $systemsec = (double) $matches[1];
             }
         } elseif (preg_match("/Damage Taken: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 $dmgtaken = (int) $matches[1];
                 $this->dmgtaken = $dmgtaken;
             }
         } elseif (preg_match("/Moon: (.*)/", $victim[$counter], $matches)) {
             if ($matches[1]) {
                 $moon = $matches[1];
                 $victimname = $matches[1];
                 $pos = 1;
             } else {
                 //if the system is valid, it will pick this up, provided it features after
                 //the moon is listed - which is unlikely unless the mail format
                 //drastically changes... again :)
                 $moon = 'Unknown';
                 $victimname = 'Unknown';
                 $pos = 1;
             }
         }
     }
     //faction warfare stuff
     if (strcasecmp($alliancename, 'None') == 0) {
         $alliancename = $factionname;
     }
     //report the errors for the things that make sense.
     //we need pilot names, corp names, ship types, and the system to be sure
     //the rest aren't required but for completeness, you'd want them in :)
     // Customs Offices don't have names. Hack a fix in by accepting mails with
     // no victim name but that do have a system.
     if (strcmp($victimname, 'Unknown') == 0) {
         if (strcmp($systemname, 'Unknown') == 0) {
             $this->error('Victim has no name.');
             unset($victimname);
             //we unset the variable so that it fails the next check
             $this->error('Killmail lacks solar system information.');
             unset($systemname);
         } else {
             $victimname = $systemname;
         }
     }
     if (strcmp($corpname, 'Unknown') == 0) {
         $this->error('Victim has no corp.');
         unset($corpname);
     }
     if (strcmp($shipname, 'Unknown') == 0) {
         $this->error('Victim has no ship type.');
         unset($shipname);
     }
     if (strcmp($systemname, 'Unknown') == 0) {
         $this->error('Killmail lacks solar system information.');
         unset($systemname);
     }
     if ($pos == 1) {
         $victimname = $moon;
     }
     if (!isset($timestamp) || !isset($factionname) || !isset($alliancename) || !isset($corpname) || !isset($victimname) || !isset($shipname) || !isset($systemname) || !isset($systemsec)) {
         return 0;
     }
     if ($checkauth) {
         $authorized = false;
     } else {
         $authorized = true;
     }
     // populate/update database
     $alliance = $this->fetchAlliance($alliancename);
     $corp = $this->fetchCorp($corpname, $alliance, $timestamp);
     $victim = $this->fetchPilot($victimname, $corp, $timestamp);
     $system = SolarSystem::lookup($systemname);
     if (!$system || !$system->getID()) {
         $this->error('System not found.', $systemname);
         $system = new SolarSystem();
     }
     $ship = Ship::lookup($shipname);
     if (!$ship || !$ship->getID()) {
         $this->error('Ship not found.', $shipname);
         $ship = new Ship();
     }
     $kill = new Kill();
     if ($this->externalID) {
         $kill->setExternalID($this->externalID);
     }
     $kill->setTimeStamp($timestamp);
     $kill->setVictim($victim);
     $kill->setVictimID($victim->getID());
     $kill->setVictimCorpID($corp->getID());
     $kill->setVictimAllianceID($alliance->getID());
     $kill->setVictimShip($ship);
     $kill->setSolarSystem($system);
     if ($dmgtaken) {
         $kill->set('dmgtaken', $dmgtaken);
     }
     if (config::get('cfg_allianceid') && in_array($alliance->getID(), config::get('cfg_allianceid'))) {
         $authorized = true;
     } elseif (config::get('cfg_corpid') && in_array($corp->getID(), config::get('cfg_corpid'))) {
         $authorized = true;
     } elseif (config::get('cfg_pilotid') && in_array($victim->getID(), config::get('cfg_pilotid'))) {
         $authorized = true;
     }
     // involved parties section
     $end = strpos($this->killmail_, "Destroyed items:");
     if ($end == 0) {
         $end = strpos($this->killmail_, "Dropped items:");
         if ($end == 0) {
             //try to parse to the end of the mail in the event sections are missing
             $end = strlen($this->killmail_);
         }
     }
     $involved = explode("\n", trim(substr($this->killmail_, strpos($this->killmail_, "Involved parties:") + 17, $end - (strpos($this->killmail_, "Involved parties:") + 17))));
     $ipilot_count = 0;
     //allows us to be a bit more specific when errors strike
     $i = 0;
     $topdamage = 0;
     $order = 0;
     while ($i < count($involved)) {
         $iparts = count($involved);
         $finalblow = 0;
         while ($i < $iparts) {
             $ipilot_count++;
             $ipname = "Unknown";
             $ianame = "None";
             $ifname = "None";
             $icname = "None";
             $isname = "Unknown";
             $iwname = "Unknown";
             $idmgdone = '0';
             $secstatus = "0.0";
             while ($involved[$i] == '') {
                 //compensates for multiple blank lines between involved parties
                 $i++;
                 if ($i > count($involved)) {
                     $this->error("Involved parties section prematurely ends.");
                     return 0;
                 }
             }
             for ($counter = $i; $counter <= $iparts; $counter++) {
                 if (preg_match("/Name: (.*)/", $involved[$counter], $matches)) {
                     if ($matches[1]) {
                         if (stristr($involved[$counter], '/')) {
                             $slash = strpos($involved[$counter], '/');
                             $name = trim(substr($involved[$counter], 5, $slash - 5));
                             $corporation = trim(substr($involved[$counter], $slash + 1, strlen($involved[$counter]) - $slash + 1));
                             //now if the corp bit has final blow info, note it
                             preg_match("/(.*) \\(laid the final blow\\)/", $corporation, $matched);
                             if ($matched[1]) {
                                 $finalblow = 1;
                                 $iwname = $name;
                                 $end = strpos($corporation, '(') - 1;
                                 $corporation = substr($corporation, 0, $end);
                             } else {
                                 $finalblow = 0;
                                 $iwname = $name;
                             }
                             //alliance lookup for warp disruptors - normal NPCs aren't to be bundled in
                             $crp = $this->fetchCorp($corporation);
                             if ($crp && $crp->getExternalID(true) > 0) {
                                 if ($crp->fetchCorp()) {
                                     $al = $crp->getAlliance();
                                     $alName = $al->getName();
                                     if (trim($alName) != "") {
                                         $ianame = $al->getName();
                                     }
                                 }
                                 // else check db for kills with that corp at the same time?
                             }
                             $ipname = $name;
                             $icname = $corporation;
                         } else {
                             $ipname = $matches[1];
                             preg_match("/(.*)\\s*\\(laid the final blow\\)/", $ipname, $matches);
                             if (isset($matches[1])) {
                                 $ipname = trim($matches[1]);
                                 $finalblow = 1;
                             } else {
                                 $finalblow = 0;
                             }
                         }
                     }
                 } else {
                     if (preg_match("/Alliance: (.*)/", $involved[$counter], $matches)) {
                         if ($matches[1]) {
                             $ianame = $matches[1];
                         }
                         if ($ianame == "Unknown") {
                             $ianame = "None";
                         }
                     } else {
                         if (preg_match("/Faction: (.*)/", $involved[$counter], $matches)) {
                             if (strlen($matches[1]) > 5 && $matches[1] != "Unknown") {
                                 //catches faction mails from -A-
                                 $ifname = $matches[1];
                             } else {
                                 $ifname = "NONE";
                             }
                         } else {
                             if (preg_match("/Corp: (.*)/", $involved[$counter], $matches)) {
                                 if ($matches[1]) {
                                     $icname = $matches[1];
                                 }
                             } else {
                                 if (preg_match("/Ship: (.*)/", $involved[$counter], $matches)) {
                                     if ($matches[1]) {
                                         $isname = $matches[1];
                                     }
                                 } else {
                                     if (preg_match("/Weapon: (.*)/", $involved[$counter], $matches)) {
                                         if ($matches[1]) {
                                             $iwname = $matches[1];
                                         }
                                     } else {
                                         if (preg_match("/Security: (.*)/", $involved[$counter], $matches)) {
                                             if ($matches[1]) {
                                                 $secstatus = (double) $matches[1];
                                             }
                                         } else {
                                             if (preg_match("/Damage Done: (.*)/", $involved[$counter], $matches)) {
                                                 if ($matches[1]) {
                                                     $idmgdone = (int) $matches[1];
                                                 }
                                                 if ($idmgdone > $topdamage) {
                                                     $topdamage = $idmgdone;
                                                 }
                                             } else {
                                                 if ($involved[$counter] == '') {
                                                     //allows us to process the involved party. This is the empty line after the
                                                     //involved party section
                                                     $counter++;
                                                     $i = $counter;
                                                     break;
                                                 } else {
                                                     //skip over this entry, it could read anything, we don't care. Handy if/when
                                                     //new mail fields get added and we aren't handling them yet.
                                                     $counter++;
                                                     $i = $counter;
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
                 if ($this->needs_final_blow_) {
                     $finalblow = 1;
                     $this->needs_final_blow_ = 0;
                 }
             }
             // Faction Warfare stuff
             if (strcasecmp($ianame, "None") == 0) {
                 $ianame = $ifname;
             }
             // end faction warfare stuff
             $ialliance = $this->fetchAlliance($ianame);
             if (strcmp($icname, 'None') == 0) {
                 //don't add corp, because pilots have to be in corps.
                 $this->error('Involved party has no corp. (Party No. ' . $ipilot_count . ')');
                 $icorp = new Corporation();
             } else {
                 $icorp = $this->fetchCorp($icname, $ialliance, $kill->getTimeStamp());
             }
             if (preg_match("/^(Mobile \\w+ Warp|\\w+ Control Tower( \\w+)?)/", $iwname)) {
                 //for involved parties parsed that lack a pilot, but are actually POS or mobile warp disruptors
                 $ipname = $icname . ' - ' . $iwname;
                 $ipilot = $this->fetchPilot($ipname, $icorp, $timestamp);
             } elseif (strcmp($ipname, 'Unknown') == 0 || empty($ipname)) {
                 $ipilot = new Pilot();
                 $this->error('Involved party has no name. (Party No. ' . $ipilot_count . ')');
             } else {
                 //don't add pilot if the pilot's unknown or dud
                 $ipilot = $this->fetchPilot($ipname, $icorp, $timestamp);
             }
             $iship = Ship::lookup($isname);
             if (!$iship || !$iship->getName()) {
                 $this->error('Ship not found.', $isname);
             }
             if (strcmp($iwname, 'Unknown') == 0 && $iship && $iship->getID()) {
                 $iwname = $iship->getName();
             }
             $iweapon = Item::lookup($iwname);
             if (strcmp($iwname, 'Unknown') == 0) {
                 $this->error('No weapon found for pilot "' . $ipname . '"');
                 $iweapon = new Item();
             } else {
                 if (!$iweapon || !$iweapon->getID()) {
                     $this->error('Weapon not found.', $iwname);
                     $iweapon = new Item();
                 }
             }
             if (config::get('cfg_allianceid') && in_array($ialliance->getID(), config::get('cfg_allianceid'))) {
                 $authorized = true;
             } elseif (config::get('cfg_corpid') && in_array($icorp->getID(), config::get('cfg_corpid'))) {
                 $authorized = true;
             } elseif (config::get('cfg_pilotid') && in_array($ipilot->getID(), config::get('cfg_pilotid'))) {
                 $authorized = true;
             }
             if (!$authorized) {
                 if ($string = config::get('post_permission')) {
                     if ($string == 'all') {
                         $authorized = true;
                     } else {
                         $tmp = explode(',', $string);
                         foreach ($tmp as $item) {
                             if (!$item) {
                                 continue;
                             }
                             $typ = substr($item, 0, 1);
                             $id = substr($item, 1);
                             if ($typ == 'a') {
                                 if ($ialliance->getID() == $id || $kill->getVictimAllianceID() == $id) {
                                     $authorized = true;
                                     break;
                                 }
                             } elseif ($typ == 'c') {
                                 if ($icorp->getID() == $id || $kill->getVictimCorpID() == $id) {
                                     $authorized = true;
                                     break;
                                 }
                             } elseif ($typ == 'p') {
                                 if ($ipilot->getID() == $id || $kill->getVictimID() == $id) {
                                     $authorized = true;
                                     break;
                                 }
                             }
                         }
                     }
                 }
             }
             $iparty = new InvolvedParty($ipilot->getID(), $icorp->getID(), $ialliance->getID(), $secstatus, $iship->getID(), $iweapon->getID(), $idmgdone);
             $kill->addInvolvedParty($iparty);
             if ($finalblow == 1) {
                 $kill->setFBPilotID($ipilot->getID());
                 $kill->setFBCorpID($icorp->getID());
                 $kill->setFBAllianceID($ialliance->getID());
             }
             if ($topdamage == $idmgdone) {
                 $kill->setTDPilotID($ipilot->getID());
                 $kill->setFBCorpID($icorp->getID());
                 $kill->setFBAllianceID($ialliance->getID());
             }
         }
     }
     // Duplicate check does not use items so it's safe to check now
     if ($id = $kill->getDupe()) {
         $this->dupeid_ = $id;
         if ($this->dupeid_ > 0 && $this->externalID) {
             //if this is a duplicate and we have an external id then update the existing kill
             $qry->execute("UPDATE kb3_kills SET kll_external_id = " . $this->externalID . " WHERE kll_id = " . $this->dupeid_);
             $qry->execute("UPDATE kb3_mails SET kll_external_id = " . $this->externalID . ", kll_modified_time = UTC_TIMESTAMP() " . "WHERE kll_id = " . $this->dupeid_ . " AND kll_external_id IS NULL");
         }
         return -1;
     }
     // destroyed items section
     $destroyedpos = strpos($this->killmail_, "Destroyed items:");
     if ($destroyedpos) {
         $endpos = strlen($this->killmail_) - $destroyedpos + 16;
         $pos = strpos($this->killmail_, "Dropped items:");
         if ($pos === false) {
             $pos = strlen($this->killmail_);
         }
         $endpos = $pos - $destroyedpos - 16;
         $destroyed = explode("\n", trim(substr($this->killmail_, $destroyedpos + 16, $endpos)));
         $destroyed_items = $this->scanForItems($destroyed);
         foreach ($destroyed_items as $item) {
             $ditem = new DestroyedItem($item['item'], $item['quantity'], '', $item['location'], true);
             $kill->addDestroyedItem($ditem);
         }
     }
     $startpos = strpos($this->killmail_, "Dropped items:");
     if ($startpos) {
         $endpos = strlen($this->killmail_) - $startpos + 14;
         $dropped = explode("\n", trim(substr($this->killmail_, $startpos + 14, $endpos)));
         $dropped_items = $this->scanForItems($dropped);
         foreach ($dropped_items as $item) {
             $ditem = new DestroyedItem($item['item'], $item['quantity'], '', $item['location'], true);
             $kill->addDroppedItem($ditem);
         }
     }
     if (!$authorized) {
         return -2;
     }
     if ($this->getError()) {
         return 0;
     }
     if ($this->returnmail) {
         return $kill;
     }
     $id = $kill->add();
     if ($id == -2) {
         $this->error("An error has occurred. Please try again later.");
         $id = 0;
     }
     return $id;
 }