root/dev/common/includes/class.parser.php @ 282

Revision 282, 20.9 KB (checked in by exi, 13 years ago)

Removed autoupgrade code, all databases should be up to date.
Fixed 2 parser bugs with trinity mails.
Added event call after all mods have been loaded.
Added an option to include the dropped item value to total loss.

Line 
1<?php
2require_once("class.alliance.php");
3require_once("class.corp.php");
4require_once("class.pilot.php");
5require_once("class.kill.php");
6require_once("class.item.php");
7
8class Parser
9{
10    function Parser($killmail)
11    {
12        $this->error_ = array();
13        $this->killmail_ = trim(str_replace("\r", '', $killmail));
14        $this->returnmail = false;
15
16        if (strpos($this->killmail_, 'Beteiligte Parteien:'))
17        {
18            $this->preparse('german');
19        }
20        elseif (strpos($this->killmail_, 'System Security Level:'))
21        {
22            // this converts the killmail internally from pre-rmr to kali format
23            $this->preparse('prermr');
24        }
25
26        if (strpos($this->killmail_, '**** Truncated - mail is too large ****') > 0)
27        {
28            $this->killmail_ = str_replace('**** Truncated - mail is too large ****', '', $this->killmail_);
29        }
30
31        // Parser fix, since some killmails don't have a final blow, they would break the KB
32        if (strpos($this->killmail_, 'laid the final blow') < 1)
33        {
34            $this->needs_final_blow_ = 1;
35        }
36    }
37
38    function parse($checkauth = true)
39    {
40        // header
41        $involvedpos = strpos($this->killmail_, "Involved parties:");
42
43        $header = substr($this->killmail_, 0, $involvedpos);
44        $timestamp = substr($header, 0, 16);
45
46        if (preg_match("/Victim: (.*?)Alliance: (.*)/", $header))
47        {
48            $this->error('Found no linefeeds.');
49            return 0;
50        }
51
52        if (preg_match("/Victim: (.*)/", $header, $matches))
53        {
54            $victimname = trim($matches[1]);
55        }
56        else
57        {
58            $this->error('No victim found.');
59        }
60        if (preg_match("/Alliance: (.*)/", $header, $matches))
61        {
62            $alliancename = trim($matches[1]);
63        }
64        else
65        {
66            $this->error('No alliance found.');
67        }
68        if (preg_match("/Corp: (.*)/", $header, $matches))
69        {
70            $corpname = trim($matches[1]);
71        }
72        else
73        {
74            $this->error('No corp found.');
75        }
76        if (preg_match("/Destroyed: (.*)/", $header, $matches))
77        {
78            $shipname = trim($matches[1]);
79        }
80        else
81        {
82            $this->error('No destroyed ship found.');
83        }
84        if (preg_match("/System: (.*)/", $header, $matches))
85        {
86            $systemname = trim($matches[1]);
87        }
88        else
89        {
90            $this->error('No system found.');
91        }
92        if (preg_match("/Security: (.*)/", $header, $matches))
93        {
94            $systemsec = trim($matches[1]);
95        }
96        else
97        {
98            $this->error('No security found.');
99        }
100        $dmgtaken = false;
101        if (preg_match("/Damage Taken: (.*)/", $header, $matches))
102        {
103            $dmgtaken = trim($matches[1]);
104            $this->dmgtaken = $dmgtaken;
105        }
106
107        if (!isset($timestamp) ||
108                !isset($alliancename) ||
109                !isset($corpname) ||
110                !isset($victimname) ||
111                !isset($shipname) ||
112                !isset($systemname) ||
113                !isset($systemsec))
114            return 0;
115
116        if ($checkauth)
117        {
118            $authorized = false;
119        }
120        else
121        {
122            $authorized = true;
123        }
124
125        // populate/update database
126        $alliance = new Alliance();
127        $alliance->add($alliancename);
128        $corp = new Corporation();
129        $corp->add($corpname, $alliance, $timestamp);
130        $victim = new Pilot();
131        $victim->add($victimname, $corp, $timestamp);
132        $system = new SolarSystem();
133        $system->lookup($systemname);
134        if (!$system->getID())
135        {
136            $this->error('System not found.', $systemname);
137        }
138        $ship = new Ship();
139        $ship->lookup($shipname);
140        if (!$ship->getID())
141        {
142            $this->error('Ship not found.', $shipname);
143        }
144        $kill = new Kill();
145        $kill->setTimeStamp($timestamp);
146        $kill->setVictimID($victim->getID());
147        $kill->setVictimCorpID($corp->getID());
148        $kill->setVictimAllianceID($alliance->getID());
149        $kill->setVictimShip($ship);
150        $kill->setSolarSystem($system);
151        if ($dmgtaken)
152        {
153            $kill->set('dmgtaken', $dmgtaken);
154        }
155
156        if (ALLIANCE_ID != 0 && $alliance->getID() == ALLIANCE_ID)
157            $authorized = true;
158        elseif (CORP_ID != 0)
159        {
160            $corps = explode(",", CORP_ID);
161            foreach($corps as $checkcorp)
162            {
163                if ($corp->getID() == $checkcorp)
164                    $authorized = true;
165            }
166        }
167
168        // involved
169        $end = strpos($this->killmail_, "Destroyed items:");
170        if ($end == 0)
171        {
172            $end = strlen($this->killmail_);
173        }
174        $involved = explode("\n", trim(substr($this->killmail_, strpos($this->killmail_, "Involved parties:") + 17, $end - (strpos($this->killmail_, "Involved parties:") + 17))));
175
176        $i = 0;
177
178        $order = 0;
179        while ($i < count($involved))
180        {
181            if ($involved[$i] == "")
182            {
183                $i++;
184                continue;
185            }
186
187            preg_match("/Name: (.*)/", $involved[$i], $matches);
188            $ipname = $matches[1];
189
190            preg_match("/(.*) \\(laid the final blow\\)/", $ipname, $matches);
191            if ($matches[1])
192            {
193                $ipname = $matches[1];
194                $finalblow = 1;
195            }
196            else
197            {
198                $finalblow = 0;
199            }
200
201            /* This is part of the final blow fix, mentioned above */
202            if ($this->needs_final_blow_)
203            {
204                $finalblow = 1;
205                $this->needs_final_blow_ = 0;
206            }
207            /* END FIX */
208
209            preg_match("/Security: (.*)/", $involved[$i + 1], $matches);
210            $secstatus = $matches[1];
211
212            if ($secstatus == "") // NPC or POS
213            {
214                $secstatus = "0.0";
215                preg_match("/(.*) \/ (.*)/", $ipname, $pmatches);
216                $icname = $pmatches[2];
217                $isname = "Unknown";
218                $iwname = $pmatches[1];
219                if ($dmgtaken)
220                {
221                    preg_match("/Damage Done: (.*)/", $involved[++$i], $matches);
222                    $idmgdone = $matches[1];
223                }
224
225                if (!strlen($icname) && !strlen($iwname))
226                {
227                    // fucked up bclinic killmail, no person here, continue
228                    $i++;
229                    continue;
230                }
231
232                $tmpcorp = new Corporation();
233                $tmpcorp->lookup($icname);
234
235                if (!$tmpcorp->getID())
236                {
237                    // not a known corp, add it
238                    $ialliance = new Alliance();
239                    $ialliance->add('None');
240                    $icorp = new Corporation();
241                    $icorp->add($icname, $ialliance, $kill->getTimeStamp());
242                    $tmpcorp = $icorp;
243                }
244                                $iweapon = new Item();
245                                $iweapon->lookup($pmatches[1]);
246                                $ipname = '#'.$tmpcorp->getID().'#'.$iweapon->getID().'#'.$iwname;
247                $tmpall = $tmpcorp->getAlliance();
248                // name will be None if no alliance is set
249                $ianame = $tmpall->getName();
250
251                $ialliance = &$tmpall;
252                $icorp = &$tmpcorp;
253
254                $i++;
255            }
256            else
257            {
258                preg_match("/Alliance: (.*)/", $involved[$i + 2], $matches);
259                $ianame = $matches[1];
260
261                preg_match("/Corp: (.*)/", $involved[$i + 3], $matches);
262                $icname = $matches[1];
263
264                preg_match("/Ship: (.*)/", $involved[$i + 4], $matches);
265                $isname = $matches[1];
266
267                preg_match("/Weapon: (.*)/", $involved[$i + 5], $matches);
268                $iwname = $matches[1];
269                $i += 6;
270                if ($dmgtaken)
271                {
272                    preg_match("/Damage Done: (.*)/", $involved[$i++], $matches);
273                    $idmgdone = $matches[1];
274                }
275
276                $ialliance = new Alliance();
277                $ialliance->add($ianame);
278                $icorp = new Corporation();
279                $icorp->add($icname, $ialliance, $kill->getTimeStamp());
280            }
281
282            $ipilot = new Pilot();
283            $ipilot->add($ipname, $icorp, $timestamp);
284
285            $iship = new Ship();
286            $iship->lookup($isname);
287            if (!$iship->getID())
288            {
289                $this->error('Ship not found.', $isname);
290            }
291
292            if (!trim($iwname))
293            {
294                // set weapon to unknown in case we didn't found one
295                $iwname = 'Unknown';
296            }
297            $iweapon = new Item();
298            $iweapon->lookup($iwname);
299            if (!$iweapon->getID())
300            {
301                $this->error('Weapon not found.', $iwname);
302            }
303
304            if (ALLIANCE_ID != 0 && $ialliance->getID() == ALLIANCE_ID)
305            {
306                $authorized = true;
307            }
308            elseif (CORP_ID != 0)
309            {
310                $corps = explode(",", CORP_ID);
311                foreach($corps as $corp)
312                {
313                    if ($icorp->getID() == $corp)
314                        $authorized = true;
315                }
316            }
317            if (!$authorized)
318            {
319                if ($string = config::get('post_permission'))
320                {
321                    if ($string == 'all')
322                    {
323                        $authorized = true;
324                    }
325                    else
326                    {
327                        $tmp = explode(',', $string);
328                        foreach ($tmp as $item)
329                        {
330                            if (!$item)
331                            {
332                                continue;
333                            }
334                            $typ = substr($item, 0, 1);
335                            $id = substr($item, 1);
336                            if ($typ == 'a')
337                            {
338                                if ($ialliance->getID() == $id || $kill->getVictimAllianceID() == $id)
339                                {
340                                    $authorized = true;
341                                    break;
342                                }
343                            }
344                            elseif ($typ == 'c')
345                            {
346                                if ($icorp->getID() == $id || $kill->getVictimCorpID() == $id)
347                                {
348                                    $authorized = true;
349                                    break;
350                                }
351                            }
352                            elseif ($typ == 'p')
353                            {
354                                if ($ipilot->getID() == $id || $kill->getVictimID() == $id)
355                                {
356                                    $authorized = true;
357                                    break;
358                                }
359                            }
360                        }
361                    }
362                }
363            }
364
365            $iparty = new InvolvedParty($ipilot->getID(), $icorp->getID(),
366                $ialliance->getID(), $secstatus, $iship, $iweapon);
367            if ($dmgtaken)
368            {
369                $iparty->dmgdone_ = $idmgdone;
370            }
371            $kill->addInvolvedParty($iparty);
372
373            if ($finalblow == 1)
374            {
375                $kill->setFBPilotID($ipilot->getID());
376                $kill->setFBCorpID($icorp->getID());
377                $kill->setFBAllianceID($ialliance->getID());
378            }
379        }
380
381        // destroyed items
382        $destroyedpos = strpos($this->killmail_, "Destroyed items:");
383
384        if ($destroyedpos)
385        {
386            $endpos = strlen($this->killmail_) - $destroyedpos + 16;
387            if ($dmgtaken)
388            {
389                $pos = strpos($this->killmail_, "Dropped items:");
390                if ($pos === false)
391                {
392                    $pos = strlen($this->killmail_);
393                }
394                $endpos = $pos - $destroyedpos - 16;
395            }
396
397            $destroyed = explode("\n", trim(substr($this->killmail_, $destroyedpos + 16, $endpos)));
398            #var_dump($destroyed); exit;
399            $destroyed_items = $this->scanForItems($destroyed);
400            foreach ($destroyed_items as $item)
401            {
402                $ditem = new DestroyedItem($item['item'], $item['quantity'], $item['location']);
403                $kill->addDestroyedItem($ditem);
404            }
405        }
406        if ($dmgtaken)
407        {
408            $startpos = strpos($this->killmail_, "Dropped items:");
409            if ($startpos)
410            {
411                $endpos = strlen($this->killmail_) - $startpos + 14;
412
413                $dropped = explode("\n", trim(substr($this->killmail_, $startpos + 14, $endpos)));
414                #var_dump($dropped); exit;
415
416                $dropped_items = $this->scanForItems($dropped);
417                foreach ($dropped_items as $item)
418                {
419                    $ditem = new DroppedItem($item['item'], $item['quantity'], $item['location']);
420                    $kill->addDroppedItem($ditem);
421                }
422            }
423        }
424
425        if (!$authorized)
426        {
427            return -2;
428        }
429        if ($this->getError())
430        {
431            return 0;
432        }
433
434        if ($this->returnmail)
435        {
436            return $kill;
437        }
438        $id = $kill->add();
439        if ($id == -1)
440        {
441            $this->dupeid_ = $kill->dupeid_;
442        }
443
444        return $id;
445    }
446
447    function scanForItems($destroyed)
448    {
449        $i = 0;
450        $num = count($destroyed);
451        while ($i < $num)
452        {
453            $destroyed[$i] = trim($destroyed[$i]);
454            if ($destroyed[$i] == "")
455            {
456                $i++;
457                continue;
458            }
459
460            if ($destroyed[$i] == "Empty.")
461            {
462                $container = false;
463                $i++;
464                continue;
465            }
466
467            $qtypos = 0;
468            $locpos = 0;
469            $itemname = "";
470            $quantity = "";
471            $location = "";
472
473            $qtypos = strpos($destroyed[$i], ", Qty: ");
474            $locpos = strrpos($destroyed[$i], "(");
475
476            if ($container && $locpos != false)
477            {
478                $container = false;
479            }
480            if (strpos($destroyed[$i], "Container"))
481            {
482                $container = true;
483            }
484            if ($qtypos <= 0 && !$locpos)
485            {
486                $itemlen = strlen($destroyed[$i]);
487                if ($container) $location = "Cargo";
488            }
489            if ($qtypos > 0 && !$locpos)
490            {
491                $itemlen = $qtypos;
492                $qtylen = strlen($destroyed[$i]) - $qtypos;
493                if ($container) $location = "Cargo";
494            }
495            if ($locpos > 0 && $qtypos <= 0)
496            {
497                $itemlen = $locpos - 1;
498                $qtylen = 0;
499                $loclen = strlen($destroyed[$i]) - $locpos - 2;
500                if (!$locpos) $container = false;
501            }
502            if ($locpos > 0 && $qtypos > 0)
503            {
504                $itemlen = $qtypos;
505                $qtylen = $locpos - $qtypos - 7;
506                $loclen = strlen($destroyed[$i]) - $locpos - 2;
507                if (!$locpos) $container = false;
508            }
509
510            $itemname = substr($destroyed[$i], 0, $itemlen);
511            if ($qtypos) $quantity = substr($destroyed[$i], $qtypos + 6, $qtylen);
512            if ($locpos) $location = substr($destroyed[$i], $locpos + 1, $loclen);
513
514            if ($quantity == "")
515            {
516                $quantity = 1;
517            }
518
519            $item = new Item();
520            $item->lookup(trim($itemname));
521            if (!$item->getID())
522            {
523                $this->error('Item not found.', trim($itemname));
524            }
525            if ($location == 'In Container')
526            {
527                $location = 'Cargo';
528            }
529
530            $items[] = array('item' => $item, 'quantity' => $quantity, 'location' => $location);
531            $i++;
532        }
533
534        return $items;
535    }
536
537    function error($message, $debugtext = null)
538    {
539        $this->error_[] = array($message, $debugtext);
540    }
541
542    function getError()
543    {
544        if (count($this->error_))
545        {
546            return $this->error_;
547        }
548        return false;
549    }
550
551    function preparse($set)
552    {
553        if ($set == 'german')
554        {
555            $this->killmail_ = str_replace(array(chr(195).chr(182), chr(195).chr(164)), array(chr(246), chr(228)), $this->killmail_);
556
557            $search = array('Ziel:','Allianz: NICHTS','Allianz: nichts','Allianz:',
558                            'Zerst'.chr(246).'rte Gegenst'.chr(228).'nde', 'Zerst'.chr(246).'rt:', 'Sicherheit:',
559                            'Beteiligte Parteien:','Anz:','Corporation:','(Fracht)', 'Schiff:','Waffe:',
560                            'Verursachter Schaden:','Erlittener Schaden:', '(gab den letzten Schuss ab)',
561                            'Hinterlassene Gegenst'.chr(228).'nde:', 'Anz.:', 'Unbekannt', 'Dronenhangar');
562            $replace = array('Victim:','Alliance: None','Alliance: None','Alliance:',
563                            'Destroyed items','Destroyed:', 'Security:',
564                            'Involved parties:', 'Qty:', 'Corp:', '(Cargo)', 'Ship:', 'Weapon:',
565                            'Damage Done:', 'Damage Taken:', '(laid the final blow)',
566                            'Dropped items:', 'Qty:', 'Unknown', 'Drone Bay');
567
568            //if (strpos($this->killmail, chr(246)) === false)
569            //{
570            //    $this->killmail_ = utf8_decode($this->killmail_);
571            //}
572            $this->killmail_ = str_replace($search, $replace, $this->killmail_);
573            return;
574        }
575        if ($set == 'prermr')
576        {
577            $search = array('Corporation:','Destroyed Type:','Solar System:', 'System Security Level:', 'Security Status:', 'Ship Type:', 'Weapon Type:', '(Fitted - Medium slot)', '(Fitted - Low slot)', '(Fitted - High slot)');
578            $replace = array('Corp:','Destroyed:', 'System:', 'Security:', 'Security:', 'Ship:', 'Weapon:', '', '', '');
579            $this->killmail_ = str_replace($search, $replace, $this->killmail_);
580            $position = strpos($this->killmail_, 'Destroyed items:');
581            if ($position !== false)
582            {
583                $destroyed = explode("\n", strstr($this->killmail_, 'Destroyed items:'));
584                $i = 0;
585                $num = count($destroyed);
586                while ($i < $num)
587                {
588                    $destroyed[$i] = trim($destroyed[$i]);
589
590                    $itempos = strpos($destroyed[$i], 'Type: ');
591                    if ($itempos !== false)
592                    {
593                        $destroyed[$i] = substr($destroyed[$i], $itempos+6);
594                        if (isset($destroyed[$i+1]))
595                        {
596                            $quantitypos = strstr($destroyed[$i+1], 'Quantity: ');
597                            if ($quantitypos !== false)
598                            {
599                                $qty = ', Qty: '.substr($destroyed[$i+1], $quantitypos+10);
600                                $pos = strpos($destroyed[$i], '(');
601                                if ($pos !== false)
602                                {
603                                    $destroyed[$i] = trim(substr($destroyed[$i], 0, $pos)).$qty.' '.substr($destroyed[$i], $pos);
604                                }
605                                else
606                                {
607                                    $destroyed[$i] .= $qty;
608                                }
609                                unset($destroyed[$i+1]);
610                                $i++;
611                            }
612                        }
613                    }
614                    else
615                    {
616                        unset($destroyed[$i]);
617                    }
618                    $i++;
619                }
620                $this->killmail_ = substr($this->killmail_, 0, $position).'Destroyed items: '."\n\n\n".join("\n", $destroyed)."\n";
621            }
622        }
623    }
624}
625?>
Note: See TracBrowser for help on using the browser.