Passed
Push — master ( 39edd6...47e6f5 )
by Pedro
01:57
created

BotParser::getMapDimensions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Application\Service;
4
5
use Carbon\Carbon;
6
7
class BotParser
8
{
9
    const ONLINE_COLOR = '#0080e1';
10
    const OFFLINE_COLOR = '#d30000';
11
    const ITEM_COLOR = '#ff8000';
12
    const UNIQUE_ITEM_COLOR = '#ffc000';
13
    private $items = [
14
        'amulet',
15
        'boots',
16
        'charm',
17
        'gloves',
18
        'helm',
19
        'leggings',
20
        'ring',
21
        'shield',
22
        'tunic',
23
        'weapon',
24
    ];
25
    private $penalties = [
26
        'kick',
27
        'logout',
28
        'msg',
29
        'nick',
30
        'part',
31
        'quest',
32
        'quit',
33
    ];
34
    private $config;
35
36
    public function __construct(array $config)
37
    {
38
        $this->config = $config;
39
    }
40
41
    /**
42
     * Converts a DateInterval to a human readable format
43
     * Returns 'None' if the difference is zero
44
     * @param int $seconds
45
     * @return string
46
     */
47
    private function secondsToTime(int $seconds)
48
    {
49
        $result = 'None';
50
51
        if ($seconds > 0) {
52
            $dtF = new Carbon('@0');
53
            $dtT = new Carbon("@$seconds");
54
            $result = $dtF->diffForHumans($dtT, true, false, 2);
55
        }
56
57
        return $result;
58
    }
59
60
    /**
61
     * Returns the alignment
62
     * @param string $alignment
63
     * @return string
64
     */
65
    private function parseAlignment(string $alignment)
66
    {
67
        $align = "";
68
        switch ($alignment) {
69
            case 'n':
70
                $align = "Neutral";
71
                break;
72
            case 'e':
73
                $align = "Evil";
74
                break;
75
            case 'g':
76
                $align = "Good";
77
                break;
78
        }
79
        return $align;
80
    }
81
82
    /**
83
     * Returns the name of item if it is unique, or null if it isn't
84
     * @param mixed $item_value
85
     * @return null|string
86
     */
87
    private function parseUniqueItem($item_value)
88
    {
89
        $result = null;
90
91
        $regex = '/\d+([a-h])/';
92
        preg_match($regex, $item_value, $matches);
93
94
        if (isset($matches[1])) {
95
            switch ($matches[1]) {
96
                case 'a':
97
                    $result = "Mattt's Omniscience Grand Crown";
98
                    break;
99
                case 'b':
100
                    $result = "Res0's Protectorate Plate Mail";
101
                    break;
102
                case 'c':
103
                    $result = "Dwyn's Storm Magic Amulet";
104
                    break;
105
                case 'd':
106
                    $result = "Jotun's Fury Colossal Sword";
107
                    break;
108
                case 'e':
109
                    $result = "Drdink's Cane of Blind Rage";
110
                    break;
111
                case 'f':
112
                    $result = "Mrquick's Magical Boots of Swiftness";
113
                    break;
114
                case 'g':
115
                    $result = "Jeff's Cluehammer of Doom";
116
                    break;
117
                case 'h':
118
                    $result = "Juliet's Glorious Ring of Sparkliness";
119
                    break;
120
            }
121
        }
122
123
        return $result;
124
    }
125
126
    /**
127
     * Sums the values from the keys of the array $record from $start till $end
128
     * @param array $record
129
     * @param int $start
130
     * @param int $end
131
     * @return int
132
     */
133
    private function sumFields(array $record, int $start, int $end)
134
    {
135
        $total = 0;
136
        for ($i = $start; $i <= $end; $i++) {
137
            $total += (int) $record[$i];
138
        }
139
        return $total;
140
    }
141
142
    /**
143
     * @return array
144
     */
145
    public function getPenaltiesList()
146
    {
147
        return $this->penalties;
148
    }
149
150
    /**
151
     * @return array
152
     */
153
    public function getItemsList()
154
    {
155
        return $this->items;
156
    }
157
158
    /**
159
     * Returns an array with a list of all the Items from the database
160
     * @return array
161
     */
162
    public function getItems()
163
    {
164
        $items = [];
165
        $row = 0;
166
        if (($handle = fopen($this->config['bot_item'], "r")) !== false) {
167
            while (($data = fgetcsv($handle, 1024, "\t")) !== false) {
168
                $row++;
169
                if ($row == 1) {
170
                    continue;
171
                }
172
173
                $record = [
174
                    'x_pos' => (int) $data[0],
175
                    'y_pos' => (int) $data[1],
176
                    'type'  => $data[2],
177
                    'level' => $data[3],
178
                    'age'   => $data[4]
179
                ];
180
181
                $items[] = $record;
182
            }
183
            fclose($handle);
184
        }
185
186
        return $items;
187
    }
188
189
    /**
190
     * Returns an array with the Players, sorted by level
191
     * Includes the fields needed for the scoreboard page
192
     * @return array
193
     */
194
    public function getScoreboard()
195
    {
196
        $players = [];
197
        $row = 0;
198
        if (($handle = fopen($this->config['bot_db'], "r")) !== false) {
199
            while (($data = fgetcsv($handle, 1024, "\t")) !== false) {
200
                $row++;
201
                if ($row == 1) {
202
                    continue;
203
                }
204
                $players[] = [
205
                    'nick'   => $data[0],
206
                    'level'  => (int) $data[3],
207
                    'class'  => $data[4],
208
                    'ttl'    => $this->secondsToTime((int) $data[5]),
209
                    'status' => (bool) $data[8],
210
                ];
211
            }
212
            fclose($handle);
213
        }
214
        array_multisort(array_column($players, 'level'), SORT_DESC, $players);
0 ignored issues
show
Bug introduced by
array_column($players, 'level') cannot be passed to array_multisort() as the parameter $arr expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

214
        array_multisort(/** @scrutinizer ignore-type */ array_column($players, 'level'), SORT_DESC, $players);
Loading history...
215
216
        return $players;
217
    }
218
219
    /**
220
     * Returns a list with (almost) all the fields from the Players database
221
     * If the parameter $nick is used, only returns the data for that Player
222
     * or 0 if that Player doesn't exist
223
     * @param string|null $nick
224
     * @return array|int|mixed
225
     */
226
    public function getDatabase(string $nick = null)
227
    {
228
        $database = [];
229
        $row = 0;
230
        if (($handle = fopen($this->config['bot_db'], "r")) !== false) {
231
            while (($data = fgetcsv($handle, 1024, "\t")) !== false) {
232
                $row++;
233
                if ($row == 1) {
234
                    continue;
235
                }
236
237
                if ($nick !== null && strcmp($data[0], $nick) !== 0) {
238
                    continue;
239
                }
240
241
                $record = [
242
                    'nick' => $data[0], // nick
243
                    'level' => $data[3], // level
244
                    'admin' => ($data[2] ? 'Yes' : 'No'), // admin
245
                    'class' => $data[4], // class
246
                    'ttl' => [
247
                        'display' => $this->secondsToTime((int) $data[5]),
248
                        'numeric' => (int) $data[5], // ttl
249
                    ],
250
                    'nick_host' => $data[7], // nick and host
251
                    'online' => ($data[8] ? 'Yes' : 'No'), // online
252
                    'idled' => [
253
                        'display' => $this->secondsToTime((int) $data[9]), // idled
254
                        'numeric' => (int) $data[9],
255
                    ],
256
                    'x_pos' => (int) $data[10], // x pos
257
                    'y_pos' => (int) $data[11], // y pos
258
                    'msg_pen' => [
259
                        'display' => $this->secondsToTime((int) $data[12]), // msg pen
260
                        'numeric' => (int) $data[12],
261
                    ],
262
                    'nick_pen' => [
263
                        'display' => $this->secondsToTime((int) $data[13]), // nick pen
264
                        'numeric' => (int) $data[13],
265
                    ],
266
                    'part_pen' => [
267
                        'display' => $this->secondsToTime((int) $data[14]), // part pen
268
                        'numeric' => (int) $data[14],
269
                    ],
270
                    'kick_pen' => [
271
                        'display' => $this->secondsToTime((int) $data[15]), // kick pen
272
                        'numeric' => (int) $data[15],
273
                    ],
274
                    'quit_pen' => [
275
                        'display' => $this->secondsToTime((int) $data[16]), // quit pen
276
                        'numeric' => (int) $data[16],
277
                    ],
278
                    'quest_pen' => [
279
                        'display' => $this->secondsToTime((int) $data[17]), // quest pen
280
                        'numeric' => (int) $data[17],
281
                    ],
282
                    'logout_pen' => [
283
                        'display' => $this->secondsToTime((int) $data[18]), // logout pen
284
                        'numeric' => (int) $data[18],
285
                    ],
286
                    'total_pen' => [
287
                        'display' => $this->secondsToTime($this->sumFields($data, 12, 18)),
288
                        'numeric' => $this->sumFields($data, 12, 18),
289
                    ],
290
                    'created' => [
291
                        'display' => date('Y-m-d H:i:s', (int) $data[19]), // created
292
                        'numeric' => (int) $data[19],
293
                    ],
294
                    'last_login' => [
295
                        'display' => date('Y-m-d H:i:s', (int) $data[20]), // last login
296
                        'numeric' => (int) $data[20],
297
                    ],
298
                    'amulet' => [
299
                        'display' => $data[21], // amulet
300
                        'numeric' => (int) $data[21],
301
                        'unique' => $this->parseUniqueItem($data[21])
302
                    ],
303
                    'charm' => [
304
                        'display' => $data[22], // charm
305
                        'numeric' => (int) $data[22],
306
                        'unique' => $this->parseUniqueItem($data[22])
307
                    ],
308
                    'helm' => [
309
                        'display' => $data[23], // helm
310
                        'numeric' => (int) $data[23],
311
                        'unique' => $this->parseUniqueItem($data[23])
312
                    ],
313
                    'boots' => [
314
                        'display' => $data[24], // boots
315
                        'numeric' => (int) $data[24],
316
                        'unique' => $this->parseUniqueItem($data[24])
317
                    ],
318
                    'gloves' => [
319
                        'display' => $data[25], // gloves
320
                        'numeric' => (int) $data[25],
321
                        'unique' => $this->parseUniqueItem($data[25])
322
                    ],
323
                    'ring' => [
324
                        'display' => $data[26], // ring
325
                        'numeric' => (int) $data[26],
326
                        'unique' => $this->parseUniqueItem($data[26])
327
                    ],
328
                    'leggings' => [
329
                        'display' => $data[27], // leggings
330
                        'numeric' => (int) $data[27],
331
                        'unique' => $this->parseUniqueItem($data[27])
332
                    ],
333
                    'shield' => [
334
                        'display' => $data[28], // shield
335
                        'numeric' => (int) $data[28],
336
                        'unique' => $this->parseUniqueItem($data[28])
337
                    ],
338
                    'tunic' => [
339
                        'display' => $data[29], // tunic
340
                        'numeric' => (int) $data[29],
341
                        'unique' => $this->parseUniqueItem($data[29])
342
                    ],
343
                    'weapon' => [
344
                        'display' => $data[30], // weapon
345
                        'numeric' => (int) $data[30],
346
                        'unique' => $this->parseUniqueItem($data[30])
347
                    ],
348
                    'sum' => $this->sumFields($data, 21, 30),
349
                    'alignment' => $this->parseAlignment($data[31]), // alignment
350
                ];
351
352
                if ($nick !== null) {
353
                    return $record;
354
                }
355
356
                $database[] = $record;
357
            }
358
            fclose($handle);
359
        }
360
361
        if ($nick !== null) {
362
            return 0;
363
        }
364
365
        return $database;
366
    }
367
368
    /**
369
     * Returns the last $limit events [from the user $nick]
370
     * If $limit is 0 returns all
371
     * @param int $limit
372
     * @param string|null $nick
373
     * @return array|mixed
374
     */
375
    public function getEvents(int $limit, string $nick = null)
376
    {
377
        $modifiers = [
378
            'items' => [],
379
            'total' => 0,
380
        ];
381
382
        $tmp = [];
383
        $handle = fopen($this->config['bot_mod'], "r");
384
        if ($handle !== false) {
385
            while (($line = fgets($handle)) !== false) {
386
                if ($nick !== null && strpos($line, $nick) !== false) {
387
                    $tmp[] = $line;
388
                }
389
390
                if ($nick === null) {
391
                    $tmp[] = $line;
392
                }
393
            }
394
            fclose($handle);
395
        }
396
397
        $tmp = array_reverse($tmp);
398
        $modifiers['total'] = count($tmp);
399
        $modifiers['items'] = array_slice($tmp, 0, ($limit > 0 ) ? $limit : null);
400
401
        return $modifiers;
402
    }
403
404
    /**
405
     * Returns an array with the coordinates and name of all Players and Items
406
     * @return array
407
     */
408
    public function getCoordinates()
409
    {
410
        $coordinates = [];
411
412
        $players = $this->getDatabase();
413
        $items = $this->getItems();
414
415
        foreach ($players as $player) {
416
            $coordinates[] = [
417
                'x'     => $player['x_pos'],
418
                'y'     => $player['y_pos'],
419
                'text'  => $player['nick'],
420
                'color' => ($player['online'] == 'Yes' ? self::ONLINE_COLOR : self::OFFLINE_COLOR)
421
            ];
422
        }
423
424
        foreach ($items as $item) {
425
            $coordinates[] = [
426
                'x'     => $item['x_pos'],
427
                'y'     => $item['y_pos'],
428
                'text'  => $item['type'],
429
                'color' => self::ITEM_COLOR,
430
            ];
431
        }
432
433
        return $coordinates;
434
    }
435
436
    /**
437
     * Returns an array with all the data associated with the current quest
438
     * @return array
439
     */
440
    public function getQuestData()
441
    {
442
        $quest = [];
443
        if (($handle = fopen($this->config['bot_quest'], "r")) !== false) {
444
            while (($data = fgets($handle, 1024)) !== false) {
445
                // T - title
446
                if (! isset($data['title']) && $data[0] == "T") {
447
                    $quest['title'] = substr($data, 2);
448
                }
449
                // Y - type. 1 for time based, 2 for stages
450
                if (! isset($data['type']) && $data[0] == "Y") {
451
                    $quest['type'] = (int) substr($data, 2);
452
                }
453
                // S - objective
454
                if ($data[0] == "S") {
455
                    if ($quest['type'] == 1) {
456
                        // Time to end
457
                        $quest['objective'] = $this->secondsToTime((int) substr($data, 2));
458
                    } elseif ($quest['type'] == 2) {
459
                        // Stage
460
                        $quest['objective'] = (int) substr($data, 2);
461
                    }
462
                }
463
                if ($data[0] == "P") {
464
                    $data_exploded = explode(" ", $data);
465
                    // P - stages position
466
                    if ($data_exploded[0] == "P") {
467
                        $quest['stages'] = [
468
                            [
469
                                'x_pos' => (int) $data_exploded[1],
470
                                'y_pos' => (int) $data_exploded[2],
471
                                'color' => self::OFFLINE_COLOR,
472
                            ],
473
                            [
474
                                'x_pos' => (int) $data_exploded[3],
475
                                'y_pos' => (int) $data_exploded[4],
476
                                'color' => self::OFFLINE_COLOR,
477
                            ],
478
                        ];
479
                    }
480
                    // P{1-4} - player position
481
                    if (isset($data_exploded[0][1])) {
482
                        $quest['players'][] = [
483
                            'nick'  => $data_exploded[1],
484
                            'x_pos' => (int) $data_exploded[2],
485
                            'y_pos' => (int) $data_exploded[3],
486
                            'color' => self::ONLINE_COLOR,
487
                        ];
488
                    }
489
                }
490
            }
491
            fclose($handle);
492
        }
493
494
        return $quest;
495
    }
496
497
    /**
498
     * Returns an array with all the Players nicks
499
     * @return array
500
     */
501
    public function getPlayers()
502
    {
503
        $players = [];
504
505
        $row = 0;
506
        if (($handle = fopen($this->config['bot_db'], "r")) !== false) {
507
            while (($data = fgetcsv($handle, 1024, "\t")) !== false) {
508
                $row++;
509
                if ($row == 1) {
510
                    continue;
511
                }
512
513
                $players[] = $data[0]; // nick
514
            }
515
        }
516
517
        return $players;
518
    }
519
520
    /**
521
     * Returns an array with the dimensions of the map image
522
     * @return array
523
     */
524
    public function getMapDimensions()
525
    {
526
        return [
527
            'height' => $this->config['map_height'],
528
            'width'  => $this->config['map_width'],
529
        ];
530
    }
531
}
532