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

Revision 339, 24.3 KB (checked in by beans, 12 years ago)

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