Passed
Pull Request — master (#1887)
by Janko
53:41
created

EndLotteryPeriod::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
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 13
dl 0
loc 15
ccs 0
cts 2
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
namespace Stu\Module\Maintenance;
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\Player\UserAwardEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Player\UserAwardEnum 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\Trade\TradeEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Component\Trade\TradeEnum 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\Module\Award\Lib\CreateUserAwardInterface;
10
use Stu\Module\Commodity\CommodityTypeEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\Commodity\CommodityTypeEnum 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\Module\Control\StuRandom;
12
use Stu\Module\Control\StuTime;
13
use Stu\Module\Message\Lib\PrivateMessageFolderTypeEnum;
14
use Stu\Module\Message\Lib\PrivateMessageSenderInterface;
15
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...
16
use Stu\Module\Prestige\Lib\CreatePrestigeLogInterface;
17
use Stu\Module\Ship\Lib\ShipCreatorInterface;
18
use Stu\Module\Trade\Lib\LotteryFacadeInterface;
19
use Stu\Module\Trade\Lib\TradeLibFactoryInterface;
20
use Stu\Orm\Entity\LotteryWinnerBuildplanInterface;
21
use Stu\Orm\Entity\TradePostInterface;
22
use Stu\Orm\Entity\UserInterface;
23
use Stu\Orm\Repository\AwardRepositoryInterface;
24
use Stu\Orm\Repository\LotteryTicketRepositoryInterface;
25
use Stu\Orm\Repository\LotteryWinnerBuildplanRepositoryInterface;
26
use Stu\Orm\Repository\TradePostRepositoryInterface;
27
use Stu\Orm\Repository\UserRepositoryInterface;
28
29
final class EndLotteryPeriod implements MaintenanceHandlerInterface
30
{
31
    public function __construct(
32
        private LotteryTicketRepositoryInterface $lotteryTicketRepository,
33
        private TradePostRepositoryInterface $tradepostRepository,
34
        private AwardRepositoryInterface $awardRepository,
35
        private LotteryWinnerBuildplanRepositoryInterface $lotteryWinnerBuildplanRepository,
36
        private UserRepositoryInterface $userRepository,
37
        private LotteryFacadeInterface $lotteryFacade,
38
        private TradeLibFactoryInterface $tradeLibFactory,
39
        private CreateUserAwardInterface $createUserAward,
40
        private ShipCreatorInterface $shipCreator,
41
        private CreatePrestigeLogInterface $createPrestigeLog,
42
        private PrivateMessageSenderInterface $privateMessageSender,
43
        private StuTime $stuTime,
44
        private StuRandom $stuRandom
45
    ) {}
46
47
    #[Override]
48
    public function handle(): void
49
    {
50
        $time = $this->stuTime->time();
51
        $day = (int)date("j", $time);
52
53
        if ($day !== 1) {
54
            return;
55
        }
56
57
        $tickets = $this->lotteryFacade->getTicketsOfLastPeriod();
58
        $ticketCount = count($tickets);
59
60
        if ($ticketCount === 0) {
61
            return;
62
        }
63
64
        $tradePost = $this->tradepostRepository->getFergTradePost(TradeEnum::DEALS_FERG_TRADEPOST_ID);
65
        if ($tradePost === null) {
66
            throw new RuntimeException('no deals ferg tradepost found');
67
        }
68
69
        $jackpot = (int)ceil($ticketCount / 100 * 80);
70
71
        $winnerIndex = random_int(0, $ticketCount - 1);
72
        $losers = [];
73
        $winner = null;
74
75
        //set winner and loser
76
        for ($i = 0; $i < $ticketCount; $i++) {
77
            $ticket = $tickets[$i];
78
            $user = $ticket->getUser();
79
80
            if ($i === $winnerIndex) {
81
                $ticket->setIsWinner(true);
82
                $winner = $user;
83
84
                //jackpot to winner
85
                $this->createAwardAndPrestige($winner, $time);
86
                $this->payOutLatinum($winner, $jackpot, $ticketCount, $tradePost);
87
                $this->transmitShip($winner, $tradePost);
88
            } else {
89
                $ticket->setIsWinner(false);
90
91
                $losers[$user->getId()] = $user;
92
            }
93
94
            $this->lotteryTicketRepository->save($ticket);
95
        }
96
97
        if ($winner === null) {
98
            return;
99
        }
100
101
        //PM to all losers
102
        foreach ($losers as $loserId => $user) {
103
            //skip winner if he had more than one ticket
104
            if ($user === $winner) {
105
                continue;
106
            }
107
108
            $this->privateMessageSender->send(
109
                $tradePost->getUserId(),
110
                $loserId,
111
                sprintf(
112
                    "%s hat %d Latinum in der Lotterie gewonnen.\nEs waren %d Lose im Topf.\nViel Glück beim nächsten Mal!",
113
                    $winner->getName(),
114
                    $jackpot,
115
                    $ticketCount
116
                ),
117
                PrivateMessageFolderTypeEnum::SPECIAL_TRADE
118
            );
119
        }
120
121
        $userCount = $this->userRepository->getActiveAmount();
122
123
        //give random users a ticket
124
        foreach ($this->userRepository->getNonNpcList() as $user) {
125
            $winRateInPercent = 10 * ($user->getId() - UserEnum::USER_FIRST_ID) / $userCount;
126
127
            if (random_int(1, 100) > $winRateInPercent) {
128
                continue;
129
            }
130
131
            $this->lotteryFacade->createLotteryTicket($user, true);
132
        }
133
    }
134
135
    private function createAwardAndPrestige(UserInterface $user, int $time): void
136
    {
137
        $award = $this->awardRepository->find(UserAwardEnum::LOTTERY_WINNER);
138
139
        if ($award !== null) {
140
            $this->createUserAward->createAwardForUser(
141
                $user,
142
                $award
143
            );
144
        }
145
146
        $amount = $this->lotteryFacade->getTicketAmountByUser($user->getId(), true);
147
148
        $this->createPrestigeLog->createLog(
149
            $amount,
150
            sprintf('%1$d Prestige erhalten für den Erwerb von %1$d Losen in der letzten Lotterieziehung', $amount),
151
            $user,
152
            $time
153
        );
154
    }
155
156
    private function payOutLatinum(UserInterface $winner, int $jackpot, int $ticketCount, TradePostInterface $tradePost): void
157
    {
158
        $storageManagerUser = $this->tradeLibFactory->createTradePostStorageManager($tradePost, $winner);
159
160
        $storageManagerUser->upperStorage(
161
            CommodityTypeEnum::COMMODITY_LATINUM,
162
            $jackpot
163
        );
164
165
        $this->privateMessageSender->send(
166
            $tradePost->getUserId(),
167
            $winner->getId(),
168
            sprintf(
169
                "Du hast %d Latinum in der Lotterie gewonnen.\nEs waren %d Lose im Topf.\nDer Gewinn wartet auf dich am Handelsposten 'Zur goldenen Kugel'",
170
                $jackpot,
171
                $ticketCount
172
            ),
173
            PrivateMessageFolderTypeEnum::SPECIAL_TRADE
174
        );
175
    }
176
177
    private function transmitShip(UserInterface $winner, TradePostInterface $tradePost): void
178
    {
179
        /** @var array<int, LotteryWinnerBuildplanInterface> */
180
        $winnerBuildplans = $this->lotteryWinnerBuildplanRepository->findAll();
181
        if (empty($winnerBuildplans)) {
182
            return;
183
        }
184
185
        $chances = array_map(fn(LotteryWinnerBuildplanInterface $winnerBuildplan) => $winnerBuildplan->getChance(), $winnerBuildplans);
186
187
        $randomKey = $this->stuRandom->randomKeyOfProbabilities($chances);
188
        $buildplan = $winnerBuildplans[$randomKey]->getBuildplan();
189
190
        $wrapper = $this->shipCreator
191
            ->createBy(
192
                $winner->getId(),
193
                $buildplan->getRumpId(),
194
                $buildplan->getId()
195
            )->setLocation($tradePost->getShip()->getLocation())
196
            ->setShipName(sprintf(
197
                'Lotteriegewinn (%s)',
198
                $this->stuTime->transformToStuDate(time())
199
            ))
200
            ->finishConfiguration();
201
202
        $ship = $wrapper->get();
203
204
        $this->privateMessageSender->send(
205
            $tradePost->getUserId(),
206
            $winner->getId(),
207
            sprintf(
208
                "Als zusätzlicher Lotteriegewinn wurde dir ein Schiff der %s-Klasse zu den Koordinaten %s am Handelsposten 'Zur goldenen Kugel' überstellt.",
209
                $ship->getRumpName(),
210
                $ship->getSectorString()
211
            ),
212
            PrivateMessageFolderTypeEnum::SPECIAL_SHIP
213
        );
214
    }
215
}
216