Failed Conditions
Push — dev ( 460643...c06d4d )
by Janko
05:36
created

EventMapGeneration::generateEventMapForLayer()   D

Complexity

Conditions 18
Paths 34

Size

Total Lines 92
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 342

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 18
eloc 60
c 1
b 0
f 1
nc 34
nop 2
dl 0
loc 92
ccs 0
cts 61
cp 0
crap 342
rs 4.8666

How to fix   Long Method    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
declare(strict_types=1);
4
5
namespace Stu\Module\Tick\History\Component;
6
7
use InvalidArgumentException;
8
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...
9
use Stu\Component\Map\EncodedMapInterface;
10
use Stu\Lib\ModuleScreen\GradientColorInterface;
11
use Stu\Module\Config\StuConfigInterface;
12
use Stu\Module\Control\StuTime;
13
use Stu\Module\Logging\StuLogger;
14
use Stu\Module\Tick\History\HistoryTickHandlerInterface;
15
use Stu\Orm\Repository\LayerRepositoryInterface;
16
use Stu\Orm\Repository\MapRepositoryInterface;
17
use Stu\Orm\Entity\Layer;
18
use Stu\Orm\Repository\HistoryRepositoryInterface;
19
20
final class EventMapGeneration implements HistoryTickHandlerInterface
21
{
22
    private const SCALE = 5;
23
24
    public function __construct(
25
        private readonly MapRepositoryInterface $mapRepository,
26
        private readonly LayerRepositoryInterface $layerRepository,
27
        private readonly HistoryRepositoryInterface $historyRepository,
28
        private readonly StuConfigInterface $config,
29
        private readonly EncodedMapInterface $encodedMap,
30
        private readonly GradientColorInterface $gradientColor,
31
        private readonly StuTime $stuTime
32
    ) {}
33
34
    #[\Override]
35
    public function work(): void
36
    {
37
        $mapGraphicBasePath = $this->getMapGraphicBasePath();
38
39
        foreach($this->layerRepository->findAll() as $layer) {
40
            $this->generateEventMapForLayer($layer, $mapGraphicBasePath);
41
        }
42
    }
43
44
    private function generateEventMapForLayer(Layer $layer, string $mapGraphicBasePath): void
45
    {
46
        $width = $layer->getWidth() * self::SCALE;
47
        $height = $layer->getHeight() * self::SCALE;
48
49
        if ($width < 1 || $height < 1) {
50
            throw new InvalidArgumentException('Ungültige Dimensionen für die Bilderstellung');
51
        }
52
53
        $img = imagecreatetruecolor($width, $height);
54
        if ($img === false) {
55
            throw new InvalidArgumentException('Fehler bei Erstellung von true color image');
56
        }
57
58
        $types = [];
59
60
        // mapfields
61
        $startY = 1;
62
        $cury = 0;
63
        $curx = 0;
64
65
        foreach ($this->mapRepository->getAllOrdered($layer) as $data) {
66
            if ($startY !== $data->getCy()) {
67
                $startY = $data->getCy();
68
                $curx = 0;
69
                $cury += self::SCALE;
70
            }
71
72
            $imagePath = $this->getMapGraphicPath($layer, $data->getFieldType()->getType(), $mapGraphicBasePath);
73
            $partialImage = imagecreatefrompng($imagePath);
74
            if ($partialImage === false) {
75
                throw new InvalidArgumentException('error creating partial image');
76
            }
77
78
            $types[$data->getFieldId()] = $partialImage;
79
            imagecopyresized($img, $types[$data->getFieldId()], $curx, $cury, 0, 0, self::SCALE, self::SCALE, 30, 30);
80
            $curx += self::SCALE;
81
        }
82
83
        imagefilter($img, IMG_FILTER_GRAYSCALE);
84
        $historyAmountsIndexed = $this->historyRepository->getAmountIndexedByLocationId(
85
            $layer,
86
            $this->stuTime->time() - TimeConstants::SEVEN_DAYS_IN_SECONDS
87
        );
88
        foreach ($historyAmountsIndexed as $data) {
89
            $map = $data[0];
90
            $locationId = $map->getId();
91
            $historyCount = $data['amount'];
92
            [$red, $green, $blue] = $this->gradientColor->calculateGradientColorRGB($historyCount, 0, 20);
93
94
            $cury = ($map->getCy() - 1) * self::SCALE;
95
            $curx = ($map->getCx() - 1) * self::SCALE;
96
97
            if (
98
                $red < 0 || $red > 255
99
                || $green < 0 || $green > 255
100
                || $blue < 0 || $blue > 255
101
            ) {
102
                throw new InvalidArgumentException(sprintf('rgb range exception, red: %d, green: %d, blue: %d', $red, $green, $blue));
103
            }
104
105
            StuLogger::logf("location %d has %d history entries -> rgb(%d,%d,%d)", $locationId, $historyCount, $red, $green, $blue);
106
107
            $filling = imagecreatetruecolor(self::SCALE, self::SCALE);
108
            $col = imagecolorallocate($filling, $red, $green, $blue);
109
            if (!$col) {
110
                throw new InvalidArgumentException(sprintf('color range exception, col: %d', $col));
111
            }
112
            imagefill($filling, 0, 0, $col);
113
            imagecopy($img, $filling, $curx, $cury, 0, 0, self::SCALE, self::SCALE);
114
        }
115
116
        //clear all resources in history folder
117
        $historyFolder = $this->config->getGameSettings()->getTempDir() . '/history';
118
        $files = glob($historyFolder . '/layer_' . $layer->getId() . '.png');
119
        if ($files === false) {
120
            throw new InvalidArgumentException('error reading history folder files');
121
        }
122
        foreach ($files as $file) {
123
            if (is_file($file)) {
124
                unlink($file);
125
            }
126
        }
127
128
        StuLogger::logf("saving event map for layer %d", $layer->getId());
129
130
        imagepng(
131
            $img,
132
            sprintf(
133
                '%s/history/layer_%d.png',
134
                $this->config->getGameSettings()->getTempDir(),
135
                $layer->getId()
136
            )
137
        );
138
    }
139
140
    private function getMapGraphicBasePath(): string
141
    {
142
        $webrootWithoutPublic = str_replace("/Public", "", $this->config->getGameSettings()->getWebroot());
143
144
        return $webrootWithoutPublic . '/../../assets/map/';
145
    }
146
147
    private function getMapGraphicPath(Layer $layer, int $fieldType, string $mapGraphicBasePath): string
148
    {
149
        if ($layer->isEncoded()) {
150
            return $mapGraphicBasePath . $this->encodedMap->getEncodedMapPath($fieldType, $layer);
151
        }
152
153
        return $mapGraphicBasePath . $layer->getId() . "/" . $fieldType . '.png';
154
    }
155
}
156