root/branch/rev3/common/includes/class.parser.php @ 244

Revision 244, 19.7 KB (checked in by exi, 15 years ago)

Removed rig0rs mail on request.
New option in Mapoptions to cache region maps.
Added several NPC corp images.
Improved corp image handling, you can now store the logo as <corpname>.jpg in img/corps/.
Killmails now handle the Killmail Mk1.5 format.
A reinforced killboard will now cache all generated maps regardless of their type.
Page kill_detail will now show damage and dropped items.
Upgraded category icons on kill_detail to ones with alpha channel.

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