Completed
Branch master (83a2f0)
by De Cramer
02:40
created

GuiHandler::executeMultiCall()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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