Completed
Push — master ( 6c7852...c45dbb )
by De Cramer
14s
created

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