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