MapListDataProvider::onMapListModified()   B
last analyzed

Complexity

Conditions 8
Paths 72

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
dl 0
loc 43
ccs 0
cts 33
cp 0
rs 7.9875
c 0
b 0
f 0
cc 8
nc 72
nop 3
crap 72
1
<?php
2
3
namespace eXpansion\Framework\GameManiaplanet\DataProviders;
4
5
use eXpansion\Framework\Core\DataProviders\AbstractDataProvider;
6
use eXpansion\Framework\Core\Plugins\StatusAwarePluginInterface;
7
use eXpansion\Framework\Core\Services\DedicatedConnection\Factory;
8
use eXpansion\Framework\Core\Storage\MapStorage;
9
use League\Flysystem\Exception;
10
use Maniaplanet\DedicatedServer\Connection;
11
use Maniaplanet\DedicatedServer\Xmlrpc\IndexOutOfBoundException;
12
use Maniaplanet\DedicatedServer\Xmlrpc\NextMapException;
13
14
/**
15
 * Class MapDataProvider provides information to plugins about what is going on with the maps on the server.
16
 *
17
 * @package eXpansion\Framework\Core\DataProviders
18
 */
19
class MapListDataProvider extends AbstractDataProvider implements StatusAwarePluginInterface
20
{
21
    /** Size of batch to get maps from the storage. */
22
    const BATCH_SIZE = 500;
23
24
    /**
25
     * @var MapStorage
26
     */
27
    protected $mapStorage;
28
29
    /**
30
     * @var Factory
31
     */
32
    protected $factory;
33
34
    /**
35
     * MapListDataProvider constructor.
36
     *
37
     * @param MapStorage $mapStorage
38
     * @param Factory $factory
39
     */
40
    public function __construct(MapStorage $mapStorage, Factory $factory)
41
    {
42
        $this->mapStorage = $mapStorage;
43
        $this->factory = $factory;
44
    }
45
46
    /**
47
     * @inheritdoc
48
     */
49
    public function setStatus($status)
50
    {
51
        if ($status) {
52
            $this->updateMapList();
53
            $currentMap = $this->factory->getConnection()->getCurrentMapInfo();
54
            if ($currentMap) {
55
                $this->mapStorage->setCurrentMap($currentMap);
56
                try {
57
                    $this->mapStorage->setNextMap($this->factory->getConnection()->getNextMapInfo());
58
                } catch (NextMapException $ex) {
59
                    $this->mapStorage->setNextMap($currentMap);
60
                }
61
            }
62
        }
63
    }
64
65
66
    /**
67
     * Update the list of maps in the storage.
68
     */
69
    protected function updateMapList()
70
    {
71
        $start = 0;
72
73
        do {
74
            try {
75
                $maps = $this->factory->getConnection()->getMapList(self::BATCH_SIZE, $start);
76
            } catch (IndexOutOfBoundException $e) {
77
                // This is normal error when we we are trying to find all maps and we are out of bounds.
78
                return;
79
            } catch (NextMapException $ex) {
80
                // this is if no maps defined
81
                return;
82
            }
83
84
            if (!empty($maps)) {
85
                foreach ($maps as $map) {
86
                    $this->mapStorage->addMap($map);
87
                }
88
            }
89
90
            $start += self::BATCH_SIZE;
91
92
        } while (count($maps) == self::BATCH_SIZE);
93
    }
94
95
    /**
96
     * Called when map list is modified.
97
     *
98
     * @param $curMapIndex
99
     * @param $nextMapIndex
100
     * @param $isListModified
101
     *
102
     */
103
    public function onMapListModified($curMapIndex, $nextMapIndex, $isListModified)
104
    {
105
        if ($isListModified) {
106
            $oldMaps = $this->mapStorage->getMaps();
107
108
            $this->mapStorage->resetMapData();
109
            $this->updateMapList();
110
111
            // We will dispatch even only when list is modified. If not we dispatch specific events.
112
            $this->dispatch(__FUNCTION__, [$oldMaps, $curMapIndex, $nextMapIndex, $isListModified]);
113
        }
114
115
        try {
116
            $currentMap = $this->factory->getConnection()->getCurrentMapInfo();  // sync better
117
        } catch (\Exception $e) {
118
            // fallback to use map storage
119
            $currentMap = $this->mapStorage->getMapByIndex($curMapIndex);
120
        }        // current map can be false if map by index is not found..
121
        if ($currentMap) {
122
            if ($this->mapStorage->getCurrentMap()->uId != $currentMap->uId) {
123
                $previousMap = $this->mapStorage->getCurrentMap();
124
                $this->mapStorage->setCurrentMap($currentMap);
125
126
                $this->dispatch('onExpansionMapChange', [$currentMap, $previousMap]);
127
            }
128
        }
129
130
        try {
131
            $nextMap = $this->factory->getConnection()->getNextMapInfo();  // sync better
132
        } catch (\Exception $e) {
133
            // fallback to use map storage
134
            $nextMap = $this->mapStorage->getMapByIndex($nextMapIndex);
135
        }
136
        // next map can be false if map by index is not found..
137
        if ($nextMap) {
138
            if ($this->mapStorage->getNextMap()->uId != $nextMap->uId) {
139
                $previousNextMap = $this->mapStorage->getNextMap();
140
                $this->mapStorage->setNextMap($nextMap);
141
142
                $this->dispatch('onExpansionNextMapChange', [$nextMap, $previousNextMap]);
143
            }
144
        }
145
    }
146
}
147