Completed
Pull Request — master (#161)
by De Cramer
02:59
created

GuiHandler::getDisplayeds()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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