root/dev/common/class.parser.php @ 133

Revision 133, 14.8 KB (checked in by exi, 14 years ago)

Reduced one potential sql-bug.
Added ability to identify items as t2 via their techlevel rather than just 'II'.
Fixed item location 0 to not cause skipping that item.
Added anzahl/quantity-replace for the german killpreparser.
Fixed final blow award to show correct numbers.
Removed unnecessary code from db.php.
Added a table data check to the sql importer and made the importer more verbose, this should minimize support requests caused by empty table data.
Fixed a small misalignment of the comment block.

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
20        if (strpos($this->killmail_, '**** Truncated - mail is too large ****') > 0)
21        {
22            $this->killmail_ = str_replace('**** Truncated - mail is too large ****', '', $this->killmail_);
23        }
24
25        // Parser fix, since some killmails don't have a final blow, they would break the KB
26        if (strpos($this->killmail_, 'laid the final blow') < 1)
27        {
28            $this->needs_final_blow_ = 1;
29        }
30    }
31
32    function parse($checkauth = true)
33    {
34        global $config;
35        // header
36        $involvedpos = strpos($this->killmail_, "Involved parties:");
37
38        $header = substr($this->killmail_, 0, $involvedpos);
39        $timestamp = substr($header, 0, 16);
40
41        if (preg_match("/Victim: (.*)/", $header, $matches))
42        {
43            $victimname = trim($matches[1]);
44        }
45        else
46        {
47            $this->error('No victim found.');
48        }
49        if (preg_match("/Alliance: (.*)/", $header, $matches))
50        {
51            $alliancename = trim($matches[1]);
52        }
53        else
54        {
55            $this->error('No alliance found.');
56        }
57        if (preg_match("/Corp: (.*)/", $header, $matches))
58        {
59            $corpname = trim($matches[1]);
60        }
61        else
62        {
63            $this->error('No corp found.');
64        }
65        if (preg_match("/Destroyed: (.*)/", $header, $matches))
66        {
67            $shipname = trim($matches[1]);
68        }
69        else
70        {
71            $this->error('No destroyed ship found.');
72        }
73        if (preg_match("/System: (.*)/", $header, $matches))
74        {
75            $systemname = trim($matches[1]);
76        }
77        else
78        {
79            $this->error('No system found.');
80        }
81        if (preg_match("/Security: (.*)/", $header, $matches))
82        {
83            $systemsec = trim($matches[1]);
84        }
85        else
86        {
87            $this->error('No security found.');
88        }
89
90        if (!isset($timestamp) ||
91                !isset($alliancename) ||
92                !isset($corpname) ||
93                !isset($victimname) ||
94                !isset($shipname) ||
95                !isset($systemname) ||
96                !isset($systemsec))
97            return 0;
98
99        if ($checkauth)
100        {
101            $authorized = false;
102        }
103        else
104        {
105            $authorized = true;
106        }
107
108        // populate/update database
109        $alliance = new Alliance();
110        $alliance->add($alliancename);
111        $corp = new Corporation();
112        $corp->add($corpname, $alliance, $timestamp);
113        $victim = new Pilot();
114        $victim->add($victimname, $corp, $timestamp);
115        $system = new SolarSystem();
116        $system->lookup($systemname);
117        if (!$system->getID())
118        {
119            $this->error('System not found.', $systemname);
120        }
121        $ship = new Ship();
122        $ship->lookup($shipname);
123        if (!$ship->getID())
124        {
125            $this->error('Ship not found.', $shipname);
126        }
127        $kill = new Kill();
128        $kill->setTimeStamp($timestamp);
129        $kill->setVictimID($victim->getID());
130        $kill->setVictimCorpID($corp->getID());
131        $kill->setVictimAllianceID($alliance->getID());
132        $kill->setVictimShip($ship);
133        $kill->setSolarSystem($system);
134
135        if (ALLIANCE_ID != 0 && $alliance->getID() == ALLIANCE_ID)
136            $authorized = true;
137        elseif (CORP_ID != 0)
138        {
139            $corps = explode(",", CORP_ID);
140            foreach($corps as $checkcorp)
141            {
142                if ($corp->getID() == $checkcorp)
143                    $authorized = true;
144            }
145        }
146
147        // involved
148        $end = strpos($this->killmail_, "Destroyed items:");
149        if ($end == 0)
150        {
151            $end = strlen($this->killmail_);
152        }
153        $involved = explode("\n", trim(substr($this->killmail_, strpos($this->killmail_, "Involved parties:") + 17, $end - (strpos($this->killmail_, "Involved parties:") + 17))));
154
155        $i = 0;
156
157        $order = 0;
158        while ($i < count($involved))
159        {
160            if ($involved[$i] == "")
161            {
162                $i++;
163                continue;
164            }
165
166            preg_match("/Name: (.*)/", $involved[$i], $matches);
167            $ipname = $matches[1];
168
169            preg_match("/(.*) \\(laid the final blow\\)/", $ipname, $matches);
170            if ($matches[1])
171            {
172                $ipname = $matches[1];
173                $finalblow = 1;
174            }
175            else
176            {
177                $finalblow = 0;
178            }
179
180            /* This is part of the final blow fix, mentioned above */
181            if ($this->needs_final_blow_)
182            {
183                $finalblow = 1;
184                $this->needs_final_blow_ = 0;
185            }
186            /* END FIX */
187
188            preg_match("/Security: (.*)/", $involved[$i + 1], $matches);
189            $secstatus = $matches[1];
190
191            if ($secstatus == "") // NPC or POS
192            {
193                $secstatus = "0.0";
194                preg_match("/(.*) \/ (.*)/", $ipname, $pmatches);
195                $icname = $pmatches[2];
196                $isname = "Unknown";
197                $iwname = $pmatches[1];
198                if (!strlen($icname) && !strlen($iwname))
199                {
200                    // fucked up bclinic killmail, no person here, continue
201                    $i++;
202                    continue;
203                }
204
205                $tmpcorp = new Corporation();
206                $tmpcorp->lookup($icname);
207
208                if (!$tmpcorp->getID())
209                {
210                    // not a known corp, add it
211                    $ialliance = new Alliance();
212                    $ialliance->add('None');
213                    $icorp = new Corporation();
214                    $icorp->add($icname, $ialliance, $kill->getTimeStamp());
215                    $tmpcorp = $icorp;
216                }
217                                $iweapon = new Item();
218                                $iweapon->lookup($pmatches[1]);
219                                $ipname = '#'.$tmpcorp->getID().'#'.$iweapon->getID().'#'.$iwname;
220                $tmpall = $tmpcorp->getAlliance();
221                // name will be None if no alliance is set
222                $ianame = $tmpall->getName();
223
224                $ialliance = &$tmpall;
225                $icorp = &$tmpcorp;
226
227                $i++;
228            }
229            else
230            {
231                preg_match("/Alliance: (.*)/", $involved[$i + 2], $matches);
232                $ianame = $matches[1];
233
234                preg_match("/Corp: (.*)/", $involved[$i + 3], $matches);
235                $icname = $matches[1];
236
237                preg_match("/Ship: (.*)/", $involved[$i + 4], $matches);
238                $isname = $matches[1];
239
240                preg_match("/Weapon: (.*)/", $involved[$i + 5], $matches);
241                $iwname = $matches[1];
242                $i += 6;
243
244                $ialliance = new Alliance();
245                $ialliance->add($ianame);
246                $icorp = new Corporation();
247                $icorp->add($icname, $ialliance, $kill->getTimeStamp());
248            }
249
250            $ipilot = new Pilot();
251            $ipilot->add($ipname, $icorp, $timestamp);
252
253            $iship = new Ship();
254            $iship->lookup($isname);
255            if (!$iship->getID())
256            {
257                $this->error('Ship not found.', $isname);
258            }
259            $iweapon = new Item();
260            $iweapon->lookup($iwname);
261            if (!$iweapon->getID())
262            {
263                $this->error('Weapon not found.', $iwname);
264            }
265
266            if (ALLIANCE_ID != 0 && $ialliance->getID() == ALLIANCE_ID)
267            {
268                $authorized = true;
269            }
270            elseif (CORP_ID != 0)
271            {
272                $corps = explode(",", CORP_ID);
273                foreach($corps as $corp)
274                {
275                    if ($icorp->getID() == $corp)
276                        $authorized = true;
277                }
278            }
279            if (!$authorized)
280            {
281                if ($string = $config->getConfig('post_permission'))
282                {
283                    if ($string == 'all')
284                    {
285                        $authorized = true;
286                    }
287                    else
288                    {
289                        $tmp = explode(',', $string);
290                        foreach ($tmp as $item)
291                        {
292                            if (!$item)
293                            {
294                                continue;
295                            }
296                            $typ = substr($item, 0, 1);
297                            $id = substr($item, 1);
298                            if ($typ == 'a')
299                            {
300                                if ($ialliance->getID() == $id)
301                                {
302                                    $authorized = true;
303                                    break;
304                                }
305                            }
306                            elseif ($typ == 'c')
307                            {
308                                if ($icorp->getID() == $id)
309                                {
310                                    $authorized = true;
311                                    break;
312                                }
313                            }
314                            elseif ($typ == 'p')
315                            {
316                                if ($ipilot->getID() == $id)
317                                {
318                                    $authorized = true;
319                                    break;
320                                }
321                            }
322                        }
323                    }
324                }
325            }
326
327            $iparty = new InvolvedParty($ipilot->getID(), $icorp->getID(),
328                $ialliance->getID(), $secstatus, $iship, $iweapon);
329            $kill->addInvolvedParty($iparty);
330
331            if ($finalblow == 1)
332            {
333                $kill->setFBPilotID($ipilot->getID());
334                $kill->setFBCorpID($icorp->getID());
335                $kill->setFBAllianceID($ialliance->getID());
336            }
337        }
338
339        // destroyed items
340        $destroyedpos = strpos($this->killmail_, "Destroyed items:");
341
342        if ($destroyedpos > 0)
343        {
344            $destroyed = explode("\n", trim(substr($this->killmail_,
345                         strpos($this->killmail_, "Destroyed items:") + 16,
346                         strlen($this->killmail_) - (strpos($this->killmail_, "Destroyed items:") + 16))));
347
348            $i = 0;
349            while ($i < count($destroyed))
350            {
351                if ($destroyed[$i] == "")
352                {
353                    $i++;
354                    continue;
355                }
356
357                if ($destroyed[$i] == "Empty.")
358                {
359                    $container = false;
360                    $i++;
361                    continue;
362                }
363
364                $qtypos = 0;
365                $locpos = 0;
366                $itemname = "";
367                $quantity = "";
368                $location = "";
369
370                $qtypos = strpos($destroyed[$i], ", Qty: ");
371                $locpos = strpos($destroyed[$i], "(");
372
373                if ($container && $qtypos == false)
374                {
375                    $container = false;
376                }
377                if (strpos($destroyed[$i], "Container"))
378                {
379                    $container = true;
380                }
381                if ($qtypos <= 0 && !$locpos)
382                {
383                    $itemlen = strlen($destroyed[$i]);
384                    if ($container) $location = "Cargo";
385                }
386                if ($qtypos > 0 && !$locpos)
387                {
388                    $itemlen = $qtypos;
389                    $qtylen = strlen($destroyed[$i]) - $qtypos;
390                    if ($container) $location = "Cargo";
391                }
392                if ($locpos > 0 && $qtypos <= 0)
393                {
394                    $itemlen = $locpos - 1;
395                    $qtylen = 0;
396                    $loclen = strlen($destroyed[$i]) - $locpos - 2;
397                    if (!$locpos) $container = false;
398                }
399                if ($locpos > 0 && $qtypos > 0)
400                {
401                    $itemlen = $qtypos;
402                    $qtylen = $locpos - $qtypos - 7;
403                    $loclen = strlen($destroyed[$i]) - $locpos - 2;
404                    if (!$locpos) $container = false;
405                }
406
407                $itemname = substr($destroyed[$i], 0, $itemlen);
408                if ($qtypos) $quantity = substr($destroyed[$i], $qtypos + 6, $qtylen);
409                if ($locpos) $location = substr($destroyed[$i], $locpos + 1, $loclen);
410
411                if ($quantity == "")
412                {
413                    $quantity = 1;
414                }
415
416                $item = new Item();
417                $item->lookup(trim($itemname));
418                if (!$item->getID())
419                {
420                    $this->error('Item not found.', trim($itemname));
421                }
422                $ditem = new DestroyedItem($item, $quantity, $location);
423                $kill->addDestroyedItem($ditem);
424
425                $i++;
426            }
427        }
428
429        if (!$authorized)
430        {
431            return -2;
432        }
433        if ($this->getError())
434        {
435            return 0;
436        }
437
438        $id = $kill->add();
439        if ($id == -1)
440        {
441            $this->dupeid_ = $kill->dupeid_;
442        }
443
444        return $id;
445    }
446
447    function error($message, $debugtext = null)
448    {
449        $this->error_[] = array($message, $debugtext);
450    }
451
452    function getError()
453    {
454        if (count($this->error_))
455        {
456            return $this->error_;
457        }
458        return false;
459    }
460
461    function preparse($set)
462    {
463        if ($set == 'german')
464        {
465            $search = array('Ziel:','Allianz: nichts','Allianz:','Zerstört','Sicherheit:','Beteiligte Parteien:','Anz:');
466            $replace = array('Victim:','Alliance: None','Alliance:','Destroyed','Security:','Involved parties:', 'Qty:');
467            $this->killmail_ = str_replace($search, $replace, $this->killmail_);
468            return;
469        }
470    }
471}
472?>
Note: See TracBrowser for help on using the browser.