/** * @param SimpleXMLElement $inv * @param Kill $kill * @param string $time YYYY-mm-dd hh:ss * @return boolean false on error */ private function processInvolved($inv, &$kill, $time) { if (!(int) $inv['shipTypeID'] && !(int) $inv['weaponTypeID'] && !(int) $inv['characterID'] && !(string) $inv['characterName']) { $this->parsemsg[] = "Involved party blank."; return false; } $npc = false; $ship = Ship::getByID((int) $inv['shipTypeID']); $weapon = Cacheable::factory('Item', (int) $inv['weaponTypeID']); $alliance = new Alliance(); if ((int) $inv['allianceID']) { $alliance = Alliance::add(strval($inv['allianceName']), (int) $inv['allianceID']); } else { if ((int) $inv['factionID']) { $alliance = Alliance::add(strval($inv['factionName']), (int) $inv['factionID']); } else { $alliance = Alliance::add("None"); } } // get alliance from corp if ship is any kind of tower $shipClassID = $ship->getClass()->getID(); if ($shipClassID == 35 || $shipClassID == 36 || $shipClassID == 37) { $corpByName = Corporation::lookup(strval($inv['corporationName'])); if ($corpByName) { $alliance = $corpByName->getAlliance(); } } $corp = Corporation::add(strval($inv['corporationName']), $alliance, $time, (int) $inv['corporationID']); $charid = (int) $inv['characterID']; $charname = (string) $inv['characterName']; // Allow for blank names for consistency with CCP API. if (preg_match("/(Mobile (Large|Medium|Small) Warp Disruptor I?I?|\\w+ Control Tower( \\w+)?)/", $charname)) { $charname = $inv['corporationName'] . ' - ' . $charname; $charid = 0; } else { if ($charname == "" && preg_match("/(Mobile \\w+ Warp|\\w+ Control Tower( \\w+)?)/", $weapon->getName())) { $charname = $inv['corporationName'] . ' - ' . $weapon->getName(); $charid = 0; } else { if ($charname == "" && !$charid) { // NPC ship $ship = Ship::lookup("Unknown"); $weapon = Item::getByID((int) $inv['shipTypeID']); $charname = $weapon->getName(); $npc = true; $charid = $weapon->getID(); } else { if ($charname == "" && $charid) { // Bugged kill $this->parsemsg[] = "Involved party has blank pilot name."; return false; } } } } $pilot = Pilot::add((string) $charname, $corp, $time, $charid); $iparty = new InvolvedParty($pilot->getID(), $corp->getID(), $alliance->getID(), (double) $inv['securityStatus'], $ship->getID(), $weapon->getID(), (int) $inv['damageDone']); $kill->addInvolvedParty($iparty); if ((int) $inv['finalBlow'] == 1) { $kill->setFBPilotID($pilot->getID()); } $this->npcOnly = $this->npcOnly && $npc; return true; }
/** * * @global array $destroyed * @global <type> $pilots * @global array $pods * @param Kill $kill * @param <type> $side * @return <type> */ function handle_destroyed($kill, $side, &$destroyed, &$pilots, $sideAssignmentMap = array(), $completeInformation = FALSE) { // ------------------------------------------------------------------------- // FIX BATTLE REPORT a little by Evoke. Salvoxia // BEGIN // ------------------------------------------------------------------------- // we don't want losses of our own corp/ally as losses on the enemy's side if ($side == 'e') { if (config::get('cfg_corpid')) { $corpId = config::get('cfg_corpid'); $corpId = $corpId[0]; if ($kill->getVictimCorpID() == $corpId) { return; } } elseif (config::get('cfg_allianceid')) { $allianceId = config::get('cfg_allianceid'); $allianceId = $allianceId[0]; if ($kill->getVictimAllianceID() == $allianceId) { return; } } } // ------------------------------------------------------------------------- // FIX BATTLE REPORT a little by Evoke. Salvoxia // END // ------------------------------------------------------------------------- if ($completeInformation && !is_null($destroyed) && is_array($destroyed)) { $destroyed[$kill->getID()] = $kill->getVictimID(); } if (config::get('fleet_battles_mod_sideassign')) { // determine whether the pilot is member of an alliance if ($kill->getVictimAllianceName() == "None") { $entityType = "corp"; $entityId = $kill->getVictimCorpID(); } else { $entityType = "alliance"; $entityId = $kill->getVictimAllianceID(); } if (isset($sideAssignmentMap[$entityType][$entityId])) { $pilotSide = $sideAssignmentMap[$entityType][$entityId]; } else { $pilotSide = $side; } } else { $pilotSide = $side; } $ship = Ship::lookup($kill->getVictimShipName()); $shipc = $ship->getClass(); $ts = strtotime($kill->getTimeStamp()); // mark the pilot as podded if ($shipc->getID() == 18 || $shipc->getID() == 2) { // increase the timestamp of a podkill by 1 so its after the shipkill $ts++; } // search for ships with the same id if (isset($pilots[$pilotSide][$kill->getVictimId()]) && is_array($pilots[$pilotSide][$kill->getVictimId()])) { foreach ($pilots[$pilotSide][$kill->getVictimId()] as $id => $_ship) { if ($ship->getID() == $_ship['sid']) { $pilots[$pilotSide][$kill->getVictimId()][$id]['destroyed'] = true; if (!isset($pilots[$pilotSide][$kill->getVictimId()][$id]['kll_id'])) { $pilots[$pilotSide][$kill->getVictimId()][$id]['kll_id'] = $kill->getID(); $pilots[$pilotSide][$kill->getVictimId()][$id]['kll_url'] = edkURI::page('kill_detail', $kill->getID(), "kll_id"); } //$pilots[$side][$kill->getVictimId()][0]["times"] +=1; return; } } } if ($completeInformation) { $pilots[$pilotSide][$kill->getVictimId()][] = array('name' => $kill->getVictimName(), 'plt_url' => edkURI::page("pilot_detail", $kill->getVictimID(), "plt_id"), 'kll_id' => $kill->getID(), 'kll_url' => edkURI::page('kill_detail', $kill->getID(), "kll_id"), 'spic' => imageURL::getURL('Ship', $ship->getID(), 32), 'scl' => $shipc->getPoints(), 'destroyed' => true, 'corp' => $kill->getVictimCorpName(), 'alliance' => $kill->getVictimAllianceName(), 'aid' => $kill->getVictimAllianceID(), 'alliance_url' => edkURI::page("alliance_detail", $kill->getVictimAllianceID(), "all_id"), 'ship' => $kill->getVictimShipname(), 'shipClass' => $shipc->getName(), 'shipClassObject' => $shipc, 'sid' => $ship->getID(), 'cid' => $kill->getVictimCorpID(), 'crp_url' => edkURI::page("corp_detail", $kill->getVictimCorpID(), "crp_id"), 'ts' => $ts, 'times' => 0, 'color' => getColorClassByClass($shipc)); } else { $pilots[$pilotSide][$kill->getVictimId()] = 1; } }
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; }