Completed
Pull Request — master (#189)
by De Cramer
31:19 queued 25:39
created

GuiHandler::onExpansionGroupAddUser()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 15
Ratio 100 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
dl 15
loc 15
ccs 8
cts 8
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 7
nc 4
nop 2
crap 5
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\GameManiaplanet\DataProviders\Listener\ListenerInterfaceMpLegacyPlayer;
8
use eXpansion\Framework\Core\Model\Gui\ManialinkFactoryInterface;
9
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
10
use eXpansion\Framework\Core\Model\UserGroups\Group;
11
use eXpansion\Framework\Core\Plugins\Gui\ActionFactory;
12
use eXpansion\Framework\Core\Plugins\Gui\ManialinkFactory;
13
use eXpansion\Framework\Core\Services\Console;
14
use eXpansion\Framework\Core\Storage\Data\Player;
15
use Maniaplanet\DedicatedServer\Connection;
16
use oliverde8\AssociativeArraySimplified\AssociativeArray;
17
use Psr\Log\LoggerInterface;
18
19
/**
20
 * Class GuiHandler will send manialinks to player as needed.
21
 *
22
 * @package eXpansion\Framework\Core\Plugins\Gui
23
 * @author Oliver de Cramer
24
 */
25
class GuiHandler implements
26
    ListenerInterfaceExpTimer,
27
    ListenerInterfaceExpUserGroup,
28
    ListenerInterfaceMpLegacyPlayer,
29
    GuiHandlerInterface
30
{
31
    /** @var Connection */
32
    protected $connection;
33
34
    /** @var LoggerInterface */
35
    protected $logger;
36
37
    /** @var Console */
38
    protected $console;
39
40
    /** @var ActionFactory */
41
    protected $actionFactory;
42
43
    /** @var int */
44
    protected $charLimit;
45
46
    /** @var ManialinkInterface[][] */
47
    protected $displayQueu = [];
48
49
    /** @var ManialinkInterface[][] */
50
    protected $individualQueu = [];
51
52
    /** @var ManialinkInterface[][] */
53
    protected $displayeds = [];
54
55
    /** @var ManialinkInterface[][] */
56
    protected $hideQueu = [];
57
58
    /** @var ManialinkInterface[][] */
59
    protected $hideIndividualQueu = [];
60
61
    /** @var String[] */
62
    protected $disconnectedLogins = [];
63
64
    /**
65
     * GuiHandler constructor.
66
     *
67
     * @param Connection $connection
68
     */
69 15
    public function __construct(
70
        Connection $connection,
71
        LoggerInterface $logger,
72
        Console $console,
73
        ActionFactory $actionFactory,
74
        $charLimit = 262144
75
    ) {
76 15
        $this->connection = $connection;
77
78 15
        $this->connection->sendHideManialinkPage(null);
79
80 15
        $this->logger = $logger;
81 15
        $this->console = $console;
82 15
        $this->actionFactory = $actionFactory;
83 15
        $this->charLimit = $charLimit;
84 15
    }
85
86
87
    /**
88
     * @inheritdoc
89
     **/
90 13
    public function addToDisplay(ManialinkInterface $manialink)
91
    {
92
93 13
        $userGroup = $manialink->getUserGroup()->getName();
94 13
        $id = $manialink->getManialinkFactory()->getId();
95
96 13
        if (AssociativeArray::getFromKey($this->hideQueu, [$userGroup, $id])) {
97 1
            unset($this->hideQueu[$userGroup][$id]);
98
        }
99
100 13
        $this->displayQueu[$userGroup][$id] = $manialink;
101 13
    }
102
103
    /**
104
     * @inheritdoc
105
     */
106 3
    public function addToHide(ManialinkInterface $manialink)
107
    {
108 3
        $userGroup = $manialink->getUserGroup()->getName();
109 3
        $id = $manialink->getManialinkFactory()->getId();
110
111 3
        if (AssociativeArray::getFromKey($this->displayQueu, [$userGroup, $id])) {
112 1
            unset($this->displayQueu[$userGroup][$id]);
113
        }
114
115 3
        if (AssociativeArray::getFromKey($this->displayeds, [$userGroup, $id])) {
116 1
            unset($this->displayeds[$userGroup][$id]);
117
        }
118
119 3
        $this->actionFactory->destroyManialinkActions($manialink);
120 3
        $this->hideQueu[$userGroup][$id] = $manialink;
121 3
    }
122
123
    /**
124
     * @inheritdoc
125
     */
126
    public function getManialink(Group $group, ManialinkFactoryInterface $manialinkFactory)
127
    {
128
        $varsToCheck = ['displayeds', 'hideQueu', 'displayQueu'];
129
130
        foreach ($varsToCheck as $var) {
131
            if (isset($this->$var[$group->getName()]) && isset($this->$var[$group->getName()][$manialinkFactory->getId()])) {
132
                return $this->$var[$group->getName()][$manialinkFactory->getId()];
133
            }
134
        }
135
136
        return null;
137
    }
138
139
    /**
140
     * Display & hide all manialinks.
141
     */
142 14
    protected function displayManialinks()
143
    {
144 14
        $size = 0;
145 14
        foreach ($this->getManialinksToDisplay() as $mlData) {
146 14
            $currentSize = $size;
147 14
            $size += strlen($mlData['ml']);
148
149 14
            if ($currentSize != 0 && $size > $this->charLimit) {
150 2
                $this->executeMultiCall();
151 2
                $size = strlen($mlData['ml']);
152
            }
153
154 14
            $this->connection->sendDisplayManialinkPage(
155 14
                $mlData['logins'],
156 14
                $mlData['ml'],
157 14
                0,
158 14
                false,
159 14
                true
160
            );
161
        }
162
163 14
        if ($size > 0) {
164 14
            $this->executeMultiCall();
165
        }
166
167
        // Reset the queues.
168 14
        $this->displayQueu = [];
169 14
        $this->individualQueu = [];
170 14
        $this->hideQueu = [];
171 14
        $this->hideIndividualQueu = [];
172 14
        $this->disconnectedLogins = [];
173 14
    }
174
175
    /**
176
     * Execute multi call & handle error.
177
     */
178 14
    protected function executeMultiCall()
179
    {
180
        try {
181 14
            $this->connection->executeMulticall();
182 1
        } catch (\Exception $e) {
183 1
            $this->logger->error("Couldn't deliver all manialinks : ".$e->getMessage(), ['exception' => $e]);
184 1
            $this->console->writeln('$F00ERROR - Couldn\'t deliver all manialinks : '.$e->getMessage());
185
        }
186 14
    }
187
188
    /**
189
     * Get list of all manialinks that needs to be displayed
190
     *
191
     * @return \Generator
192
     */
193 14
    protected function getManialinksToDisplay()
194
    {
195 14
        foreach ($this->displayQueu as $groupName => $manialinks) {
196 13
            foreach ($manialinks as $factoryId => $manialink) {
197 13
                $logins = $manialink->getUserGroup()->getLogins();
198
199 13
                $this->displayeds[$groupName][$factoryId] = $manialink;
200 13
                if (!empty($logins)) {
201 13
                    yield ['logins' => $logins, 'ml' => $manialink->getXml()];
202
                }
203
            }
204
        }
205
206 14
        foreach ($this->individualQueu as $manialinks) {
207
            // Fetch all logins
208 4
            $logins = [];
209 4
            $lastManialink = null;
210 4
            foreach ($manialinks as $login => $manialink) {
211 3
                $logins[] = $login;
212 3
                $lastManialink = $manialink;
213
            }
214
215 4
            if ($lastManialink) {
216 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...
217 4
                yield ['logins' => $logins, 'ml' => $xml];
218
            }
219
        }
220
221 14
        foreach ($this->hideQueu as $manialinks) {
222 3
            foreach ($manialinks as $manialink) {
223 2
                $id = $manialink->getId();
224 2
                $manialink->destroy();
225
226 2
                $logins = $manialink->getUserGroup()->getLogins();
227 2
                $logins = array_diff($logins, $this->disconnectedLogins);
228
229 2
                if (!empty($logins)) {
230 3
                    yield ['logins' => $logins, 'ml' => '<manialink id="'.$id.'" />'];
231
                }
232
            }
233
        }
234
235 14
        foreach ($this->hideIndividualQueu as $id => $manialinks) {
236
            // Fetch all logins.
237 5
            $logins = [];
238 5
            $lastManialink = null;
239 5
            foreach ($manialinks as $login => $manialink) {
240 4
                if (!in_array($login, $this->disconnectedLogins)) {
241 3
                    $logins[] = $login;
242 4
                    $lastManialink = $manialink;
243
                }
244
            }
245
246 5
            if ($lastManialink) {
247
                // Manialink is not destroyed just not shown at a particular user that left the group.
248 5
                yield ['logins' => $logins, 'ml' => '<manialink id="'.$lastManialink->getId().'" />'];
249
            }
250
        }
251 14
    }
252
253
    /**
254
     * @param int $charLimit
255
     */
256 2
    public function setCharLimit($charLimit)
257
    {
258 2
        $this->charLimit = $charLimit;
259 2
    }
260
261
    /**
262
     * List of all manialinks that are currently displayed.
263
     *
264
     * @return ManialinkInterface[][]
265
     */
266 1
    public function getDisplayeds()
267
    {
268 1
        return $this->displayeds;
269
    }
270
271
    /**
272
     * @inheritdoc
273
     */
274 14
    public function onPostLoop()
275
    {
276 14
        $this->displayManialinks();
277 14
    }
278
279
    /**
280
     * @inheritdoc
281
     */
282 1
    public function onPreLoop()
283
    {
284 1
    }
285
286
    /**
287
     * @inheritdoc
288
     */
289 1
    public function onEverySecond()
290
    {
291 1
    }
292
293
    /**
294
     * @inheritdoc
295
     */
296 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...
297
    {
298 4
        $group = $group->getName();
299
300
        // User was added to group, need to display all manialinks of the group to this user
301 4
        if (isset($this->displayeds[$group])) {
302 4
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
303 4
                $this->individualQueu[$mlId][$loginAdded] = $manialink;
304
305 4
                if (isset($this->hideIndividualQueu[$mlId]) && isset($this->hideIndividualQueu[$mlId][$loginAdded])) {
306 4
                    unset ($this->hideIndividualQueu[$mlId][$loginAdded]);
307
                }
308
            }
309
        }
310 4
    }
311
312
    /**
313
     * @inheritdoc
314
     */
315 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...
316
    {
317 5
        $group = $group->getName();
318
319
        // User was removed from group, need to hide all manialinks of the group to this user
320 5
        if (isset($this->displayeds[$group])) {
321 5
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
322 5
                $this->hideIndividualQueu[$mlId][$loginRemoved] = $manialink;
323
324 5
                if (isset($this->individualQueu[$mlId]) && isset($this->individualQueu[$mlId][$loginRemoved])) {
325 5
                    unset ($this->individualQueu[$mlId][$loginRemoved]);
326
                }
327
            }
328
        }
329 5
    }
330
331
    /**
332
     * @inheritdoc
333
     */
334 1
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
335
    {
336 1
        if (isset($this->displayeds[$group->getName()])) {
337 1
            unset($this->displayeds[$group->getName()]);
338
        }
339 1
    }
340
341
    /**
342
     * @inheritdoc
343
     */
344 1
    public function onPlayerConnect(Player $player)
345
    {
346 1
    }
347
348
    /**
349
     * @inheritdoc
350
     */
351 1
    public function onPlayerDisconnect(Player $player, $disconnectionReason)
352
    {
353
        // To prevent sending manialinks to those players.
354 1
        $this->disconnectedLogins[] = $player->getLogin();
355 1
    }
356
357
    /**
358
     * @inheritdoc
359
     */
360 1
    public function onPlayerInfoChanged(Player $oldPlayer, Player $player)
361
    {
362 1
    }
363
364
    /**
365
     * @inheritdoc
366
     */
367 1
    public function onPlayerAlliesChanged(Player $oldPlayer, Player $player)
368
    {
369 1
    }
370
}
371