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

Revision 274, 20.5 KB (checked in by exi, 15 years ago)

Added new german translation parsing.
Changed upgrade sql so it doesn't kill all rows if something is wrong.

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