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

TickManager::shipRepairEvents()   B

Complexity

Conditions 10
Paths 15

Size

Total Lines 48
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
cc 10
eloc 26
nc 15
nop 1
dl 0
loc 48
ccs 0
cts 27
cp 0
crap 110
rs 7.6666
c 0
b 0
f 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 Stu\Module\Tick;
4
5
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...
6
use RuntimeException;
7
use Stu\Component\Building\BuildingEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Building\BuildingEnum 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...
8
use Stu\Component\Colony\ColonyFunctionManagerInterface;
9
use Stu\Component\Event\EventManagerInterface;
10
use Stu\Component\Event\EventTypeEnum;
11
use Stu\Component\Event\Payload\PayloadWithIdAndTurn;
12
use Stu\Component\Event\Payload\PayloadWithTurn;
13
use Stu\Component\Game\TimeConstants;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Game\TimeConstants 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...
14
use Stu\Module\Logging\LoggerUtilFactoryInterface;
15
use Stu\Module\Logging\LoggerUtilInterface;
16
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...
17
use Stu\Orm\Entity\GameTurnInterface;
18
use Stu\Orm\Entity\UserInterface;
19
use Stu\Orm\Repository\AnomalyRepositoryInterface;
20
use Stu\Orm\Repository\ColonyShipRepairRepositoryInterface;
21
use Stu\Orm\Repository\GameTurnRepositoryInterface;
22
use Stu\Orm\Repository\GameTurnStatsRepositoryInterface;
23
use Stu\Orm\Repository\KnPostRepositoryInterface;
24
use Stu\Orm\Repository\PlanetFieldRepositoryInterface;
25
use Stu\Orm\Repository\UserLockRepositoryInterface;
26
use Stu\Orm\Repository\UserRepositoryInterface;
27
28
final class TickManager implements TickManagerInterface
29
{
30
    private LoggerUtilInterface $loggerUtil;
31
32
    public function __construct(
33
        private GameTurnRepositoryInterface $gameTurnRepository,
34
        private UserLockRepositoryInterface $userLockRepository,
35
        private GameTurnStatsRepositoryInterface $gameTurnStatsRepository,
36
        private UserRepositoryInterface $userRepository,
37
        private KnPostRepositoryInterface $knPostRepository,
38
        private AnomalyRepositoryInterface $anomalyRepository,
39
        private ColonyShipRepairRepositoryInterface $colonyShipRepairRepository,
40
        private PlanetFieldRepositoryInterface $planetFieldRepository,
41
        private ColonyFunctionManagerInterface $colonyFunctionManager,
42
        private EventManagerInterface $eventManager,
43
        LoggerUtilFactoryInterface $loggerUtilFactory
44
    ) {
45
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil();
46
    }
47
48
    #[Override]
49
    public function work(): void
50
    {
51
        $turn = $this->gameTurnRepository->getCurrent();
52
        if ($turn === null) {
53
            throw new RuntimeException('no current turn exists');
54
        }
55
56
        $this->endTurn($turn);
57
        $newTurnNumber = $turn->getTurn() + 1;
58
59
        $this->createAnomalyProcessingEvents($newTurnNumber);
60
        $this->shipRepairEvents($newTurnNumber);
61
        $this->createUserTickEvents($newTurnNumber);
62
        $this->createAnomalyCreationEvent($newTurnNumber);
63
64
        $this->reduceUserLocks();
65
66
        $newTurn = $this->startTurn($newTurnNumber);
67
        $this->createGameTurnStats($newTurn);
68
    }
69
70
    private function endTurn(GameTurnInterface $turn): void
71
    {
72
        $turn->setEnd(time());
73
74
        $this->gameTurnRepository->save($turn);
75
    }
76
77
    private function startTurn(int $newTurnNumber): GameTurnInterface
78
    {
79
        $obj = $this->gameTurnRepository->prototype();
80
        $obj->setStart(time());
81
        $obj->setEnd(0);
82
        $obj->setTurn($newTurnNumber);
83
84
        $this->gameTurnRepository->save($obj);
85
86
        return $obj;
87
    }
88
89
    private function createAnomalyProcessingEvents(int $newTurnNumber): void
90
    {
91
        foreach ($this->anomalyRepository->findAllActive() as $anomaly) {
92
93
            $this->eventManager->createEvent(
94
                EventTypeEnum::ANOMALY_PROCESSING,
95
                new PayloadWithIdAndTurn($anomaly->getId(), $newTurnNumber)
96
            );
97
        }
98
    }
99
100
    private function shipRepairEvents(int $newTurnNumber): void
101
    {
102
        $usedShipyards = [];
103
104
        foreach ($this->colonyShipRepairRepository->getMostRecentJobs() as $colonyShipRepair) {
105
106
            $colony = $colonyShipRepair->getColony();
107
            if ($colony->getUser()->isVacationRequestOldEnough()) {
108
                continue;
109
            }
110
111
            if ($colony->isBlocked()) {
112
                continue;
113
            }
114
115
            if (!array_key_exists($colony->getId(), $usedShipyards)) {
116
                $usedShipyards[$colony->getId()] = [];
117
            }
118
119
            $field = $this->planetFieldRepository->getByColonyAndFieldIndex(
120
                $colonyShipRepair->getColonyId(),
121
                $colonyShipRepair->getFieldId()
122
            );
123
124
            if ($field === null) {
125
                continue;
126
            }
127
            if (!$field->isActive()) {
128
                continue;
129
            }
130
131
            if (!array_key_exists($colony->getId(), $usedShipyards)) {
132
                $usedShipyards[$colony->getId()] = [];
133
            }
134
135
            //already repaired a ship on this colony field, max is one without repair station
136
            if (
137
                in_array($field->getFieldId(), $usedShipyards[$colony->getId()])
138
                && !$this->colonyFunctionManager->hasActiveFunction($colony, BuildingEnum::BUILDING_FUNCTION_REPAIR_SHIPYARD)
139
            ) {
140
                continue;
141
            }
142
143
            $usedShipyards[$colony->getId()][] = $field->getFieldId();
144
145
            $this->eventManager->createEvent(
146
                EventTypeEnum::COLONY_SHIP_REPAIR,
147
                new PayloadWithIdAndTurn($colonyShipRepair->getId(), $newTurnNumber)
148
            );
149
        }
150
    }
151
152
    private function createUserTickEvents(int $newTurnNumber): void
153
    {
154
        foreach ($this->userRepository->findAll() as $user) {
155
            if ($user->isVacationRequestOldEnough()) {
156
                continue;
157
            }
158
159
            $this->eventManager->createEvent(
160
                $this->getEventType($user),
161
                new PayloadWithIdAndTurn($user->getId(), $newTurnNumber)
162
            );
163
        }
164
    }
165
166
    private function createAnomalyCreationEvent(int $newTurnNumber): void
167
    {
168
        $this->eventManager->createEvent(
169
            EventTypeEnum::ANOMALY_CREATION,
170
            new PayloadWithTurn($newTurnNumber)
171
        );
172
    }
173
174
    private function getEventType(UserInterface $user): EventTypeEnum
175
    {
176
        if ($user->getId() === UserEnum::USER_NOONE) {
177
            return EventTypeEnum::NOONE_TICK;
178
        }
179
180
        return $user->isNpc()
181
            ? EventTypeEnum::NPC_TICK
182
            : EventTypeEnum::USER_TICK;
183
    }
184
185
    private function reduceUserLocks(): void
186
    {
187
        $locks = $this->userLockRepository->getActive();
188
189
        foreach ($locks as $lock) {
190
            $remainingTicks = $lock->getRemainingTicks();
191
192
            if ($remainingTicks === 1) {
193
                $userId = $lock->getUser()->getId();
194
195
                $lock->setUser(null);
196
                $lock->setUserId(null);
197
                $lock->setFormerUserId($userId);
198
                $lock->setRemainingTicks(0);
199
            } else {
200
                $lock->setRemainingTicks($remainingTicks - 1);
201
            }
202
203
            $this->userLockRepository->save($lock);
204
        }
205
    }
206
207
    private function createGameTurnStats(GameTurnInterface $turn): void
208
    {
209
        $stats = $this->gameTurnStatsRepository->prototype();
210
211
        $this->loggerUtil->log('setting stats values');
212
213
        $stats->setTurn($turn);
214
        $stats->setUserCount($this->userRepository->getActiveAmount());
215
        $stats->setLogins24h($this->userRepository->getActiveAmountRecentlyOnline(time() - TimeConstants::ONE_DAY_IN_SECONDS));
216
        $stats->setInactiveCount($this->userRepository->getInactiveAmount(14));
217
        $stats->setVacationCount($this->userRepository->getVacationAmount());
218
        $stats->setShipCount($this->gameTurnStatsRepository->getShipCount());
219
        $stats->setShipCountManned($this->gameTurnStatsRepository->getShipCountManned());
220
        $stats->setShipCountNpc($this->gameTurnStatsRepository->getShipCountNpc());
221
        $stats->setKnCount($this->knPostRepository->getAmount());
222
        $stats->setFlightSig24h($this->gameTurnStatsRepository->getFlightSigs24h());
223
        $stats->setFlightSigSystem24h($this->gameTurnStatsRepository->getFlightSigsSystem24h());
224
225
        $this->gameTurnStatsRepository->save($stats);
226
        $this->loggerUtil->log('saved stats');
227
    }
228
}
229