Completed
Push — master ( 2a3483...c07a8d )
by De Cramer
02:05 queued 02:03
created

GuiHandler::onPreLoop()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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