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

Revision 353, 25.8 KB (checked in by beans, 12 years ago)

Parser fix from FriedRoadKill?

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