GuiHandler::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 13
Ratio 100 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
dl 13
loc 13
ccs 7
cts 7
cp 1
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 5
crap 1
1
<?php
2
3
namespace eXpansion\Framework\Core\Plugins;
4
5
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpTimer;
6
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpUserGroup;
7
use eXpansion\Framework\Core\Model\Gui\ManialinkFactoryInterface;
8
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
9
use eXpansion\Framework\Core\Model\UserGroups\Group;
10
use eXpansion\Framework\Core\Plugins\Gui\ActionFactory;
11
use eXpansion\Framework\Core\Plugins\Gui\ManialinkFactory;
12
use eXpansion\Framework\Core\Services\Console;
13
use eXpansion\Framework\Core\Services\DedicatedConnection\Factory;
14
use eXpansion\Framework\Core\Storage\Data\Player;
15
use eXpansion\Framework\GameManiaplanet\DataProviders\Listener\ListenerInterfaceMpLegacyPlayer;
16
use Maniaplanet\DedicatedServer\Connection;
17
use oliverde8\AssociativeArraySimplified\AssociativeArray;
18
use Psr\Log\LoggerInterface;
19
20
/**
21
 * Class GuiHandler will send manialinks to player as needed.
22
 *
23
 * @package eXpansion\Framework\Core\Plugins\Gui
24
 * @author Oliver de Cramer
25
 */
26
class GuiHandler implements
27
    ListenerInterfaceExpTimer,
28
    ListenerInterfaceExpUserGroup,
29
    ListenerInterfaceMpLegacyPlayer,
30
    StatusAwarePluginInterface,
31
    GuiHandlerInterface
32
{
33
    /** @var Factory */
34
    protected $factory;
35
36
    /** @var LoggerInterface */
37
    protected $logger;
38
39
    /** @var Console */
40
    protected $console;
41
42
    /** @var ActionFactory */
43
    protected $actionFactory;
44
45
    /** @var int */
46
    protected $charLimit;
47
48
    /** @var ManialinkInterface[][] */
49
    protected $displayQueu = [];
50
51
    /** @var ManialinkInterface[][] */
52
    protected $individualQueu = [];
53
54
    /** @var ManialinkInterface[][] */
55
    protected $displayeds = [];
56
57
    /** @var ManialinkInterface[][] */
58
    protected $hideQueu = [];
59
60
    /** @var ManialinkInterface[][] */
61
    protected $hideIndividualQueu = [];
62
63
    /** @var String[] */
64
    protected $disconnectedLogins = [];
65
66
    /**
67
     * GuiHandler constructor.
68
     *
69
     * @param Factory $factory
70
     * @param LoggerInterface $logger
71
     * @param Console $console
72
     * @param ActionFactory $actionFactory
73
     * @param int $charLimit
74
     */
75 15 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
76
        Factory $factory,
77
        LoggerInterface $logger,
78
        Console $console,
79
        ActionFactory $actionFactory,
80
        $charLimit = 262144
81
    ) {
82 15
        $this->factory = $factory;
83 15
        $this->logger = $logger;
84 15
        $this->console = $console;
85 15
        $this->actionFactory = $actionFactory;
86 15
        $this->charLimit = $charLimit;
87 15
    }
88
89
    /**
90
     * @inheritdoc
91
     */
92
    public function setStatus($status)
93
    {
94
        if ($status) {
95
            $this->factory->getConnection()->sendHideManialinkPage(null);
96
        }
97
    }
98
99
100
    /**
101
     * @inheritdoc
102
     **/
103 13
    public function addToDisplay(ManialinkInterface $manialink)
104
    {
105
106 13
        $userGroup = $manialink->getUserGroup()->getName();
107 13
        $id = $manialink->getManialinkFactory()->getId();
108
109 13
        if (AssociativeArray::getFromKey($this->hideQueu, [$userGroup, $id])) {
110 1
            unset($this->hideQueu[$userGroup][$id]);
111
        }
112
113 13
        $this->displayQueu[$userGroup][$id] = $manialink;
114 13
    }
115
116
    /**
117
     * @inheritdoc
118
     */
119 3
    public function addToHide(ManialinkInterface $manialink)
120
    {
121 3
        $userGroup = $manialink->getUserGroup()->getName();
122 3
        $id = $manialink->getManialinkFactory()->getId();
123
124 3
        if (AssociativeArray::getFromKey($this->displayQueu, [$userGroup, $id])) {
125 1
            unset($this->displayQueu[$userGroup][$id]);
126
        }
127
128 3
        if (AssociativeArray::getFromKey($this->displayeds, [$userGroup, $id])) {
129 1
            unset($this->displayeds[$userGroup][$id]);
130
        }
131
132 3
        $this->actionFactory->destroyManialinkActions($manialink);
133 3
        $this->hideQueu[$userGroup][$id] = $manialink;
134 3
    }
135
136
    /**
137
     * @inheritdoc
138
     */
139
    public function getManialink(Group $group, ManialinkFactoryInterface $manialinkFactory)
140
    {
141
        $varsToCheck = ['displayeds', 'hideQueu', 'displayQueu'];
142
143
        foreach ($varsToCheck as $var) {
144
            if (isset($this->$var[$group->getName()]) && isset($this->$var[$group->getName()][$manialinkFactory->getId()])) {
145
                return $this->$var[$group->getName()][$manialinkFactory->getId()];
146
            }
147
        }
148
149
        return null;
150
    }
151
152
    /**
153
     * @inheritdoc
154
     */
155
    public function getFactoryManialinks(ManialinkFactory $manialinkFactory)
156
    {
157
        $varsToCheck = ['displayeds', 'hideQueu', 'displayQueu'];
158
159
        $factoryManialinks = [];
160
        foreach ($varsToCheck as $var) {
161
            foreach ($this->$var as $groupName => $manialinks) {
162
                foreach ($manialinks as $manialinkFactoryId => $manialink) {
163
                    if ($manialinkFactoryId == $manialinkFactory->getId()) {
164
                        $factoryManialinks[] = $manialink;
165
                    }
166
                }
167
            }
168
        }
169
170
        return $factoryManialinks;
171
    }
172
173
    /**
174
     * Display & hide all manialinks.
175
     * @throws \Maniaplanet\DedicatedServer\InvalidArgumentException
176
     */
177 14
    protected function displayManialinks()
178
    {
179 14
        $size = 0;
180 14
        foreach ($this->getManialinksToDisplay() as $mlData) {
181 14
            $currentSize = $size;
182 14
            $size += strlen($mlData['ml']);
183
184 14
            if ($currentSize != 0 && $size > $this->charLimit) {
185 2
                $this->executeMultiCall();
186 2
                $size = strlen($mlData['ml']);
187
            }
188
189 14
            $logins = array_filter($mlData['logins'], function ($value) {
190 14
                return $value != '';
191 14
            });
192
193 14
            if (!empty($logins)) {
194 14
                $this->factory->getConnection()->sendDisplayManialinkPage(
195 14
                    $mlData['logins'],
196 14
                    $mlData['ml'],
197 14
                    $mlData['timeout'],
198 14
                    false,
199 14
                    true
200
                );
201
            }
202
        }
203
204 14
        if ($size > 0) {
205 14
            $this->executeMultiCall();
206
        }
207
208
        // Reset the queues.
209 14
        $this->displayQueu = [];
210 14
        $this->individualQueu = [];
211 14
        $this->hideQueu = [];
212 14
        $this->hideIndividualQueu = [];
213 14
        $this->disconnectedLogins = [];
214 14
    }
215
216
    /**
217
     * Execute multi call & handle error.
218
     */
219 14 View Code Duplication
    protected function executeMultiCall()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
220
    {
221
        try {
222 14
            $this->factory->getConnection()->executeMulticall();
223 1
        } catch (\Exception $e) {
224 1
            $this->logger->error("Couldn't deliver all manialinks : ".$e->getMessage(), ['exception' => $e]);
225 1
            $this->console->writeln('$F00ERROR - Couldn\'t deliver all manialinks : '.$e->getMessage());
226
        }
227 14
    }
228
229
    /**
230
     * Get list of all manialinks that needs to be displayed
231
     *
232
     * @return \Generator
233
     */
234 14
    protected function getManialinksToDisplay()
235
    {
236 14
        foreach ($this->displayQueu as $groupName => $manialinks) {
237 13
            foreach ($manialinks as $factoryId => $manialink) {
238 13
                $logins = $manialink->getUserGroup()->getLogins();
239
240 13
                $this->displayeds[$groupName][$factoryId] = $manialink;
241 13 View Code Duplication
                if (!empty($logins)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242 13
                    yield ['logins' => $logins, 'ml' => $manialink->getXml(), "timeout" => $manialink->getTimeout()];
243
                }
244
            }
245
        }
246
247 14
        foreach ($this->individualQueu as $manialinks) {
248
            // Fetch all logins
249 4
            $logins = [];
250 4
            $lastManialink = null;
251 4
            foreach ($manialinks as $login => $manialink) {
252 3
                $logins[] = $login;
253 3
                $lastManialink = $manialink;
254
            }
255
256 4 View Code Duplication
            if ($lastManialink) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
257 3
                $xml = $manialink->getXml();
0 ignored issues
show
Bug introduced by
The variable $manialink does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
258 3
                yield ['logins' => $logins, 'ml' => $xml, "timeout" => $manialink->getTimeout()];
259
            }
260
        }
261
262 14
        foreach ($this->hideQueu as $manialinks) {
263 3
            foreach ($manialinks as $manialink) {
264 2
                $id = $manialink->getId();
265 2
                $manialink->destroy();
266
267 2
                $logins = $manialink->getUserGroup()->getLogins();
268 2
                $logins = array_diff($logins, $this->disconnectedLogins);
269
270 2
                if (!empty($logins)) {
271 2
                    yield ['logins' => $logins, 'ml' => '<manialink id="'.$id.'" />', "timeout" => 0];
272
                }
273
            }
274
        }
275
276 14
        foreach ($this->hideIndividualQueu as $id => $manialinks) {
277
            // Fetch all logins.
278 5
            $logins = [];
279 5
            $lastManialink = null;
280 5
            foreach ($manialinks as $login => $manialink) {
281 4
                if (!in_array($login, $this->disconnectedLogins)) {
282 3
                    $logins[] = $login;
283 3
                    $lastManialink = $manialink;
284
                }
285
            }
286
287 5
            if ($lastManialink) {
288
                // Manialink is not destroyed just not shown at a particular user that left the group.
289 3
                yield ['logins' => $logins, 'ml' => '<manialink id="'.$lastManialink->getId().'" />', "timeout" => 0];
290
            }
291
        }
292 14
    }
293
294
    /**
295
     * @param int $charLimit
296
     */
297 2
    public function setCharLimit($charLimit)
298
    {
299 2
        $this->charLimit = $charLimit;
300 2
    }
301
302
    /**
303
     * List of all manialinks that are currently displayed.
304
     *
305
     * @return ManialinkInterface[][]
306
     */
307 1
    public function getDisplayeds()
308
    {
309 1
        return $this->displayeds;
310
    }
311
312
    /**
313
     * @inheritdoc
314
     */
315 14
    public function onPostLoop()
316
    {
317 14
        $this->displayManialinks();
318 14
    }
319
320
    /**
321
     * @inheritdoc
322
     */
323 1
    public function onPreLoop()
324
    {
325 1
    }
326
327
    /**
328
     * @inheritdoc
329
     */
330 1
    public function onEverySecond()
331
    {
332 1
    }
333
334
    /**
335
     * @inheritdoc
336
     */
337 4 View Code Duplication
    public function onExpansionGroupAddUser(Group $group, $loginAdded)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
338
    {
339 4
        $group = $group->getName();
340
341
        // User was added to group, need to display all manialinks of the group to this user
342 4
        if (isset($this->displayeds[$group])) {
343 4
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
344 4
                $this->individualQueu[$mlId][$loginAdded] = $manialink;
345
346 4
                if (isset($this->hideIndividualQueu[$mlId]) && isset($this->hideIndividualQueu[$mlId][$loginAdded])) {
347 1
                    unset ($this->hideIndividualQueu[$mlId][$loginAdded]);
348
                }
349
            }
350
        }
351 4
    }
352
353
    /**
354
     * @inheritdoc
355
     */
356 5 View Code Duplication
    public function onExpansionGroupRemoveUser(Group $group, $loginRemoved)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
357
    {
358 5
        $group = $group->getName();
359
360
        // User was removed from group, need to hide all manialinks of the group to this user
361 5
        if (isset($this->displayeds[$group])) {
362 5
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
363 5
                $this->hideIndividualQueu[$mlId][$loginRemoved] = $manialink;
364
365 5
                if (isset($this->individualQueu[$mlId]) && isset($this->individualQueu[$mlId][$loginRemoved])) {
366 1
                    unset ($this->individualQueu[$mlId][$loginRemoved]);
367
                }
368
            }
369
        }
370 5
    }
371
372
    /**
373
     * @inheritdoc
374
     */
375 1
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
376
    {
377 1
        if (isset($this->displayeds[$group->getName()])) {
378 1
            unset($this->displayeds[$group->getName()]);
379
        }
380 1
    }
381
382
    /**
383
     * @inheritdoc
384
     */
385 1
    public function onPlayerConnect(Player $player)
386
    {
387 1
    }
388
389
    /**
390
     * @inheritdoc
391
     */
392 1
    public function onPlayerDisconnect(Player $player, $disconnectionReason)
393
    {
394
        // To prevent sending manialinks to those players.
395 1
        $this->disconnectedLogins[] = $player->getLogin();
396 1
    }
397
398
    /**
399
     * @inheritdoc
400
     */
401 1
    public function onPlayerInfoChanged(Player $oldPlayer, Player $player)
402
    {
403 1
    }
404
405
    /**
406
     * @inheritdoc
407
     */
408 1
    public function onPlayerAlliesChanged(Player $oldPlayer, Player $player)
409
    {
410 1
    }
411
}
412