Passed
Pull Request — master (#1830)
by Nico
30:56
created

ShipTick::checkForFinishedAstroMapping()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 21
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 33
ccs 0
cts 22
cp 0
crap 56
rs 8.6506
1
<?php
2
3
namespace Stu\Module\Tick\Ship;
4
5
use RuntimeException;
6
use Stu\Component\Ship\AstronomicalMappingEnum;
7
use Stu\Component\Ship\Repair\RepairUtilInterface;
8
use Stu\Component\Ship\ShipAlertStateEnum;
9
use Stu\Component\Ship\ShipStateEnum;
10
use Stu\Component\Ship\System\Data\EpsSystemData;
11
use Stu\Component\Ship\System\ShipSystemManagerInterface;
12
use Stu\Component\Ship\System\ShipSystemTypeEnum;
13
use Stu\Component\Station\StationUtilityInterface;
14
use Stu\Module\Control\GameControllerInterface;
15
use Stu\Module\Database\Lib\CreateDatabaseEntryInterface;
16
use Stu\Module\Logging\LoggerUtilFactoryInterface;
17
use Stu\Module\Logging\LoggerUtilInterface;
18
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
19
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
20
use Stu\Module\PlayerSetting\Lib\UserEnum;
21
use Stu\Module\Ship\Lib\AstroEntryLibInterface;
22
use Stu\Module\Ship\Lib\Crew\ShipLeaverInterface;
23
use Stu\Module\Ship\Lib\Interaction\ShipTakeoverManagerInterface;
24
use Stu\Module\Ship\Lib\Interaction\TrackerDeviceManagerInterface;
25
use Stu\Module\Ship\Lib\ReactorWrapperInterface;
26
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
27
use Stu\Module\Ship\Lib\ShipWrapperInterface;
28
use Stu\Module\Ship\View\ShowShip\ShowShip;
29
use Stu\Module\Tick\Ship\ManagerComponent\ManagerComponentInterface;
30
use Stu\Orm\Entity\DatabaseEntryInterface;
31
use Stu\Orm\Entity\ShipInterface;
32
use Stu\Orm\Repository\DatabaseUserRepositoryInterface;
33
use Stu\Orm\Repository\ShipRepositoryInterface;
34
35
final class ShipTick implements ShipTickInterface, ManagerComponentInterface
36
{
37
    private LoggerUtilInterface $loggerUtil;
38
39
    /**
40
     * @var array<string>
41
     */
42
    private array $msg = [];
43
44
    public function __construct(
45
        private ShipWrapperFactoryInterface $shipWrapperFactory,
46
        private PrivateMessageSenderInterface $privateMessageSender,
47
        private ShipRepositoryInterface $shipRepository,
48
        private ShipSystemManagerInterface $shipSystemManager,
49
        private ShipLeaverInterface $shipLeaver,
50
        private GameControllerInterface $game,
51
        private AstroEntryLibInterface $astroEntryLib,
52
        private DatabaseUserRepositoryInterface $databaseUserRepository,
53
        private CreateDatabaseEntryInterface $createDatabaseEntry,
54
        private StationUtilityInterface $stationUtility,
55
        private RepairUtilInterface $repairUtil,
56
        private ShipTakeoverManagerInterface $shipTakeoverManager,
57
        private TrackerDeviceManagerInterface $trackerDeviceManager,
58
        LoggerUtilFactoryInterface $loggerUtilFactory
59
    ) {
60
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil(true);
61
    }
62
63
    public function work(): void
64
    {
65
        foreach ($this->shipRepository->getPlayerShipsForTick() as $ship) {
66
            $this->workShip($this->shipWrapperFactory->wrapShip($ship));
67
        }
68
    }
69
70
    public function workShip(ShipWrapperInterface $wrapper): void
71
    {
72
        $ship = $wrapper->get();
73
74
        $startTime = microtime(true);
75
76
        // do construction stuff
77
        if ($this->doConstructionStuff($ship)) {
78
            $this->shipRepository->save($ship);
79
            $this->sendMessages($ship);
80
            return;
81
        }
82
83
        $this->potentialLog($ship, "marker0", $startTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime can also be of type string; however, parameter $startTime of Stu\Module\Tick\Ship\ShipTick::potentialLog() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

83
        $this->potentialLog($ship, "marker0", /** @scrutinizer ignore-type */ $startTime);
Loading history...
84
85
86
        $startTime = microtime(true);
87
        // repair station
88
        if ($ship->isBase() && $ship->getState() === ShipStateEnum::SHIP_STATE_REPAIR_PASSIVE) {
89
            $this->doRepairStation($wrapper);
90
        }
91
        $this->potentialLog($ship, "marker1", $startTime);
92
93
        $startTime = microtime(true);
94
        // leave ship
95
        if ($ship->getCrewCount() > 0 && !$ship->isSystemHealthy(ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT)) {
96
            $this->msg[] = _('Die Lebenserhaltung ist ausgefallen:');
97
            $this->msg[] = $this->shipLeaver->evacuate($wrapper);
98
            $this->sendMessages($ship);
99
            $this->potentialLog($ship, "marker2", $startTime);
100
            return;
101
        }
102
103
        $startTime = microtime(true);
104
        $eps = $wrapper->getEpsSystemData();
105
        $reactor = $wrapper->getReactorWrapper();
106
        if ($eps === null) {
107
            $this->potentialLog($ship, "marker3", $startTime);
108
            return;
109
        }
110
111
        $startTime = microtime(true);
112
        $hasEnoughCrew = $ship->hasEnoughCrew();
113
114
        // not enough crew
115
        if (!$hasEnoughCrew) {
116
            $this->msg[] = _('Zu wenig Crew an Bord, Schiff ist nicht voll funktionsfähig! Systeme werden deaktiviert!');
117
118
            //deactivate all systems except life support
119
            foreach ($this->shipSystemManager->getActiveSystems($ship) as $system) {
120
                if ($system->getSystemType() != ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT) {
121
                    $this->shipSystemManager->deactivate($wrapper, $system->getSystemType(), true);
122
                }
123
            }
124
        }
125
        $this->potentialLog($ship, "marker4", $startTime);
126
127
        $startTime = microtime(true);
128
        $reactorUsageForWarpdrive = $this->loadWarpdrive(
129
            $wrapper,
130
            $hasEnoughCrew
131
        );
132
        $this->potentialLog($ship, "marker5", $startTime);
133
134
        $startTime = microtime(true);
135
        $availableEps = $this->getAvailableEps(
136
            $wrapper,
137
            $eps,
138
            $reactor,
139
            $hasEnoughCrew,
140
            $reactorUsageForWarpdrive
141
        );
142
        $this->potentialLog($ship, "marker6", $startTime);
143
144
        $startTime = microtime(true);
145
        //try to save energy by reducing alert state
146
        if ($wrapper->getEpsUsage() > $availableEps) {
147
            $malus = $wrapper->getEpsUsage() - $availableEps;
148
            $alertUsage = $ship->getAlertState()->value - 1;
149
150
            if ($alertUsage > 0) {
151
                $preState = $ship->getAlertState();
152
                $reduce = (int)min($malus, $alertUsage);
153
154
                $ship->setAlertState(ShipAlertStateEnum::from($preState->value - $reduce));
155
                $this->msg[] = sprintf(
156
                    _('Wechsel von %s auf %s wegen Energiemangel'),
157
                    $preState->getDescription(),
158
                    $ship->getAlertState()->getDescription()
159
                );
160
            }
161
        }
162
        $this->potentialLog($ship, "marker7", $startTime);
163
164
        $startTime = microtime(true);
165
        //try to save energy by deactivating systems from low to high priority
166
        if ($wrapper->getEpsUsage() > $availableEps) {
167
            $activeSystems = $this->shipSystemManager->getActiveSystems($ship, true);
168
169
            foreach ($activeSystems as $system) {
170
                $energyConsumption = $this->shipSystemManager->getEnergyConsumption($system->getSystemType());
171
                if ($energyConsumption < 1) {
172
                    continue;
173
                }
174
175
                //echo "- eps: ".$eps." - usage: ".$wrapper->getEpsUsage()."\n";
176
                if ($availableEps - $wrapper->getEpsUsage() - $energyConsumption < 0) {
177
                    //echo "-- hit system: ".$system->getDescription()."\n";
178
179
                    $this->shipSystemManager->deactivate($wrapper, $system->getSystemType(), true);
180
181
                    $wrapper->lowerEpsUsage($energyConsumption);
182
                    $this->msg[] = $system->getSystemType()->getDescription() . ' deaktiviert wegen Energiemangel';
183
184
                    if ($ship->getCrewCount() > 0 && $system->getSystemType() == ShipSystemTypeEnum::SYSTEM_LIFE_SUPPORT) {
185
                        $this->msg[] = _('Die Lebenserhaltung ist ausgefallen:');
186
                        $this->msg[] = $this->shipLeaver->evacuate($wrapper);
187
                        $this->sendMessages($ship);
188
                        return;
189
                    }
190
                }
191
                if ($wrapper->getEpsUsage() <= $availableEps) {
192
                    break;
193
                }
194
            }
195
        }
196
197
        $this->potentialLog($ship, "marker8", $startTime);
198
        $startTime = microtime(true);
199
200
        $newEps = $availableEps - $wrapper->getEpsUsage();
201
        $batteryReload = $ship->isBase()
202
            && $eps->reloadBattery()
203
            && $newEps > $eps->getEps()
204
            ? min(
205
                (int) ceil($eps->getMaxBattery() / 10),
206
                $newEps - $eps->getEps(),
207
                $eps->getMaxBattery() - $eps->getBattery()
208
            ) : 0;
209
210
        $newEps -= $batteryReload;
211
        if ($newEps > $eps->getMaxEps()) {
212
            $newEps = $eps->getMaxEps();
213
        }
214
215
216
        $usedEnergy = $wrapper->getEpsUsage() + $batteryReload + ($newEps - $eps->getEps()) + $reactorUsageForWarpdrive;
217
218
        //echo "--- Generated Id ".$ship->getId()." - eps: ".$eps." - usage: ".$wrapper->getEpsUsage()." - old eps: ".$ship->getEps()." - wk: ".$wkuse."\n";
219
        $eps->setEps($newEps)
220
            ->setBattery($eps->getBattery() + $batteryReload)
221
            ->update();
222
223
        if ($usedEnergy > 0 && $reactor !== null) {
224
            $reactor->changeLoad(-$usedEnergy);
225
        }
226
227
        $this->potentialLog($ship, "marker9", $startTime);
228
229
        $startTime = microtime(true);
230
        $this->checkForFinishedTakeover($ship);
231
        $this->potentialLog($ship, "marker10", $startTime);
232
233
        $startTime = microtime(true);
234
        $this->checkForFinishedAstroMapping($wrapper);
235
        $this->potentialLog($ship, "marker11", $startTime);
236
237
        //update tracker status
238
        $startTime = microtime(true);
239
        $this->doTrackerDeviceStuff($wrapper);
240
        $this->potentialLog($ship, "marker12", $startTime);
241
242
        $startTime = microtime(true);
243
        $this->shipRepository->save($ship);
244
        $this->potentialLog($ship, "marker13", $startTime);
245
246
        $startTime = microtime(true);
247
        $this->sendMessages($ship);
248
        $this->potentialLog($ship, "marker14", $startTime);
249
    }
250
251
    private function potentialLog(ShipInterface $ship, string $marker, float $startTime): void
252
    {
253
        $endTime = microtime(true);
254
255
        if (
256
            $endTime - $startTime > 0.01
257
        ) {
258
            $this->loggerUtil->log(sprintf(
259
                "\t\t\t%s of %d, seconds: %F",
260
                $marker,
261
                $ship->getId(),
262
                $endTime - $startTime
263
            ));
264
        }
265
    }
266
267
    private function getAvailableEps(
268
        ShipWrapperInterface $wrapper,
269
        EpsSystemData $eps,
270
        ?ReactorWrapperInterface $reactor,
271
        bool $hasEnoughCrew,
272
        int $reactorUsageForWarpdrive
273
    ): int {
274
        if ($hasEnoughCrew && $reactor !== null) {
275
276
            return $eps->getEps() + $reactor->getEpsProduction() +  $this->getCarryOver(
277
                $wrapper,
278
                $reactor,
279
                $reactorUsageForWarpdrive
280
            );
281
        }
282
283
        return $eps->getEps();
284
    }
285
286
    private function getCarryOver(
287
        ShipWrapperInterface $wrapper,
288
        ReactorWrapperInterface $reactor,
289
        int $reactorUsageForWarpdrive
290
    ): int {
291
        $warpdrive = $wrapper->getWarpDriveSystemData();
292
        if ($warpdrive === null || !$warpdrive->getAutoCarryOver()) {
293
            return 0;
294
        }
295
296
        return $reactor->getOutputCappedByLoad() - $reactor->getEpsProduction() - $reactorUsageForWarpdrive;
297
    }
298
299
    private function loadWarpdrive(ShipWrapperInterface $wrapper, bool $hasEnoughCrew): int
300
    {
301
        if (!$hasEnoughCrew) {
302
            return 0;
303
        }
304
305
        $reactor = $wrapper->getReactorWrapper();
306
        $warpdrive = $wrapper->getWarpDriveSystemData();
307
        if ($warpdrive === null || $reactor === null) {
308
            return 0;
309
        }
310
311
        $effectiveWarpdriveProduction = $reactor->getEffectiveWarpDriveProduction();
312
        if ($effectiveWarpdriveProduction === 0) {
313
            return 0;
314
        }
315
316
        $currentLoad = $warpdrive->getWarpDrive();
317
318
        $warpdrive->setWarpDrive($currentLoad + $effectiveWarpdriveProduction)->update();
319
320
        return $effectiveWarpdriveProduction * $wrapper->get()->getRump()->getFlightECost();
321
    }
322
323
    private function doConstructionStuff(ShipInterface $ship): bool
324
    {
325
        $progress =  $this->stationUtility->getConstructionProgress($ship);
326
327
        if ($progress === null) {
328
            return false;
329
        }
330
331
        if ($progress->getRemainingTicks() === 0) {
332
            return false;
333
        }
334
335
        $isUnderConstruction = $ship->getState() === ShipStateEnum::SHIP_STATE_UNDER_CONSTRUCTION;
336
337
        if (!$this->stationUtility->hasEnoughDockedWorkbees($ship, $ship->getRump())) {
338
            $neededWorkbees = $isUnderConstruction ? $ship->getRump()->getNeededWorkbees() :
339
                (int)ceil($ship->getRump()->getNeededWorkbees() / 2);
340
341
            $this->msg[] = sprintf(
342
                _('Nicht genügend Workbees (%d/%d) angedockt um %s weiterführen zu können'),
343
                $this->stationUtility->getDockedWorkbeeCount($ship),
344
                $neededWorkbees,
345
                $isUnderConstruction ? 'den Bau' : 'die Demontage'
346
            );
347
            return true;
348
        }
349
350
        if ($progress->getRemainingTicks() === 1) {
351
            if ($isUnderConstruction) {
352
                $this->stationUtility->finishStation($ship, $progress);
353
            } else {
354
                $this->stationUtility->finishScrapping($ship, $progress);
355
            }
356
357
            $this->msg[] = sprintf(
358
                _('%s: %s bei %s fertiggestellt'),
359
                $ship->getRump()->getName(),
360
                $isUnderConstruction ? 'Bau' : 'Demontage',
361
                $ship->getSectorString()
362
            );
363
        } else {
364
            $this->stationUtility->reduceRemainingTicks($progress);
365
366
            if ($isUnderConstruction) {
367
                // raise hull
368
                $increase = intdiv($ship->getMaxHull(), 2 * $ship->getRump()->getBuildtime());
369
                $ship->setHuell($ship->getHull() + $increase);
370
            }
371
        }
372
373
        return true;
374
    }
375
376
    private function doRepairStation(ShipWrapperInterface $wrapper): void
377
    {
378
        $station = $wrapper->get();
379
380
        if (!$this->stationUtility->hasEnoughDockedWorkbees($station, $station->getRump())) {
381
            $neededWorkbees = (int)ceil($station->getRump()->getNeededWorkbees() / 5);
382
383
            $this->msg[] = sprintf(
384
                _('Nicht genügend Workbees (%d/%d) angedockt um die Reparatur weiterführen zu können'),
385
                $this->stationUtility->getDockedWorkbeeCount($station),
386
                $neededWorkbees
387
            );
388
            return;
389
        }
390
391
        $neededParts = $this->repairUtil->determineSpareParts($wrapper, true);
392
393
        // parts stored?
394
        if (!$this->repairUtil->enoughSparePartsOnEntity($neededParts, $station, $station)) {
395
            return;
396
        }
397
398
        //repair hull
399
        $station->setHuell($station->getHull() + $station->getRepairRate());
400
        if ($station->getHull() > $station->getMaxHull()) {
401
            $station->setHuell($station->getMaxHull());
402
        }
403
404
        //repair station systems
405
        $damagedSystems = $wrapper->getDamagedSystems();
406
        if (!empty($damagedSystems)) {
407
            $firstSystem = $damagedSystems[0];
408
            $firstSystem->setStatus(100);
409
410
            if ($station->getCrewCount() > 0) {
411
                $firstSystem->setMode($this->shipSystemManager->lookupSystem($firstSystem->getSystemType())->getDefaultMode());
412
            }
413
414
            // maximum of two systems get repaired
415
            if (count($damagedSystems) > 1) {
416
                $secondSystem = $damagedSystems[1];
417
                $secondSystem->setStatus(100);
418
419
                if ($station->getCrewCount() > 0) {
420
                    $secondSystem->setMode($this->shipSystemManager->lookupSystem($secondSystem->getSystemType())->getDefaultMode());
421
                }
422
            }
423
        }
424
425
        // consume spare parts
426
        $this->repairUtil->consumeSpareParts($neededParts, $station);
427
428
        if (!$wrapper->canBeRepaired()) {
429
            $station->setHuell($station->getMaxHull());
430
            $station->setState(ShipStateEnum::SHIP_STATE_NONE);
431
432
            $shipOwnerMessage = sprintf(
433
                "Die Reparatur der %s wurde in Sektor %s fertiggestellt",
434
                $station->getName(),
435
                $station->getSectorString()
436
            );
437
438
            $this->privateMessageSender->send(
439
                UserEnum::USER_NOONE,
440
                $station->getUser()->getId(),
441
                $shipOwnerMessage,
442
                PrivateMessageFolderTypeEnum::SPECIAL_STATION
443
            );
444
        }
445
        $this->shipRepository->save($station);
446
    }
447
448
    private function checkForFinishedTakeover(ShipInterface $ship): void
449
    {
450
        $startTime = microtime(true);
451
        $takeover = $ship->getTakeoverActive();
452
        if ($takeover === null) {
453
            return;
454
        }
455
        $this->potentialLog($ship, "marker10.1", $startTime);
0 ignored issues
show
Bug introduced by
It seems like $startTime can also be of type string; however, parameter $startTime of Stu\Module\Tick\Ship\ShipTick::potentialLog() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

455
        $this->potentialLog($ship, "marker10.1", /** @scrutinizer ignore-type */ $startTime);
Loading history...
456
457
        $startTime = microtime(true);
458
        $isTakeoverReady = $this->shipTakeoverManager->isTakeoverReady($takeover);
459
        $this->potentialLog($ship, "marker10.2", $startTime);
460
461
        if ($isTakeoverReady) {
462
            $startTime = microtime(true);
463
            $this->shipTakeoverManager->finishTakeover($takeover);
464
            $this->potentialLog($ship, "marker10.3", $startTime);
465
        }
466
    }
467
468
    private function checkForFinishedAstroMapping(ShipWrapperInterface $wrapper): void
469
    {
470
        $ship = $wrapper->get();
471
472
        /** @var null|DatabaseEntryInterface $databaseEntry */
473
        [$message, $databaseEntry] = $this->getDatabaseEntryForShipLocation($ship);
474
475
        $astroLab = $wrapper->getAstroLaboratorySystemData();
476
477
        if (
478
            $ship->getState() === ShipStateEnum::SHIP_STATE_ASTRO_FINALIZING
479
            && $databaseEntry !== null
480
            && $astroLab !== null
481
            && $this->game->getCurrentRound()->getTurn() >= ($astroLab->getAstroStartTurn() + AstronomicalMappingEnum::TURNS_TO_FINISH)
482
        ) {
483
            $this->astroEntryLib->finish($wrapper);
484
485
            $this->msg[] = sprintf(
486
                _('Die Kartographierung %s wurde vollendet'),
487
                $message
488
            );
489
490
            $userId = $ship->getUser()->getId();
491
            $databaseEntryId = $databaseEntry->getId();
492
493
            if (!$this->databaseUserRepository->exists($userId, $databaseEntryId)) {
494
                $entry = $this->createDatabaseEntry->createDatabaseEntryForUser($ship->getUser(), $databaseEntryId);
495
496
                if ($entry !== null) {
497
                    $this->msg[] = sprintf(
498
                        _('Neuer Datenbankeintrag: %s (+%d Punkte)'),
499
                        $entry->getDescription(),
500
                        $entry->getCategory()->getPoints()
501
                    );
502
                }
503
            }
504
        }
505
    }
506
507
    /**
508
     * @return array{0: string|null, 1: DatabaseEntryInterface|null}
509
     */
510
    private function getDatabaseEntryForShipLocation(ShipInterface $ship): array
511
    {
512
        $system = $ship->getSystem();
513
        if ($system !== null) {
514
            return [
515
                'des Systems ' . $system->getName(),
516
                $system->getDatabaseEntry()
517
            ];
518
        }
519
520
        $mapRegion = $ship->getMapRegion();
521
        if ($mapRegion !== null) {
522
            return [
523
                'der Region ' . $mapRegion->getDescription(),
524
                $mapRegion->getDatabaseEntry()
525
            ];
526
        }
527
528
        return [null, null];
529
    }
530
531
    private function doTrackerDeviceStuff(ShipWrapperInterface $wrapper): void
532
    {
533
        $ship = $wrapper->get();
534
        $tracker = $wrapper->getTrackerSystemData();
535
536
        if ($tracker === null || $tracker->targetId === null) {
537
            return;
538
        }
539
540
        $targetWrapper = $tracker->getTargetWrapper();
541
        if ($targetWrapper === null) {
542
            throw new RuntimeException('should not happen');
543
        }
544
545
        $target = $targetWrapper->get();
546
        $shipLocation = $ship->getLocation();
547
        $targetLocation = $target->getLocation();
548
        $remainingTicks = $tracker->getRemainingTicks();
549
550
        $reduceByTicks = max(1, (int)ceil((abs($shipLocation->getCx() - $targetLocation->getCx())
551
            +  abs($shipLocation->getCy() - $targetLocation->getCy())) / 50));
552
553
        //reduce remaining ticks
554
        if ($remainingTicks > $reduceByTicks) {
555
            $tracker->setRemainingTicks($remainingTicks - $reduceByTicks)->update();
556
        } else {
557
            $this->trackerDeviceManager->deactivateTrackerIfActive($wrapper, true);
558
        }
559
    }
560
561
    private function sendMessages(ShipInterface $ship): void
562
    {
563
        if ($this->msg === []) {
564
            return;
565
        }
566
        $text = "Tickreport der " . $ship->getName() . "\n";
567
        foreach ($this->msg as $msg) {
568
            $text .= $msg . "\n";
569
        }
570
571
        $href = sprintf('ship.php?%s=1&id=%d', ShowShip::VIEW_IDENTIFIER, $ship->getId());
572
573
        $this->privateMessageSender->send(
574
            UserEnum::USER_NOONE,
575
            $ship->getUser()->getId(),
576
            $text,
577
            $ship->isBase() ? PrivateMessageFolderTypeEnum::SPECIAL_STATION : PrivateMessageFolderTypeEnum::SPECIAL_SHIP,
578
            $href
579
        );
580
581
        $this->msg = [];
582
    }
583
}
584