Passed
Push — dev ( eeaa0f...91a85a )
by Janko
26:10
created

CrewLimitations::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 10
dl 0
loc 12
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Module\Tick\Ship\ManagerComponent;
6
7
use InvalidArgumentException;
8
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Stu\Component\Event\EventManagerInterface;
10
use Stu\Component\Event\EventQueueInterface;
11
use Stu\Component\Event\EventTypeEnum;
12
use Stu\Component\Event\Payload\PayloadWithId;
13
use Stu\Component\Player\CrewLimitCalculatorInterface;
14
use Stu\Component\Ship\System\ShipSystemManagerInterface;
15
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
16
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
17
use Stu\Module\PlayerSetting\Lib\UserEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Stu\Module\Ship\Lib\ShipWrapperFactoryInterface;
19
use Stu\Module\Tick\User\UserTickComponentInterface;
20
use Stu\Orm\Entity\UserInterface;
21
use Stu\Orm\Repository\CrewRepositoryInterface;
22
use Stu\Orm\Repository\ShipCrewRepositoryInterface;
23
use Stu\Orm\Repository\ShipRepositoryInterface;
24
use Stu\Orm\Repository\UserRepositoryInterface;
25
26
final class CrewLimitations implements ManagerComponentInterface, UserTickComponentInterface
27
{
28
    public function __construct(
29
        private PrivateMessageSenderInterface $privateMessageSender,
30
        private ShipRepositoryInterface $shipRepository,
31
        private UserRepositoryInterface $userRepository,
32
        private CrewRepositoryInterface $crewRepository,
33
        private ShipCrewRepositoryInterface $shipCrewRepository,
34
        private ShipSystemManagerInterface $shipSystemManager,
35
        private ShipWrapperFactoryInterface $shipWrapperFactory,
36
        private CrewLimitCalculatorInterface $crewLimitCalculator,
37
        private EventManagerInterface $eventManager,
38
        private EventQueueInterface $eventQueue
39
    ) {
40
    }
41
42
    #[Override]
43
    public function processUser(UserInterface $user): void
44
    {
45
        $userId = $user->getId();
46
47
        $crewLimit = $this->crewLimitCalculator->getGlobalCrewLimit($user);
48
        $crewOnColonies = $this->shipCrewRepository->getAmountByUserOnColonies($user->getId());
49
        $crewOnShips = $this->shipCrewRepository->getAmountByUserOnShips($user);
50
        $crewAtTradeposts = $this->shipCrewRepository->getAmountByUserAtTradeposts($user);
51
52
        $crewToQuit = max(0, $crewOnColonies + $crewOnShips + $crewAtTradeposts - $crewLimit);
53
54
        //mutiny order: colonies, ships, tradeposts, escape pods
55
        if ($crewToQuit > 0 && $crewOnColonies > 0) {
56
            $crewToQuit -= $this->letColonyAssignmentsQuit($userId, $crewToQuit);
57
        }
58
        if ($crewToQuit > 0 && $crewOnShips > 0) {
59
            $crewToQuit -= $this->letShipAssignmentsQuit($userId, $crewToQuit);
60
        }
61
        if ($crewToQuit > 0 && $crewAtTradeposts > 0) {
62
            $crewToQuit -= $this->letTradepostAssignmentsQuit($userId, $crewToQuit);
63
        }
64
        if ($crewToQuit > 0) {
65
            $this->letEscapePodAssignmentsQuit($userId, $crewToQuit);
66
        }
67
    }
68
69
    #[Override]
70
    public function work(): void
71
    {
72
        $userList = $this->userRepository->getNonNpcList();
73
74
        foreach ($userList as $user) {
75
            //only handle user that are not on vacation
76
            if ($user->isVacationRequestOldEnough()) {
77
                return;
78
            }
79
80
            $this->processUser($user);
81
        }
82
    }
83
84
    private function letColonyAssignmentsQuit(int $userId, int $crewToQuit): int
85
    {
86
        $amount = 0;
87
88
        foreach ($this->shipCrewRepository->getByUserAtColonies($userId) as $crewAssignment) {
89
            if ($amount === $crewToQuit) {
90
                break;
91
            }
92
93
            $amount++;
94
            $this->crewRepository->delete($crewAssignment->getCrew());
95
        }
96
97
        if ($amount > 0) {
98
            $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits haben %d Crewman ihren Dienst auf deinen Kolonien quittiert'), $amount);
99
            $this->privateMessageSender->send(
100
                UserEnum::USER_NOONE,
101
                $userId,
102
                $msg,
103
                PrivateMessageFolderTypeEnum::SPECIAL_COLONY
104
            );
105
        }
106
107
        return $amount;
108
    }
109
110
    private function letTradepostAssignmentsQuit(int $userId, int $crewToQuit): int
111
    {
112
        $amount = 0;
113
114
        foreach ($this->shipCrewRepository->getByUserAtTradeposts($userId) as $crewAssignment) {
115
            if ($amount === $crewToQuit) {
116
                break;
117
            }
118
119
            $amount++;
120
            $this->crewRepository->delete($crewAssignment->getCrew());
121
        }
122
123
        if ($amount > 0) {
124
            $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits haben %d deiner Crewman auf Handelsposten ihren Dienst quittiert'), $amount);
125
            $this->privateMessageSender->send(
126
                UserEnum::USER_NOONE,
127
                $userId,
128
                $msg,
129
                PrivateMessageFolderTypeEnum::SPECIAL_SYSTEM
130
            );
131
        }
132
133
        return $amount;
134
    }
135
136
    private function letEscapePodAssignmentsQuit(int $userId, int $crewToQuit): int
137
    {
138
        $amount = 0;
139
140
        foreach ($this->shipCrewRepository->getByUserOnEscapePods($userId) as $crewAssignment) {
141
            if ($amount === $crewToQuit) {
142
                break;
143
            }
144
145
            $amount++;
146
            $this->crewRepository->delete($crewAssignment->getCrew());
147
        }
148
149
        if ($amount > 0) {
150
            $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits haben %d deiner Crewman auf Fluchtkapseln ihren Dienst quittiert'), $amount);
151
            $this->privateMessageSender->send(
152
                UserEnum::USER_NOONE,
153
                $userId,
154
                $msg,
155
                PrivateMessageFolderTypeEnum::SPECIAL_SYSTEM
156
            );
157
        }
158
159
        return $amount;
160
    }
161
162
    private function letShipAssignmentsQuit(int $userId, int $crewToQuit): int
163
    {
164
        $wipedShipsIds = [];
165
        $amount = 0;
166
167
        $wipedShipIds = [];
168
169
        while ($amount < $crewToQuit) {
170
            $randomShipId = $this->shipRepository->getRandomShipIdWithCrewByUser($userId);
171
172
            //if no more ships available
173
            if ($randomShipId === null) {
174
                break;
175
            }
176
177
            //if ship already wiped, go to next
178
            if (in_array($randomShipId, $wipedShipIds)) {
179
                continue;
180
            }
181
182
            //wipe ship crew
183
            $wipedShipsIds[] = $randomShipId;
184
            $amount += $this->letCrewQuit($randomShipId, $userId);
185
        }
186
187
        return $amount;
188
    }
189
190
    private function letCrewQuit(int $randomShipId, int $userId): int
191
    {
192
        $randomShip = $this->shipRepository->find($randomShipId);
193
194
        if ($randomShip === null) {
195
            throw new InvalidArgumentException('randomShipId should exist');
196
        }
197
198
        $wrapper = $this->shipWrapperFactory->wrapShip($randomShip);
199
        $doAlertRedCheck = $randomShip->getWarpDriveState() || $randomShip->getCloakState();
200
        //deactivate ship
201
        $this->shipSystemManager->deactivateAll($wrapper);
202
        $randomShip->setAlertStateGreen();
203
204
        $this->shipRepository->save($randomShip);
205
206
        $crewArray = [];
207
        foreach ($randomShip->getCrewAssignments() as $shipCrew) {
208
            $crewArray[] = $shipCrew->getCrew();
209
        }
210
        $randomShip->getCrewAssignments()->clear();
211
212
        //remove crew
213
        $this->shipCrewRepository->truncateByShip($randomShipId);
214
        foreach ($crewArray as $crew) {
215
            $this->crewRepository->delete($crew);
216
        }
217
218
        $msg = sprintf(_('Wegen Überschreitung des globalen Crewlimits hat die Crew der %s gemeutert und das Schiff verlassen'), $randomShip->getName());
219
        $this->privateMessageSender->send(
220
            UserEnum::USER_NOONE,
221
            $userId,
222
            $msg,
223
            $randomShip->isBase() ? PrivateMessageFolderTypeEnum::SPECIAL_STATION : PrivateMessageFolderTypeEnum::SPECIAL_SHIP
224
        );
225
226
        //do alert red stuff
227
        if ($doAlertRedCheck) {
228
            $event = $this->eventManager->createEvent(
229
                EventTypeEnum::ALERT_REACTION,
230
                new PayloadWithId($randomShip->getId())
231
            );
232
            $this->eventQueue->addEvent($event);
233
        }
234
235
        return count($crewArray);
236
    }
237
}
238