Completed
Pull Request — master (#182)
by De Cramer
52:24 queued 46:41
created

GuiHandler::setCharLimit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
cc 1
eloc 2
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\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 13
    public function __construct(
70
        Connection $connection,
71
        LoggerInterface $logger,
72
        Console $console,
73
        ActionFactory $actionFactory,
74
        $charLimit = 262144
75
    ) {
76 13
        $this->connection = $connection;
77
78 13
        $this->connection->sendHideManialinkPage(null);
79
80 13
        $this->logger = $logger;
81 13
        $this->console = $console;
82 13
        $this->actionFactory = $actionFactory;
83 13
        $this->charLimit = $charLimit;
84 13
    }
85
86
87
    /**
88
     * @inheritdoc
89
     **/
90 11
    public function addToDisplay(ManialinkInterface $manialink)
91
    {
92
93 11
        $userGroup = $manialink->getUserGroup()->getName();
94 11
        $id = $manialink->getManialinkFactory()->getId();
95
96 11
        if (AssociativeArray::getFromKey($this->hideQueu, [$userGroup, $id])) {
97 1
            unset($this->hideQueu[$userGroup][$id]);
98
        }
99
100 11
        $this->displayQueu[$userGroup][$id] = $manialink;
101 11
    }
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 12
    protected function displayManialinks()
143
    {
144 12
        $size = 0;
145 12
        foreach ($this->getManialinksToDisplay() as $mlData) {
146 12
            $currentSize = $size;
147 12
            $size += strlen($mlData['ml']);
148
149 12
            if ($currentSize != 0 && $size > $this->charLimit) {
150 2
                $this->executeMultiCall();
151 2
                $size = strlen($mlData['ml']);
152
            }
153
154 12
            $this->connection->sendDisplayManialinkPage(
155 12
                $mlData['logins'],
156 12
                $mlData['ml'],
157 12
                0,
158 12
                false,
159 12
                true
160
            );
161
        }
162
163 12
        if ($size > 0) {
164 12
            $this->executeMultiCall();
165
        }
166
167
        // Reset the queues.
168 12
        $this->displayQueu = [];
169 12
        $this->individualQueu = [];
170 12
        $this->hideQueu = [];
171 12
        $this->hideIndividualQueu = [];
172 12
        $this->disconnectedLogins = [];
173 12
    }
174
175
    /**
176
     * Execute multi call & handle error.
177
     */
178 12
    protected function executeMultiCall()
179
    {
180
        try {
181 12
            $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 12
    }
187
188
    /**
189
     * Get list of all manialinks that needs to be displayed
190
     *
191
     * @return \Generator
192
     */
193 12
    protected function getManialinksToDisplay()
194
    {
195 12
        foreach ($this->displayQueu as $groupName => $manialinks) {
196 11
            foreach ($manialinks as $factoryId => $manialink) {
197 11
                $logins = $manialink->getUserGroup()->getLogins();
198
199 11
                $this->displayeds[$groupName][$factoryId] = $manialink;
200 11
                if (!empty($logins)) {
201 11
                    yield ['logins' => $logins, 'ml' => $manialink->getXml()];
202
                }
203
            }
204
        }
205
206 12
        foreach ($this->individualQueu as $login => $manialinks) {
207 3
            foreach ($manialinks as $manialink) {
208 2
                $xml = $manialink->getXml();
209 3
                yield ['logins' => $login, 'ml' => $xml];
210
            }
211
        }
212
213 12
        foreach ($this->hideQueu as $manialinks) {
214 3
            foreach ($manialinks as $manialink) {
215 2
                $id = $manialink->getId();
216 2
                $manialink->destroy();
217
218 2
                $logins = $manialink->getUserGroup()->getLogins();
219 2
                $logins = array_diff($logins, $this->disconnectedLogins);
220
221 2
                if (!empty($logins)) {
222 3
                    yield ['logins' => $logins, 'ml' => '<manialink id="'.$id.'" />'];
223
                }
224
            }
225
        }
226
227 12
        foreach ($this->hideIndividualQueu as $login => $manialinks) {
228 4
            foreach ($manialinks as $manialink) {
229 3
                $id = $manialink->getId();
230
                // Manialink is not destroyed just not shown at a particular user that left the group.
231
232 3
                if (!in_array($login, $this->disconnectedLogins)) {
233 4
                    yield ['logins' => $login, 'ml' => '<manialink id="'.$id.'" />'];
234
                }
235
            }
236
        }
237 12
    }
238
239
    /**
240
     * @param int $charLimit
241
     */
242 2
    public function setCharLimit($charLimit)
243
    {
244 2
        $this->charLimit = $charLimit;
245 2
    }
246
247
    /**
248
     * List of all manialinks that are currently displayed.
249
     *
250
     * @return ManialinkInterface[][]
251
     */
252 1
    public function getDisplayeds()
253
    {
254 1
        return $this->displayeds;
255
    }
256
257
    /**
258
     * @inheritdoc
259
     */
260 12
    public function onPostLoop()
261
    {
262 12
        $this->displayManialinks();
263 12
    }
264
265
    /**
266
     * @inheritdoc
267
     */
268 1
    public function onPreLoop()
269
    {
270 1
    }
271
272
    /**
273
     * @inheritdoc
274
     */
275 1
    public function onEverySecond()
276
    {
277 1
    }
278
279
    /**
280
     * @inheritdoc
281
     */
282 3 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...
283
    {
284 3
        $group = $group->getName();
285
286
        // User was added to group, need to display all manialinks of the group to this user
287 3
        if (isset($this->displayeds[$group])) {
288 3
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
289 3
                $this->individualQueu[$loginAdded][$mlId] = $manialink;
290
291 3
                if (isset($this->hideIndividualQueu[$loginAdded]) && isset($this->hideIndividualQueu[$loginAdded][$mlId])) {
292 3
                    unset ($this->hideIndividualQueu[$loginAdded][$mlId]);
293
                }
294
            }
295
        }
296 3
    }
297
298
    /**
299
     * @inheritdoc
300
     */
301 4 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...
302
    {
303 4
        $group = $group->getName();
304
305
        // User was removed from group, need to hide all manialinks of the group to this user
306 4
        if (isset($this->displayeds[$group])) {
307 4
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
308 4
                $this->hideIndividualQueu[$loginRemoved][$mlId] = $manialink;
309
310 4
                if (isset($this->individualQueu[$loginRemoved]) && isset($this->individualQueu[$loginRemoved][$mlId])) {
311 4
                    unset ($this->individualQueu[$loginRemoved][$mlId]);
312
                }
313
            }
314
        }
315 4
    }
316
317
    /**
318
     * @inheritdoc
319
     */
320 1
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
321
    {
322 1
        if (isset($this->displayeds[$group->getName()])) {
323 1
            unset($this->displayeds[$group->getName()]);
324
        }
325 1
    }
326
327
    /**
328
     * @inheritdoc
329
     */
330 1
    public function onPlayerConnect(Player $player)
331
    {
332 1
    }
333
334
    /**
335
     * @inheritdoc
336
     */
337 1
    public function onPlayerDisconnect(Player $player, $disconnectionReason)
338
    {
339
        // To prevent sending manialinks to those players.
340 1
        $this->disconnectedLogins[] = $player->getLogin();
341 1
    }
342
343
    /**
344
     * @inheritdoc
345
     */
346 1
    public function onPlayerInfoChanged(Player $oldPlayer, Player $player)
347
    {
348 1
    }
349
350
    /**
351
     * @inheritdoc
352
     */
353 1
    public function onPlayerAlliesChanged(Player $oldPlayer, Player $player)
354
    {
355 1
    }
356
}
357