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

Revision 254, 19.8 KB (checked in by exi, 15 years ago)

Merging 242:253 branch into dev

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 > 0)
385        {
386            $endpos = strlen($this->killmail_) - $destroyedpos + 16;
387            if ($dmgtaken)
388            {
389                $endpos = strpos($this->killmail_, "Dropped items:") - $destroyedpos - 16;
390            }
391
392            $destroyed = explode("\n", trim(substr($this->killmail_, $destroyedpos + 16, $endpos)));
393            #var_dump($destroyed); exit;
394            $destroyed_items = $this->scanForItems($destroyed);
395            foreach ($destroyed_items as $item)
396            {
397                $ditem = new DestroyedItem($item['item'], $item['quantity'], $item['location']);
398                $kill->addDestroyedItem($ditem);
399            }
400        }
401        if ($dmgtaken)
402        {
403            $startpos = strpos($this->killmail_, "Dropped items:");
404            $endpos = strlen($this->killmail_) - $startpos + 16;
405
406            $dropped = explode("\n", trim(substr($this->killmail_, $startpos + 16, $endpos)));
407            #var_dump($dropped); exit;
408
409            $dropped_items = $this->scanForItems($dropped);
410            foreach ($dropped_items as $item)
411            {
412                $ditem = new DroppedItem($item['item'], $item['quantity'], $item['location']);
413                $kill->addDroppedItem($ditem);
414            }
415        }
416
417
418        if (!$authorized)
419        {
420            return -2;
421        }
422        if ($this->getError())
423        {
424            return 0;
425        }
426
427        if ($this->returnmail)
428        {
429            return $kill;
430        }
431        $id = $kill->add();
432        if ($id == -1)
433        {
434            $this->dupeid_ = $kill->dupeid_;
435        }
436
437        return $id;
438    }
439
440    function scanForItems($destroyed)
441    {
442        $i = 0;
443        $num = count($destroyed);
444        while ($i < $num)
445        {
446            $destroyed[$i] = trim($destroyed[$i]);
447            if ($destroyed[$i] == "")
448            {
449                $i++;
450                continue;
451            }
452
453            if ($destroyed[$i] == "Empty.")
454            {
455                $container = false;
456                $i++;
457                continue;
458            }
459
460            $qtypos = 0;
461            $locpos = 0;
462            $itemname = "";
463            $quantity = "";
464            $location = "";
465
466            $qtypos = strpos($destroyed[$i], ", Qty: ");
467            $locpos = strrpos($destroyed[$i], "(");
468
469            if ($container && $locpos != false)
470            {
471                $container = false;
472            }
473            if (strpos($destroyed[$i], "Container"))
474            {
475                $container = true;
476            }
477            if ($qtypos <= 0 && !$locpos)
478            {
479                $itemlen = strlen($destroyed[$i]);
480                if ($container) $location = "Cargo";
481            }
482            if ($qtypos > 0 && !$locpos)
483            {
484                $itemlen = $qtypos;
485                $qtylen = strlen($destroyed[$i]) - $qtypos;
486                if ($container) $location = "Cargo";
487            }
488            if ($locpos > 0 && $qtypos <= 0)
489            {
490                $itemlen = $locpos - 1;
491                $qtylen = 0;
492                $loclen = strlen($destroyed[$i]) - $locpos - 2;
493                if (!$locpos) $container = false;
494            }
495            if ($locpos > 0 && $qtypos > 0)
496            {
497                $itemlen = $qtypos;
498                $qtylen = $locpos - $qtypos - 7;
499                $loclen = strlen($destroyed[$i]) - $locpos - 2;
500                if (!$locpos) $container = false;
501            }
502
503            $itemname = substr($destroyed[$i], 0, $itemlen);
504            if ($qtypos) $quantity = substr($destroyed[$i], $qtypos + 6, $qtylen);
505            if ($locpos) $location = substr($destroyed[$i], $locpos + 1, $loclen);
506
507            if ($quantity == "")
508            {
509                $quantity = 1;
510            }
511
512            $item = new Item();
513            $item->lookup(trim($itemname));
514            if (!$item->getID())
515            {
516                $this->error('Item not found.', trim($itemname));
517            }
518            if ($location == 'In Container')
519            {
520                $location = 'Cargo';
521            }
522
523            $items[] = array('item' => $item, 'quantity' => $quantity, 'location' => $location);
524            $i++;
525        }
526
527        return $items;
528    }
529
530    function error($message, $debugtext = null)
531    {
532        $this->error_[] = array($message, $debugtext);
533    }
534
535    function getError()
536    {
537        if (count($this->error_))
538        {
539            return $this->error_;
540        }
541        return false;
542    }
543
544    function preparse($set)
545    {
546        if ($set == 'german')
547        {
548            $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)');
549            $replace = array('Victim:','Alliance: None','Alliance: None','Alliance:','Destroyed items','Destroyed','Security:','Involved parties:', 'Qty:', 'Corp:', '(Cargo)');
550            $this->killmail_ = str_replace($search, $replace, $this->killmail_);
551            return;
552        }
553        if ($set == 'prermr')
554        {
555            $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)');
556            $replace = array('Corp:','Destroyed:', 'System:', 'Security:', 'Security:', 'Ship:', 'Weapon:', '', '', '');
557            $this->killmail_ = str_replace($search, $replace, $this->killmail_);
558            $position = strpos($this->killmail_, 'Destroyed items:');
559            if ($position !== false)
560            {
561                $destroyed = explode("\n", strstr($this->killmail_, 'Destroyed items:'));
562                $i = 0;
563                $num = count($destroyed);
564                while ($i < $num)
565                {
566                    $destroyed[$i] = trim($destroyed[$i]);
567
568                    $itempos = strpos($destroyed[$i], 'Type: ');
569                    if ($itempos !== false)
570                    {
571                        $destroyed[$i] = substr($destroyed[$i], $itempos+6);
572                        if (isset($destroyed[$i+1]))
573                        {
574                            $quantitypos = strstr($destroyed[$i+1], 'Quantity: ');
575                            if ($quantitypos !== false)
576                            {
577                                $qty = ', Qty: '.substr($destroyed[$i+1], $quantitypos+10);
578                                $pos = strpos($destroyed[$i], '(');
579                                if ($pos !== false)
580                                {
581                                    $destroyed[$i] = trim(substr($destroyed[$i], 0, $pos)).$qty.' '.substr($destroyed[$i], $pos);
582                                }
583                                else
584                                {
585                                    $destroyed[$i] .= $qty;
586                                }
587                                unset($destroyed[$i+1]);
588                                $i++;
589                            }
590                        }
591                    }
592                    else
593                    {
594                        unset($destroyed[$i]);
595                    }
596                    $i++;
597                }
598                $this->killmail_ = substr($this->killmail_, 0, $position).'Destroyed items: '."\n\n\n".join("\n", $destroyed)."\n";
599            }
600        }
601    }
602}
603?>
Note: See TracBrowser for help on using the browser.