Completed
Push — dev ( 007c56...e65940 )
by
unknown
04:40
created

GuiHandler::onEverySecond()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 10
cts 10
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 14
nc 12
nop 0
crap 6
1
<?php
2
3
namespace eXpansion\Framework\Core\Plugins;
4
5
use eXpansion\Framework\Core\DataProviders\Listener\TimerDataListenerInterface;
6
use eXpansion\Framework\Core\DataProviders\Listener\UserGroupDataListenerInterface;
7
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
8
use eXpansion\Framework\Core\Model\UserGroups\Group;
9
use eXpansion\Framework\Core\Services\Console;
10
use Maniaplanet\DedicatedServer\Connection;
11
use Monolog\Logger;
12
use oliverde8\AssociativeArraySimplified\AssociativeArray;
13
14
/**
15
 * Class GuiHandler will send manialinks to player as needed.
16
 *
17
 * @package eXpansion\Framework\Core\Plugins\Gui
18
 * @author Oliver de Cramer
19
 */
20
class GuiHandler implements TimerDataListenerInterface, UserGroupDataListenerInterface
21
{
22
    /** @var Connection */
23
    protected $connection;
24
25
    /** @var Logger */
26
    protected $logger;
27
28
    /** @var Console */
29
    protected $console;
30
31
    /** @var int */
32
    protected $charLimit;
33
34
    /** @var ManialinkInterface[][] */
35
    protected $displayQueu = [];
36
37
    /** @var ManialinkInterface[][] */
38
    protected $individualQueu = [];
39
40
    /** @var ManialinkInterface[][] */
41
    protected $displayeds = [];
42
43
    /** @var ManialinkInterface[][] */
44
    protected $hideQueu = [];
45
46
    /** @var String[][] */
47
    protected $hideIndividualQueu = [];
48
49
    private $groupsBuffer = [];
50
    private $windowsBuffer = [];
51
52
    /**
53
     * GuiHandler constructor.
54 10
     *
55
     * @param Connection $connection
56 10
     */
57
    public function __construct(Connection $connection, Logger $logger, Console $console, $charLimit = 262144)
58 10
    {
59
        $this->connection = $connection;
60 10
61 10
        $this->connection->sendHideManialinkPage(null);
62 10
63 10
        $this->logger = $logger;
64
        $this->console = $console;
65
        $this->charLimit = $charLimit;
66
    }
67
68
69
    /**
70
     * Add a manialink to the display queue.
71 8
     *
72
     * @param ManialinkInterface $manialink
73 8
     *
74
     * @return void
75 8
     */
76 1
    public function addToDisplay(ManialinkInterface $manialink)
77
    {
78
        $userGroup = $manialink->getUserGroup()->getName();
79 8
80 8 View Code Duplication
        if (AssociativeArray::getFromKey($this->hideQueu, [$userGroup, $manialink->getId()])) {
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...
81
            unset($this->hideQueu[$userGroup][$manialink->getId()]);
82
        }
83
84
        $this->displayQueu[$userGroup][$manialink->getId()] = $manialink;
85
    }
86
87 3
    /**
88
     * Add a manialink to the destruction queue.
89 3
     *
90
     * @param ManialinkInterface $manialink
91 3
     */
92 1
    public function addToHide(ManialinkInterface $manialink)
93
    {
94
        $userGroup = $manialink->getUserGroup()->getName();
95 3
96 1 View Code Duplication
        if (AssociativeArray::getFromKey($this->displayQueu, [$userGroup, $manialink->getId()])) {
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...
97
            unset($this->displayQueu[$userGroup][$manialink->getId()]);
98
        }
99 3
100 3 View Code Duplication
        if (AssociativeArray::getFromKey($this->displayeds, [$userGroup, $manialink->getId()])) {
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...
101
            unset($this->displayeds[$userGroup][$manialink->getId()]);
102
        }
103
104
        $this->hideQueu[$userGroup][$manialink->getId()] = $manialink;
105 9
    }
106
107 9
    /**
108 9
     * Display & hide all manialinks.
109 9
     */
110 9
    protected function displayManialinks()
111
    {
112 9
        $size = 0;
113 2
        foreach ($this->getManialinksToDisplay() as $mlData) {
114 2
            $currentSize = $size;
115
            $size += strlen($mlData['ml']);
116
117 9
            if ($currentSize != 0 && $size > $this->charLimit) {
118
                $this->executeMultiCall();
119
                $size = strlen($mlData['ml']);
120 9
            }
121 9
122
            $this->connection->sendDisplayManialinkPage(
123
                $mlData['logins'],
124
                $mlData['ml'],
125 9
                0,
126 9
                false,
127 9
                true
128 9
            );
129 9
        }
130
131
        if ($size > 0) {
132
            $this->executeMultiCall();
133
        }
134 9
135
        // Reset the queues.
136
        $this->displayQueu = [];
137 9
        $this->individualQueu = [];
138 1
        $this->hideQueu = [];
139 1
        $this->hideIndividualQueu = [];
140 1
    }
141
142 9
    /**
143
     * Execute multi call & handle error.
144
     */
145
    protected function executeMultiCall()
146
    {
147
        try {
148
            $this->connection->executeMulticall();
149 9
        } catch (\Exception $e) {
150
            $this->logger->addError("Couldn't deliver all manialinks : ".$e->getMessage(), ['exception' => $e]);
151 9
            $this->console->writeln('$F00ERROR - Couldn\'t deliver all manialinks : '.$e->getMessage());
152 8
        }
153 8
    }
154
155 8
    /**
156 8
     * Get list of all manialinks that needs to be displayed
157 8
     *
158
     * @return \Generator
159
     */
160
    protected function getManialinksToDisplay()
161
    {
162 9
        foreach ($this->displayQueu as $groupName => $manialinks) {
163 1
            foreach ($manialinks as $id => $manialink) {
164 1
                $logins = $manialink->getUserGroup()->getLogins();
165 1
166
                $this->displayeds[$groupName][$id] = $manialink;
167
                if (!empty($logins)) {
168
                    yield ['logins' => $logins, 'ml' => $manialink->getXml()];
169 9
                }
170 3
            }
171 2
        }
172 2
173 3
        foreach ($this->individualQueu as $login => $manialinks) {
174
            foreach ($manialinks as $id => $manialink) {
175
                $xml = $manialink->getXml();
176
                yield ['logins' => $login, 'ml' => $xml];
177
            }
178 9
        }
179 1
180 1
        foreach ($this->hideQueu as $manialinks) {
181
            foreach ($manialinks as $id => $manialink) {
182
                $logins = $manialink->getUserGroup()->getLogins();
183 9
                if (!empty($logins)) {
184
                    yield ['logins' => $logins, 'ml' => '<manialink id="'.$id.'" />'];
185
                }
186
            }
187
        }
188 9
189
        foreach ($this->hideIndividualQueu as $login => $manialinks) {
190 9
            foreach ($manialinks as $id => $manialink) {
191 9
                yield ['logins' => $login, 'ml' => '<manialink id="'.$id.'" />'];
192
            }
193
        }
194
    }
195
196 1
    /**
197
     * @inheritdoc
198 1
     */
199
    public function onPostLoop()
200
    {
201
        $this->displayManialinks();
202
    }
203 1
204
    /**
205 1
     * @inheritdoc
206
     */
207
    public function onPreLoop()
208
    {
209
    }
210 1
211
    /**
212 1
     * @inheritdoc
213
     */
214
    public function onEverySecond()
215 1
    {
216 1
        $groups = array_keys($this->displayeds);
217 1
        if ($groups !== $this->groupsBuffer) {
218
            $this->console->writeln('groups ('.count($this->displayeds).') $0f0'.implode(",",
219
                    $groups));
220 1
        }
221
222
        $windows = [];
223
        foreach ($this->displayeds as $group => $ml) {
224
            foreach ($ml as $mlId => $manialink) {
225 1
                $windows[$group][] = $mlId;
226
            }
227 1
        }
228
229
        if ($windows !== $this->windowsBuffer) {
230 1
            foreach ($windows as $group => $data) {
231 1
                $this->console->writeln('windows in group '.$group.':$0f0'.implode(",", $data));
232 1
            }
233
        }
234
235 1
        $this->windowsBuffer = $windows;
236
        $this->groupsBuffer = $groups;
237
238
    }
239
240 1
    /**
241
     * @inheritdoc
242 1
     */
243 1
    public function onExpansionGroupAddUser(Group $group, $loginAdded)
244
    {
245 1
        $group = $group->getName();
246
247
        // User was added to group, need to display all manialinks of the group to this user
248 View Code Duplication
        if (isset($this->displayeds[$group])) {
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...
249
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
250
                $this->individualQueu[$loginAdded][$mlId] = $manialink;
251
            }
252 1
        } else {
253
            $this->console->writeln('player added to group, but group not found: $ff0'.$group);
254 1
        }
255
    }
256
257
    /**
258
     * @inheritdoc
259
     */
260 2
    public function onExpansionGroupRemoveUser(Group $group, $loginRemoved)
261
    {
262 2
        $group = $group->getName();
263 2
264
        // User was removed from group, need to hide all manialinks of the group to this user
265 View Code Duplication
        if (isset($this->displayeds[$group])) {
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...
266
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
267
                $this->hideIndividualQueu[$loginRemoved][$mlId] = $manialink;
268
            }
269
        }
270
    }
271
272
    /**
273
     * @inheritdoc
274
     */
275
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
276
    {
277
        if (isset($this->displayeds[$group->getName()])) {
278
            unset($this->displayeds[$group->getName()]);
279
        }
280
    }
281
282
    /**
283
     * List of all manialinks that are currently displayed.
284
     *
285
     * @return ManialinkInterface[][]
286
     */
287
    public function getDisplayeds()
288
    {
289
        return $this->displayeds;
290
    }
291
292
    /**
293
     * @param int $charLimit
294
     */
295
    public function setCharLimit($charLimit)
296
    {
297
        $this->charLimit = $charLimit;
298
    }
299
}
300