Passed
Push — dev ( 80c162...225d4f )
by Janko
09:12
created

TholianWebUtil::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 8
dl 0
loc 11
ccs 2
cts 2
cp 1
crap 1
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\Ship\Lib;
6
7
use Doctrine\ORM\EntityManagerInterface;
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 RuntimeException;
10
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...
11
use Stu\Component\Spacecraft\SpacecraftStateEnum;
12
use Stu\Component\Spacecraft\System\Data\WebEmitterSystemData;
13
use Stu\Component\Spacecraft\System\SpacecraftSystemTypeEnum;
14
use Stu\Module\Control\StuTime;
15
use Stu\Module\Logging\LoggerUtilFactoryInterface;
16
use Stu\Module\Logging\LoggerUtilInterface;
17
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
18
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
19
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...
20
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperFactoryInterface;
21
use Stu\Module\Ship\Lib\ShipWrapperInterface;
22
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
23
use Stu\Orm\Entity\SpacecraftInterface;
24
use Stu\Orm\Entity\SpacecraftSystemInterface;
25
use Stu\Orm\Entity\TholianWebInterface;
26
use Stu\Orm\Repository\ShipRepositoryInterface;
27
use Stu\Orm\Repository\SpacecraftRepositoryInterface;
28
use Stu\Orm\Repository\SpacecraftSystemRepositoryInterface;
29
use Stu\Orm\Repository\TholianWebRepositoryInterface;
30
31
final class TholianWebUtil implements TholianWebUtilInterface
32
{
33
    private LoggerUtilInterface $loggerUtil;
34
35 2
    public function __construct(
36
        private SpacecraftRepositoryInterface $spacecraftRepository,
37
        private ShipRepositoryInterface $shipRepository,
38
        private TholianWebRepositoryInterface $tholianWebRepository,
39
        private SpacecraftSystemRepositoryInterface $shipSystemRepository,
40
        private StuTime $stuTime,
41
        private PrivateMessageSenderInterface $privateMessageSender,
42
        LoggerUtilFactoryInterface $loggerUtilFactory,
43
        private EntityManagerInterface $entityManager
44
    ) {
45 2
        $this->loggerUtil = $loggerUtilFactory->getLoggerUtil();
46
    }
47
48
    #[Override]
49
    public function releaseSpacecraftFromWeb(SpacecraftWrapperInterface $wrapper): void
50
    {
51
        $this->loggerUtil->log(sprintf('releaseSpacecraftFromWeb, shipId: %d', $wrapper->get()->getId()));
52
53
        $spacecraft = $wrapper->get();
54
        $web = $spacecraft->getHoldingWeb();
55
        if ($web === null) {
56
            return;
57
        }
58
59
        $web->getCapturedSpacecrafts()->removeElement($spacecraft);
60
61
        if ($web->getCapturedSpacecrafts()->isEmpty()) {
62
            $this->resetWebHelpers($web, $wrapper->getSpacecraftWrapperFactory());
63
            $this->removeWeb($web);
64
        }
65
66
        $spacecraft->setHoldingWeb(null);
67
        $this->spacecraftRepository->save($spacecraft);
68
    }
69
70
    #[Override]
71
    public function releaseAllShips(TholianWebInterface $web, SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory): void
72
    {
73
        foreach ($web->getCapturedSpacecrafts() as $target) {
74
            $this->releaseSpacecraftFromWeb($spacecraftWrapperFactory->wrapSpacecraft($target));
75
76
            //notify target owner
77
            $this->privateMessageSender->send(
78
                $web->getUser()->getId(),
79
                $target->getUser()->getId(),
80
                sprintf(
81
                    'Das Energienetz um die %s in Sektor %s wurde aufgelöst',
82
                    $target->getName(),
83
                    $target->getSectorString()
84
                ),
85
                $target->getType()->getMessageFolderType()
86
            );
87
        }
88
    }
89
90
    #[Override]
91
    public function removeWeb(TholianWebInterface $web): void
92
    {
93
        $this->loggerUtil->log(sprintf('removeWeb, webId: %d', $web->getId()));
94
95
        $this->tholianWebRepository->delete($web);
96
    }
97
98
    #[Override]
99
    public function releaseWebHelper(ShipWrapperInterface $wrapper): void
100
    {
101
        $this->loggerUtil->log(sprintf('releaseWebHelper, shipId: %d', $wrapper->get()->getId()));
102
103
        $emitter = $this->getMandatoryEmitter($wrapper);
104
        $web = $this->getMandatoryWebUnderConstruction($emitter);
105
106
        $finishedTime = $this->releaseWebHelperIntern($wrapper);
107
        if ($finishedTime === null) {
108
            throw new RuntimeException('this should not happen');
109
        }
110
111
        $currentSpinnerSystems = $this->shipSystemRepository->getWebConstructingShipSystems($web->getId());
112
113
        //remove web if lost
114
        if ($currentSpinnerSystems === []) {
115
            $this->releaseAllShips($web, $wrapper->getSpacecraftWrapperFactory());
116
            $this->removeWeb($web);
117
        } else {
118
            $ship = $wrapper->get();
119
120
            //notify other web spinners
121
            foreach ($currentSpinnerSystems as $shipSystem) {
122
                $this->privateMessageSender->send(
123
                    $ship->getUser()->getId(),
124
                    $shipSystem->getSpacecraft()->getUser()->getId(),
125
                    sprintf(
126
                        'Die %s hat den Netzaufbau in Sektor %s verlassen, Fertigstellung: %s',
127
                        $ship->getName(),
128
                        $ship->getSectorString(),
129
                        $this->stuTime->transformToStuDateTime($finishedTime)
130
                    ),
131
                    PrivateMessageFolderTypeEnum::SPECIAL_SHIP
132
                );
133
            }
134
        }
135
    }
136
137
    #[Override]
138
    public function resetWebHelpers(
139
        TholianWebInterface $web,
140
        SpacecraftWrapperFactoryInterface $spacecraftWrapperFactory,
141
        bool $isFinished = false
142
    ): void {
143
        $this->loggerUtil->log(sprintf('resetWebHelpers, webId: %d', $web->getId()));
144
145
        $systems = $this->shipSystemRepository->getWebConstructingShipSystems($web->getId());
146
        foreach ($systems as $system) {
147
            /** @var ShipWrapperInterface */
148
            $wrapper = $spacecraftWrapperFactory->wrapSpacecraft($system->getSpacecraft());
149
            $this->releaseWebHelperIntern($wrapper);
150
151
            //notify helpers when finished
152
            if ($isFinished) {
153
                $ship = $system->getSpacecraft();
154
155
                $this->privateMessageSender->send(
156
                    UserEnum::USER_NOONE,
157
                    $ship->getUser()->getId(),
158
                    sprintf(
159
                        'Das Energienetz in Sektor %s wurde fertiggestellt',
160
                        $ship->getSectorString()
161
                    ),
162
                    PrivateMessageFolderTypeEnum::SPECIAL_SHIP
163
                );
164
            }
165
        }
166
    }
167
168
    private function releaseWebHelperIntern(ShipWrapperInterface $wrapper): ?int
169
    {
170
        $emitter = $this->getMandatoryEmitter($wrapper);
171
        $web = $this->getMandatoryWebUnderConstruction($emitter);
172
173
        if ($emitter->ownedWebId === $emitter->webUnderConstructionId && !$web->isFinished()) {
174
            $emitter->setOwnedWebId(null);
175
        }
176
        $emitter->setWebUnderConstructionId(null)->update();
177
        $wrapper->getSpacecraftSystemManager()->deactivate($wrapper, SpacecraftSystemTypeEnum::THOLIAN_WEB, true);
178
179
        $ship = $wrapper->get();
180
        $ship->setState(SpacecraftStateEnum::SHIP_STATE_NONE);
181
        $this->shipRepository->save($ship);
182
183
        //update finish time last
184
        return $this->updateWebFinishTime($web, -1);
185
    }
186
187
    #[Override]
188
    public function updateWebFinishTime(TholianWebInterface $web, ?int $helperModifier = null): ?int
189
    {
190
        $this->loggerUtil->log(sprintf('updateWebFinishTime, webId: %d', $web->getId()));
191
192
        //flush to read persistent webIds from system data
193
        $this->entityManager->flush();
194
195
        if ($web->isFinished()) {
196
            return null;
197
        }
198
199
        $currentSpinnerSystems = $this->shipSystemRepository->getWebConstructingShipSystems($web->getId());
200
        $time = $this->stuTime->time();
201
202
        //adjust by modified web spinner count
203
        if ($helperModifier !== null) {
204
            $secondsLeft = $web->getFinishedTime() - $time;
205
            $currentSpinnerCount = count($currentSpinnerSystems);
206
            $oldSpinnerCount =  $currentSpinnerCount - $helperModifier;
207
208
            if ($currentSpinnerCount !== 0) {
209
                $web->setFinishedTime($time + (int)ceil($secondsLeft * $oldSpinnerCount / $currentSpinnerCount));
210
            }
211
            $this->tholianWebRepository->save($web);
212
213
            return $web->getFinishedTime();
214
        }
215
216
        //initialize by weight of targets and spinners
217
        $targetWeightSum = array_reduce(
218
            $web->getCapturedSpacecrafts()->toArray(),
219
            fn(int $sum, SpacecraftInterface $spacecraft): int => $sum + $spacecraft->getRump()->getTractorMass(),
220
            0
221
        );
222
        $webSpinnerWeightSum = array_reduce(
223
            $this->shipSystemRepository->getWebConstructingShipSystems($web->getId()),
224
            fn(int $sum, SpacecraftSystemInterface $shipSystem): int => $sum + $shipSystem->getSpacecraft()->getRump()->getTractorMass(),
225
            0
226
        );
227
228
        $this->loggerUtil->log(sprintf('targetWeightSum: %d, webSpinnerWeightSum: %d', $targetWeightSum, $webSpinnerWeightSum));
229
230
        //only update if web spinners left
231
        if ($webSpinnerWeightSum !== 0) {
232
            $web->setFinishedTime($time + ((int)ceil($targetWeightSum / $webSpinnerWeightSum)) * TimeConstants::ONE_HOUR_IN_SECONDS);
233
            $this->tholianWebRepository->save($web);
234
        }
235
236
        return $web->getFinishedTime();
237
    }
238
239
    private function getMandatoryEmitter(ShipWrapperInterface $wrapper): WebEmitterSystemData
240
    {
241
        $emitter = $wrapper->getWebEmitterSystemData();
242
        if ($emitter === null) {
243
            throw new RuntimeException('no emitter');
244
        }
245
246
        return $emitter;
247
    }
248
    private function getMandatoryWebUnderConstruction(WebEmitterSystemData $emitter): TholianWebInterface
249
    {
250
        $web = $emitter->getWebUnderConstruction();
251
        if ($web === null) {
252
            throw new RuntimeException('no web under construction');
253
        }
254
255
        return $web;
256
    }
257
}
258