Passed
Branch master (1838bc)
by Pedro
02:07
created

BotParser::getQuestData()   C

Complexity

Conditions 13
Paths 2

Size

Total Lines 46
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 46
rs 6.6166
c 0
b 0
f 0
cc 13
nc 2
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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

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