Passed
Push — dev ( 01bde1...cb99d0 )
by Nico
06:37
created

ColonyRepository::getPirateTargets()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 63
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
eloc 55
c 1
b 1
f 0
nc 2
nop 1
dl 0
loc 63
ccs 0
cts 35
cp 0
crap 6
rs 8.9818

How to fix   Long Method   

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
declare(strict_types=1);
4
5
namespace Stu\Orm\Repository;
6
7
use Doctrine\ORM\EntityRepository;
8
use Doctrine\ORM\Query\ResultSetMapping;
9
use Doctrine\ORM\NoResultException;
10
use Stu\Component\Colony\ColonyTypeEnum;
11
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...
12
use Stu\Module\Commodity\CommodityTypeConstants;
0 ignored issues
show
Bug introduced by
The type Stu\Module\Commodity\CommodityTypeConstants 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...
13
use Stu\Module\PlayerSetting\Lib\UserConstants;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserConstants 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\PlayerSetting\Lib\UserStateEnum;
15
use Stu\Module\Spacecraft\Lib\SpacecraftWrapperInterface;
16
use Stu\Orm\Entity\Colony;
17
use Stu\Orm\Entity\ColonyChangeable;
18
use Stu\Orm\Entity\ColonyClass;
19
use Stu\Orm\Entity\Layer;
20
use Stu\Orm\Entity\Location;
21
use Stu\Orm\Entity\Map;
22
use Stu\Orm\Entity\MapRegionSettlement;
23
use Stu\Orm\Entity\PirateWrath;
24
use Stu\Orm\Entity\StarSystem;
25
use Stu\Orm\Entity\StarSystemMap;
26
use Stu\Orm\Entity\Spacecraft;
27
use Stu\Orm\Entity\User;
28
use Stu\Orm\Entity\UserRegistration;
29
30
/**
31
 * @extends EntityRepository<Colony>
32
 */
33
final class ColonyRepository extends EntityRepository implements ColonyRepositoryInterface
34
{
35
    #[\Override]
36
    public function prototype(): Colony
37
    {
38
        $colony = new Colony();
39
        $changeable = new ColonyChangeable($colony);
40
        $colony->setChangeable($changeable);
41
42
        return $colony;
43
    }
44
45 10
    #[\Override]
46
    public function save(Colony $colony): void
47
    {
48 10
        $em = $this->getEntityManager();
49
50 10
        $em->persist($colony);
51
    }
52
53
    #[\Override]
54
    public function delete(Colony $colony): void
55
    {
56
        $em = $this->getEntityManager();
57
58
        $em->remove($colony);
59
        $em->flush(); //TODO really neccessary?
60
    }
61
62 4
    #[\Override]
63
    public function getAmountByUser(User $user, ColonyTypeEnum $colonyType): int
64
    {
65 4
        return (int) $this->getEntityManager()
66 4
            ->createQuery(
67 4
                sprintf(
68 4
                    'SELECT count(c.id) from %s c WHERE c.user_id = :userId AND c.colonyClass IN (
69
                        SELECT cc FROM %s cc WHERE cc.type = :type
70 4
                    )',
71 4
                    Colony::class,
72 4
                    ColonyClass::class
73 4
                )
74 4
            )
75 4
            ->setParameters([
76 4
                'userId' => $user,
77 4
                'type' => $colonyType->value
78 4
            ])
79 4
            ->getSingleScalarResult();
80
    }
81
82 1
    #[\Override]
83
    public function getStartingByFaction(int $factionId): array
84
    {
85 1
        return $this->getEntityManager()
86 1
            ->createQuery(
87 1
                sprintf(
88 1
                    'SELECT c FROM %s c INDEX BY c.id
89
                     JOIN %s sm
90
                     WITH c.starsystemMap = sm
91
                     WHERE c.user_id = :userId AND c.colonyClass IN (
92
                        SELECT cc FROM %s cc WHERE cc.allow_start = :allowStart
93
                    ) AND sm.systems_id IN (
94
                        SELECT m.systems_id FROM %s m WHERE m.systems_id > 0 AND m.admin_region_id IN (
95
                            SELECT mrs.region_id from %s mrs WHERE mrs.faction_id = :factionId
96
                        ) AND m.id IN (SELECT l.id FROM %s l WHERE l.layer IN (SELECT ly FROM %s ly WHERE ly.is_colonizable = :true))
97 1
                    )',
98 1
                    Colony::class,
99 1
                    StarSystemMap::class,
100 1
                    ColonyClass::class,
101 1
                    Map::class,
102 1
                    MapRegionSettlement::class,
103 1
                    Location::class,
104 1
                    Layer::class
105 1
                )
106 1
            )
107 1
            ->setParameters([
108 1
                'allowStart' => 1,
109 1
                'userId' => UserConstants::USER_NOONE,
110 1
                'factionId' => $factionId,
111 1
                'true' => true
112 1
            ])
113 1
            ->getResult();
114
    }
115
116
    #[\Override]
117
    public function getForeignColoniesInBroadcastRange(
118
        StarSystemMap $systemMap,
119
        User $user
120
    ): array {
121
        return $this->getEntityManager()
122
            ->createQuery(
123
                sprintf(
124
                    'SELECT c FROM %s c
125
                     JOIN %s sm
126
                     WITH c.starsystemMap = sm
127
                     WHERE c.user_id NOT IN (:ignoreIds)
128
                     AND sm.systems_id = :systemId
129
                     AND sm.sx BETWEEN (:sx - 1) AND (:sx + 1)
130
                     AND sm.sy BETWEEN (:sy - 1) AND (:sy + 1)',
131
                    Colony::class,
132
                    StarSystemMap::class
133
                )
134
            )
135
            ->setParameters([
136
                'ignoreIds' => [$user->getId(), UserConstants::USER_NOONE],
137
                'systemId' => $systemMap->getSystem()->getId(),
138
                'sx' => $systemMap->getSx(),
139
                'sy' => $systemMap->getSy()
140
            ])
141
            ->getResult();
142
    }
143
144 1
    #[\Override]
145
    public function getByBatchGroup(int $batchGroup, int $batchGroupCount): array
146
    {
147 1
        return $this->getEntityManager()
148 1
            ->createQuery(
149 1
                sprintf(
150 1
                    'SELECT c FROM %s c
151
                    WHERE MOD(c.user_id, :groupCount) + 1 = :groupId
152 1
                    AND c.user_id != :userId',
153 1
                    Colony::class
154 1
                )
155 1
            )
156 1
            ->setParameters([
157 1
                'groupId' => $batchGroup,
158 1
                'groupCount' => $batchGroupCount,
159 1
                'userId' => UserConstants::USER_NOONE
160 1
            ])
161 1
            ->getResult();
162
    }
163
164 1
    #[\Override]
165
    public function getColonized(): array
166
    {
167 1
        return $this->getEntityManager()
168 1
            ->createQuery(
169 1
                sprintf(
170 1
                    'SELECT c FROM %s c WHERE c.user_id != :userId',
171 1
                    Colony::class
172 1
                )
173 1
            )
174 1
            ->setParameters([
175 1
                'userId' => UserConstants::USER_NOONE,
176 1
            ])
177 1
            ->getResult();
178
    }
179
180 1
    #[\Override]
181
    public function getColoniesNetWorth(): array
182
    {
183 1
        $rsm = new ResultSetMapping();
184 1
        $rsm->addScalarResult('user_id', 'user_id', 'integer');
185 1
        $rsm->addScalarResult('commodity_id', 'commodity_id', 'integer');
186 1
        $rsm->addScalarResult('sum', 'sum', 'integer');
187
188 1
        return $this->getEntityManager()
189 1
            ->createNativeQuery(
190 1
                'SELECT u.id as user_id, bc.commodity_id AS commodity_id, SUM(bc.count) AS sum
191
                FROM stu_user u
192
                JOIN stu_colony c
193
                ON u.id = c.user_id 
194
                JOIN stu_colonies_fielddata cf
195
                ON cf.colonies_id = c.id
196
                JOIN stu_buildings_cost bc 
197
                ON cf.buildings_id = bc.buildings_id 
198
                WHERE u.id >= :firstUserId
199
                AND cf.buildings_id IS NOT NULL
200
                AND cf.aktiv = 1
201 1
                GROUP BY u.id, bc.commodity_id',
202 1
                $rsm
203 1
            )
204 1
            ->setParameters(['firstUserId' => UserConstants::USER_FIRST_ID])
205 1
            ->getResult();
206
    }
207
208 1
    #[\Override]
209
    public function getColoniesProductionNetWorth(): array
210
    {
211 1
        $rsm = new ResultSetMapping();
212 1
        $rsm->addScalarResult('user_id', 'user_id', 'integer');
213 1
        $rsm->addScalarResult('commodity_id', 'commodity_id', 'integer');
214 1
        $rsm->addScalarResult('sum', 'sum', 'integer');
215
216 1
        return $this->getEntityManager()
217 1
            ->createNativeQuery(
218 1
                'SELECT c.user_id, bc.commodity_id, SUM(bc.count) AS sum
219
                FROM stu_colony c
220
                JOIN stu_colonies_fielddata cf
221
                ON cf.colonies_id = c.id 
222
                JOIN stu_buildings_commodity bc
223
                ON cf.buildings_id = bc.buildings_id
224
                JOIN stu_commodity co
225
                ON bc.commodity_id = co.id
226
                WHERE co.type = :typeStandard
227
                AND co.name != \'Latinum\'
228
                AND bc.count > 0
229
                AND cf.aktiv = 1
230 1
                GROUP BY c.user_id, bc.commodity_id',
231 1
                $rsm
232 1
            )
233 1
            ->setParameters(['typeStandard' => CommodityTypeConstants::COMMODITY_TYPE_STANDARD])
234 1
            ->getResult();
235
    }
236
237
    #[\Override]
238
    public function getSatisfiedWorkerTop10(): array
239
    {
240
        $rsm = new ResultSetMapping();
241
        $rsm->addScalarResult('user_id', 'user_id', 'integer');
242
        $rsm->addScalarResult('satisfied', 'satisfied', 'integer');
243
244
        return $this->getEntityManager()
245
            ->createNativeQuery(
246
                'SELECT user_id, SUM(satisfied) AS satisfied
247
                FROM ( SELECT c.user_id,
248
                            LEAST( COALESCE(cc.bev_work, 0),
249
                            ( SELECT COALESCE(SUM(bc.count), 0)
250
                                FROM stu_colonies_fielddata cf
251
                                JOIN stu_buildings b
252
                                ON cf.buildings_id = b.id
253
                                JOIN stu_buildings_commodity bc
254
                                ON b.id = bc.buildings_id
255
                                WHERE cf.colonies_id = c.id
256
                                AND bc.commodity_id = :lifeStandard
257
                                AND cf.aktiv = 1
258
                            )) AS satisfied
259
                        FROM stu_colony c
260
                        JOIN stu_colony_changeable cc
261
                        ON c.id = cc.colony_id
262
                        WHERE c.user_id >= :firstUserId) AS colonies
263
                GROUP BY user_id
264
                ORDER BY 2 DESC
265
                LIMIT 10',
266
                $rsm
267
            )
268
            ->setParameters([
269
                'firstUserId' => UserConstants::USER_FIRST_ID,
270
                'lifeStandard' => CommodityTypeConstants::COMMODITY_EFFECT_LIFE_STANDARD
271
            ])
272
            ->getResult();
273
    }
274
275
    #[\Override]
276
    public function getPirateTargets(SpacecraftWrapperInterface $wrapper): array
277
    {
278
        $layer = $wrapper->get()->getLayer();
279
        if ($layer === null) {
280
            return [];
281
        }
282
283
        $location = $wrapper->get()->getLocation();
284
        $range = $wrapper->getLssSystemData()?->getSensorRange() ?? 0;
285
286
        return $this->getEntityManager()->createQuery(
287
            sprintf(
288
                'SELECT c FROM %s c
289
                JOIN %s sm
290
                WITH c.starsystemMap = sm
291
                JOIN %s s
292
                WITH sm.systems_id = s.id
293
                JOIN %s m
294
                WITH s.id = m.systems_id
295
                JOIN %s l
296
                WITH m.id = l.id
297
                JOIN %s ly
298
                WITH l.layer = ly
299
                JOIN %s u
300
                WITH c.user = u
301
                JOIN %s ur
302
                WITH ur.user = u
303
                LEFT JOIN %s w
304
                WITH u = w.user
305
                WHERE l.cx BETWEEN :minX AND :maxX
306
                AND l.cy BETWEEN :minY AND :maxY
307
                AND ly.id = :layerId
308
                AND u.id >= :firstUserId
309
                AND u.state >= :stateActive
310
                AND ur.creation < :fourMonthEarlier
311
                AND (u.vac_active = :false OR u.vac_request_date > :vacationThreshold)
312
                AND COALESCE(w.protection_timeout, 0) < :currentTime',
313
                Colony::class,
314
                StarSystemMap::class,
315
                StarSystem::class,
316
                Map::class,
317
                Location::class,
318
                Layer::class,
319
                User::class,
320
                UserRegistration::class,
321
                PirateWrath::class
322
            )
323
        )
324
            ->setParameters([
325
                'minX' => $location->getCx() - $range,
326
                'maxX' => $location->getCx() + $range,
327
                'minY' => $location->getCy() - $range,
328
                'maxY' => $location->getCy() + $range,
329
                'layerId' => $layer->getId(),
330
                'firstUserId' => UserConstants::USER_FIRST_ID,
331
                'stateActive' => UserStateEnum::ACTIVE->value,
332
                'fourMonthEarlier' => time() - TimeConstants::EIGHT_WEEKS_IN_SECONDS,
333
                'false' => false,
334
                'vacationThreshold' => time() - UserConstants::VACATION_DELAY_IN_SECONDS,
335
                'currentTime' => time()
336
            ])
337
            ->getResult();
338
    }
339
340
    #[\Override]
341
    public function getClosestColonizableColonyDistance(SpacecraftWrapperInterface $wrapper): ?int
342
    {
343
        $spacecraft = $wrapper->get();
344
        $location = $spacecraft->getLocation();
345
346
        if ($location instanceof StarSystemMap) {
347
            return $this->getClosestColonizableColonyInSystem($spacecraft);
348
        } else {
349
            return $this->getClosestSystemWithColonizableColonies($spacecraft);
350
        }
351
    }
352
353
    private function getClosestColonizableColonyInSystem(Spacecraft $spacecraft): ?int
354
    {
355
        $systemMap = $spacecraft->getStarsystemMap();
356
        if ($systemMap === null) {
357
            return null;
358
        }
359
360
        $currentColony = $systemMap->getColony();
361
        if (
362
            $currentColony !== null &&
363
            $currentColony->getUserId() === UserConstants::USER_NOONE &&
364
            $currentColony->getColonyClass()->getAllowStart()
365
        ) {
366
            return null;
367
        }
368
369
        try {
370
            $result = $this->getEntityManager()->createQuery(
371
                sprintf(
372
                    'SELECT MIN(ABS(sm.sx - :sx) + ABS(sm.sy - :sy)) as distance
373
                        FROM %s c
374
                        JOIN %s sm
375
                        WITH c.starsystemMap = sm
376
                        JOIN %s cc
377
                        WITH c.colonyClass = cc
378
                        WHERE c.user_id = :nooneUserId
379
                        AND cc.allow_start = :allowStart
380
                        AND sm.systems_id = :systemId
381
                        AND sm.id != :currentMapId',
382
                    Colony::class,
383
                    StarSystemMap::class,
384
                    ColonyClass::class
385
                )
386
            )
387
                ->setParameters([
388
                    'sx' => $systemMap->getSx(),
389
                    'sy' => $systemMap->getSy(),
390
                    'systemId' => $systemMap->getSystemId(),
391
                    'currentMapId' => $systemMap->getId(),
392
                    'nooneUserId' => UserConstants::USER_NOONE,
393
                    'allowStart' => true
394
                ])
395
                ->getSingleScalarResult();
396
397
            return $result > 0 ? (int)$result : null;
398
        } catch (NoResultException) {
399
            return null;
400
        }
401
    }
402
403
404
    private function getClosestSystemWithColonizableColonies(Spacecraft $spacecraft): ?int
405
    {
406
        $currentLocation = $spacecraft->getLocation();
407
        $currentX = $currentLocation->getCx();
408
        $currentY = $currentLocation->getCy();
409
        $currentLayer = $currentLocation->getLayer();
410
411
        if ($currentLayer === null) {
412
            return null;
413
        }
414
415
        $currentLayerId = $currentLayer->getId();
416
417
        try {
418
            $result = $this->getEntityManager()->createQuery(
419
                sprintf(
420
                    'SELECT MIN(ABS(l.cx - :currentX) + ABS(l.cy - :currentY)) as distance
421
                        FROM %s c
422
                        JOIN %s sm
423
                        WITH c.starsystemMap = sm
424
                        JOIN %s s
425
                        WITH sm.systems_id = s.id
426
                        JOIN %s m
427
                        WITH s.id = m.systems_id
428
                        JOIN %s l
429
                        WITH m.id = l.id
430
                        JOIN %s ly
431
                        WITH l.layer = ly
432
                        JOIN %s cc
433
                        WITH c.colonyClass = cc
434
                        WHERE c.user_id = :nooneUserId
435
                        AND cc.allow_start = :allowStart
436
                        AND ly.id = :currentLayerId',
437
                    Colony::class,
438
                    StarSystemMap::class,
439
                    StarSystem::class,
440
                    Map::class,
441
                    Location::class,
442
                    Layer::class,
443
                    ColonyClass::class
444
                )
445
            )
446
                ->setParameters([
447
                    'currentX' => $currentX,
448
                    'currentY' => $currentY,
449
                    'currentLayerId' => $currentLayerId,
450
                    'nooneUserId' => UserConstants::USER_NOONE,
451
                    'allowStart' => true
452
                ])
453
                ->getSingleScalarResult();
454
455
            return $result > 0 ? (int)$result : null;
456
        } catch (NoResultException) {
457
            return null;
458
        }
459
    }
460
}
461