Completed
Pull Request — master (#139)
by De Cramer
02:36
created

GuiHandler::executeMultiCall()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 2
eloc 6
nc 2
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\Core\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 String[][] */
59
    protected $hideIndividualQueu = [];
60
61
    /** @var String[] */
62
    protected $disconnectedLogins = [];
63 11
64
    /**
65 11
     * GuiHandler constructor.
66
     *
67 11
     * @param Connection $connection
68
     */
69 11
    public function __construct(
70 11
        Connection $connection,
71 11
        LoggerInterface $logger,
72 11
        Console $console,
73
        ActionFactory $actionFactory,
74
        $charLimit = 262144
75
    ) {
76
        $this->connection = $connection;
77
78
        $this->connection->sendHideManialinkPage(null);
79
80
        $this->logger = $logger;
81
        $this->console = $console;
82 9
        $this->actionFactory = $actionFactory;
83
        $this->charLimit = $charLimit;
84
    }
85 9
86 9
87
    /**
88 9
     * Add a manialink to the display queue.
89 1
     *
90
     * @param ManialinkInterface $manialink
91
     * @param ManialinkFactory   $manialinkFactory
92 9
     *
93 9
     * @return void
94
     */
95
    public function addToDisplay(ManialinkInterface $manialink, ManialinkFactoryInterface $manialinkFactory)
96
    {
97
98
        $userGroup = $manialink->getUserGroup()->getName();
99
        $id = $manialinkFactory->getId();
100 3
101
        if (AssociativeArray::getFromKey($this->hideQueu, [$userGroup, $id])) {
102 3
            unset($this->hideQueu[$userGroup][$id]);
103 3
        }
104
105 3
        $this->displayQueu[$userGroup][$id] = $manialink;
106 1
    }
107
108
    /**
109 3
     * Add a manialink to the destruction queue.
110 1
     *
111
     * @param ManialinkInterface $manialink
112
     * @param ManialinkFactory   $manialinkFactory
113 3
     */
114 3
    public function addToHide(ManialinkInterface $manialink, ManialinkFactoryInterface $manialinkFactory)
115
    {
116
        $userGroup = $manialink->getUserGroup()->getName();
117
        $id = $manialinkFactory->getId();
118
119 10
        if (AssociativeArray::getFromKey($this->displayQueu, [$userGroup, $id])) {
120
            unset($this->displayQueu[$userGroup][$id]);
121 10
        }
122 10
123 10
        if (AssociativeArray::getFromKey($this->displayeds, [$userGroup, $id])) {
124 10
            unset($this->displayeds[$userGroup][$id]);
125
        }
126 10
127 2
        $this->actionFactory->destroyManialinkActions($manialink);
128 2
        $this->hideQueu[$userGroup][$id] = $manialink;
129
    }
130
131 10
    /**
132 10
     * Get manialink for a group and manialink factory.
133 10
     *
134 10
     * @param Group            $group
135 10
     * @param ManialinkFactory $manialinkFactory
136 10
     *
137
     * @return null
138
     */
139
    public function getManialink(Group $group, ManialinkFactoryInterface $manialinkFactory)
140 10
    {
141 10
        $varsToCheck = ['displayeds', 'hideQueu', 'displayQueu'];
142
143
        foreach ($varsToCheck as $var) {
144
            if (isset($this->$var[$group->getName()]) && isset($this->$var[$group->getName()][$manialinkFactory->getId()])) {
145 10
                return $this->$var[$group->getName()][$manialinkFactory->getId()];
146 10
            }
147 10
        }
148 10
149 10
        return null;
150 10
    }
151
152
    /**
153
     * Display & hide all manialinks.
154
     */
155 10
    protected function displayManialinks()
156
    {
157
        $size = 0;
158 10
        foreach ($this->getManialinksToDisplay() as $mlData) {
159 1
            $currentSize = $size;
160 1
            $size += strlen($mlData['ml']);
161 1
162
            if ($currentSize != 0 && $size > $this->charLimit) {
163 10
                $this->executeMultiCall();
164
                $size = strlen($mlData['ml']);
165
            }
166
167
            $this->connection->sendDisplayManialinkPage(
168
                $mlData['logins'],
169
                $mlData['ml'],
170 10
                0,
171
                false,
172 10
                true
173 9
            );
174 9
        }
175
176 9
        if ($size > 0) {
177 9
            $this->executeMultiCall();
178 9
        }
179
180
        // Reset the queues.
181
        $this->displayQueu = [];
182
        $this->individualQueu = [];
183 10
        $this->hideQueu = [];
184 1
        $this->hideIndividualQueu = [];
185 1
        $this->disconnectedLogins = [];
186 1
    }
187
188
    /**
189
     * Execute multi call & handle error.
190 10
     */
191 3
    protected function executeMultiCall()
192 2
    {
193 2
        try {
194
            $this->connection->executeMulticall();
195 2
        } catch (\Exception $e) {
196 3
            $this->logger->error("Couldn't deliver all manialinks : ".$e->getMessage(), ['exception' => $e]);
197
            $this->console->writeln('$F00ERROR - Couldn\'t deliver all manialinks : '.$e->getMessage());
198
        }
199
    }
200
201 10
    /**
202 2
     * Get list of all manialinks that needs to be displayed
203 2
     *
204 2
     * @return \Generator
205
     */
206
    protected function getManialinksToDisplay()
207
    {
208 10
        foreach ($this->displayQueu as $groupName => $manialinks) {
209
            foreach ($manialinks as $factoryId => $manialink) {
210
                $logins = $manialink->getUserGroup()->getLogins();
211
212
                $this->displayeds[$groupName][$factoryId] = $manialink;
213 2
                if (!empty($logins)) {
214
                    yield ['logins' => $logins, 'ml' => $manialink->getXml()];
215 2
                }
216 2
            }
217
        }
218
219
        foreach ($this->individualQueu as $login => $manialinks) {
220
            foreach ($manialinks as $manialink) {
221
                $xml = $manialink->getXml();
222
                yield ['logins' => $login, 'ml' => $xml];
223 1
            }
224
        }
225 1
226
        foreach ($this->hideQueu as $manialinks) {
227
            foreach ($manialinks as $manialink) {
228
                $id = $manialink->getId();
229
230
                $logins = $manialink->getUserGroup()->getLogins();
231 10
                $logins = array_diff($logins, $this->disconnectedLogins);
232
233 10
                if (!empty($logins)) {
234 10
                    yield ['logins' => $logins, 'ml' => '<manialink id="'.$id.'" />'];
235
                }
236
            }
237
        }
238
239 1
        foreach ($this->hideIndividualQueu as $login => $manialinks) {
240
            foreach ($manialinks as $manialink) {
241 1
                $id = $manialink->getId();
0 ignored issues
show
Bug introduced by
The method getId cannot be called on $manialink (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
242
243
                if (!in_array($login, $this->disconnectedLogins)) {
244
                    yield ['logins' => $login, 'ml' => '<manialink id="'.$id.'" />'];
245
                }
246 1
            }
247
        }
248 1
    }
249
250
    /**
251
     * @param int $charLimit
252
     */
253 1
    public function setCharLimit($charLimit)
254
    {
255 1
        $this->charLimit = $charLimit;
256
    }
257
258 1
    /**
259 1
     * List of all manialinks that are currently displayed.
260 1
     *
261
     * @return ManialinkInterface[][]
262
     */
263 1
    public function getDisplayeds()
264
    {
265
        return $this->displayeds;
266
    }
267
268 2
    /**
269
     * @inheritdoc
270 2
     */
271
    public function onPostLoop()
272
    {
273 2
        $this->displayManialinks();
274 2
    }
275 2
276
    /**
277
     * @inheritdoc
278 2
     */
279
    public function onPreLoop()
280
    {
281
    }
282
283 1
    /**
284
     * @inheritdoc
285 1
     */
286 1
    public function onEverySecond()
287
    {
288 1
    }
289
290 1
    /**
291
     * @inheritdoc
292 1
     */
293 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...
294 1
    {
295
        $group = $group->getName();
296 1
297 1
        // User was added to group, need to display all manialinks of the group to this user
298
        if (isset($this->displayeds[$group])) {
299 1
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
300
                $this->individualQueu[$loginAdded][$mlId] = $manialink;
301 1
            }
302
        }
303 1
    }
304
305 1
    /**
306
     * @inheritdoc
307
     */
308 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...
309
    {
310
        $group = $group->getName();
311
312
        // User was removed from group, need to hide all manialinks of the group to this user
313
        if (isset($this->displayeds[$group])) {
314
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
315
                $this->hideIndividualQueu[$loginRemoved][$mlId] = $manialink;
316
            }
317
        }
318
    }
319
320
    /**
321
     * @inheritdoc
322
     */
323
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
324
    {
325
        if (isset($this->displayeds[$group->getName()])) {
326
            unset($this->displayeds[$group->getName()]);
327
        }
328
    }
329
330
    public function onPlayerConnect(Player $player)
331
    {
332
    }
333
334
    public function onPlayerDisconnect(Player $player, $disconnectionReason)
335
    {
336
        $this->disconnectedLogins[] = $player->getLogin();
337
    }
338
339
    public function onPlayerInfoChanged(Player $oldPlayer, Player $player)
340
    {
341
    }
342
343
    public function onPlayerAlliesChanged(Player $oldPlayer, Player $player)
344
    {
345
    }
346
}
347