ManiaExchange::onApplicationStop()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace eXpansion\Bundle\Maps\Plugins;
4
5
use eXpansion\Bundle\Maps\Model\Map;
6
use eXpansion\Bundle\Maps\Model\MapQuery;
7
use eXpansion\Bundle\Maps\Model\Mxmap;
8
use eXpansion\Bundle\Maps\Model\MxmapQuery;
9
use eXpansion\Bundle\Maps\Services\JukeboxService;
10
use eXpansion\Bundle\Maps\Structure\MxInfo;
11
use eXpansion\Framework\AdminGroups\Helpers\AdminGroups;
12
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpApplication;
13
use eXpansion\Framework\Core\Helpers\ChatNotification;
14
use eXpansion\Framework\Core\Helpers\FileSystem;
15
use eXpansion\Framework\Core\Helpers\Http;
16
use eXpansion\Framework\Core\Helpers\Structures\HttpResult;
17
use eXpansion\Framework\Core\Helpers\TMString;
18
use eXpansion\Framework\Core\Services\Console;
19
use eXpansion\Framework\Core\Services\DedicatedConnection\Factory;
20
use eXpansion\Framework\Core\Storage\GameDataStorage;
21
use Maniaplanet\DedicatedServer\Structures\Map as DedicatedMap;
22
use Propel\Runtime\Map\TableMap;
23
use Psr\Log\LoggerInterface;
24
25
class ManiaExchange implements ListenerInterfaceExpApplication
26
{
27
    const SITE_TM = "TM";
28
    const SITE_SM = "SM";
29
30
    /** @var bool */
31
    private $downloadProgressing = false;
32
33
    /**
34
     * @var Factory
35
     */
36
    private $factory;
37
    /**
38
     * @var ChatNotification
39
     */
40
    private $chatNotification;
41
42
    /**
43
     * @var Http
44
     */
45
    private $http;
46
47
    /**
48
     * @var AdminGroups
49
     */
50
    private $adminGroups;
51
52
    /**
53
     * @var GameDataStorage
54
     */
55
    private $gameDataStorage;
56
57
    /**
58
     * @var Console
59
     */
60
    private $console;
61
62
    /**
63
     * @var LoggerInterface
64
     */
65
    private $logger;
66
67
    /**
68
     * @var JukeboxService
69
     */
70
    private $jukebox;
71
72
    /**
73
     * @var FileSystem
74
     */
75
    protected $fileSystem;
76
77
78
    protected $addQueue = [];
79
80
    /**
81
     * ManiaExchange constructor.
82
     *
83
     * @param Factory          $factory
84
     * @param ChatNotification $chatNotification
85
     * @param Http             $http
86
     * @param AdminGroups      $adminGroups
87
     * @param GameDataStorage  $gameDataStorage
88
     * @param Console          $console
89
     * @param LoggerInterface  $logger
90
     * @param JukeboxService   $jukebox
91
     * @param FileSystem       $fileSystem
92
     */
93 View Code Duplication
    public function __construct(
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...
94
        Factory $factory,
95
        ChatNotification $chatNotification,
96
        Http $http,
97
        AdminGroups $adminGroups,
98
        GameDataStorage $gameDataStorage,
99
        Console $console,
100
        LoggerInterface $logger,
0 ignored issues
show
Unused Code introduced by
The parameter $logger is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
101
        JukeboxService $jukebox,
102
        FileSystem $fileSystem
103
    ) {
104
        $this->factory = $factory;
105
        $this->chatNotification = $chatNotification;
106
        $this->http = $http;
107
        $this->adminGroups = $adminGroups;
108
        $this->gameDataStorage = $gameDataStorage;
109
        $this->console = $console;
110
        $this->jukebox = $jukebox;
111
        $this->fileSystem = $fileSystem;
112
    }
113
114
    /** @var Mxmap[] $maps */
115
    public function addAllMaps($login, $maps)
116
    {
117
        if (!$this->adminGroups->hasPermission($login, "maps.add")) {
118
            $this->chatNotification->sendMessage('expansion_mx.chat.nopermission', $login);
119
120
            return;
121
        }
122
123
        $this->addQueue = $maps;
124
        $this->chatNotification->sendMessage("expansion_mx.chat.downloadstart", null, ["%lenght%" => count($this->addQueue)]);
125
        $map = array_shift($this->addQueue);
126
        $this->addMap($login, $map['mxid'], $map['mxsite']);
127
    }
128
129
    /**
130
     * add map to queue
131
     * @param string  $login
132
     * @param integer $id
133
     * @param string  $mxsite "TM" or "SM"
134
     */
135
    public function addMapToQueue($login, $id, $mxsite)
136
    {
137
138
        if (!$this->adminGroups->hasPermission($login, "maps.add")) {
139
            $this->chatNotification->sendMessage('expansion_mx.chat.nopermission', $login);
140
141
            return;
142
        }
143
144
        if ($this->downloadProgressing || count($this->addQueue) > 1) {
145
146
            $this->addQueue[] = ['mxid' => $id, 'mxsite' => $mxsite];
147
            $this->chatNotification->sendMessage("|info| Adding map to download queue...", $login);
148
149
            return;
150
        } else {
151
            $this->addMap($login, $id, $mxsite);
152
        }
153
154
    }
155
156
    /**
157
     * @param $login
158
     * @param $id
159
     * @param $mxsite
160
     */
161
    public function addMap($login, $id, $mxsite)
162
    {
163
164
        $options = [
165
            CURLOPT_HTTPHEADER => [
166
                "Content-Type" => "application/json",
167
                "X-ManiaPlanet-ServerLogin" => $this->gameDataStorage->getSystemInfo()->serverLogin,
168
            ],
169
        ];
170
171
        if (!$mxsite) {
172
            $mxsite = $this->gameDataStorage->getTitleGame();
173
        }
174
175
        $group = $this->adminGroups->getLoginUserGroups($login);
176
177
        $this->chatNotification->sendMessage(
178
            'expansion_mx.chat.start',
179
            $group,
180
            ["%id%" => $id, "%site%" => $mxsite]
181
        );
182
        $this->downloadProgressing = true;
183
        $this->http->get("https://api.mania-exchange.com/".strtolower($mxsite)."/maps?ids=".$id,
184
            [$this, 'callbackAddMap1'],
185
            ['login' => $login, 'site' => $mxsite, 'mxId' => $id], $options);
186
187
    }
188
189
190
    public function callbackAddMap1(HttpResult $result)
191
    {
192
        $additionalData = $result->getAdditionalData();
193
        $group = $this->adminGroups->getLoginUserGroups($additionalData['login']);
194
195
        $json = json_decode($result->getResponse(), true);
196
197
        if (isset($json['StatusCode'])) {
198
            $this->chatNotification->sendMessage(
199
                'expansion_mx.chat.apierror',
200
                $group,
201
                ["%status%" => $json['StatusCode'], "%message%" => $json['Message']]
202
            );
203
            $this->downloadProgressing = false;
204
205
            return;
206
        }
207
        if (!isset($json[0])) {
208
            $this->chatNotification->sendMessage(
209
                'expansion_mx.chat.json',
210
                $group,
211
                ["%message%" => "Can't find info structure."]
212
            );
213
214
            return;
215
        }
216
217
        $mxInfo = new MxInfo($json[0]);
218
        $additionalData['mxInfo'] = $mxInfo;
219
220
        if (!$result->hasError()) {
221
            $options = [
222
                CURLOPT_FOLLOWLOCATION => false,
223
                CURLOPT_HTTPHEADER => [
224
                    "Content-Type" => "application/json",
225
                    "X-ManiaPlanet-ServerLogin" => $this->gameDataStorage->getSystemInfo()->serverLogin,
226
                ],
227
            ];
228
229
            $this->http->get("https://".strtolower($additionalData['site']).
230
                ".mania-exchange.com/tracks/download/".$additionalData['mxId'],
231
                [$this, 'callbackAddMap2'],
232
                $additionalData, $options);
233
        } else {
234
            $this->chatNotification->sendMessage(
235
                'expansion_mx.chat.httperror',
236
                $group,
237
                ["%status%" => $result->getHttpCode(), "%message%" => $result->getError()]
238
            );
239
        }
240
    }
241
242
    public function callbackAddMap2(HttpResult $result)
243
    {
244
        $data = $result->getAdditionalData();
245
        $group = $this->adminGroups->getLoginUserGroups($data['login']);
246
247
        if ($result->hasError()) {
248
249
            if ($result->getHttpCode() == 302) {
250
                $this->chatNotification->sendMessage(
251
                    'expansion_mx.chat.decline',
252
                    $group,
253
                    []
254
                );
255
                $this->downloadProgressing = false;
256
257
                return;
258
            }
259
260
            $this->chatNotification->sendMessage(
261
                'expansion_mx.chat.httperror',
262
                $group,
263
                ["%status%" => $result->getHttpCode(), "%message%" => $result->getError()]
264
            );
265
266
            $this->downloadProgressing = false;
267
268
            return;
269
        }
270
271
        /** @var MxInfo $info */
272
        $info = $data['mxInfo'];
273
274
        $authorName = $this->cleanString($info->username);
275
        $mapName = $this->cleanString(
276
            trim(
277
                mb_convert_encoding(
278
                    substr(TMString::trimStyles($info->gbxMapName), 0, 20),
279
                    "7bit",
280
                    "UTF-8"
281
                )
282
            )
283
        );
284
285
        $filename = $data['mxId']."-".$authorName."-".$mapName.".Map.Gbx";
286
287
        try {
288
            $titlepack = $this->gameDataStorage->getSystemInfo()->titleId;
289
            $fileSystem = $this->fileSystem->getUserData();
290
            $dir = 'Maps'.DIRECTORY_SEPARATOR.$titlepack;
291
            $file = $dir.DIRECTORY_SEPARATOR.$filename;
292
293
            if (!$fileSystem->createDir($dir)) {
294
                $this->console->writeln('<error>Error while adding map, can\'t create folder!</error>');
295
296
                return;
297
            }
298
299
            if (!$fileSystem->has($file)) {
300
                $fileSystem->write($file, $result->getResponse());
301
            }
302
303
            if (!$this->factory->getConnection()->checkMapForCurrentServerParams($titlepack.DIRECTORY_SEPARATOR.$filename)) {
304
                $this->chatNotification->sendMessage("expansion_mx.chat.fail");
305
306
                return;
307
            }
308
309
            $map = $this->factory->getConnection()->getMapInfo($titlepack.DIRECTORY_SEPARATOR.$filename);
310
            $this->factory->getConnection()->addMap($map->fileName);
311
312
            $this->jukebox->addMap($map, $data['login']);
313
            $this->chatNotification->sendMessage(
314
                'expansion_mx.chat.success',
315
                null,
316
                [
317
                    "%mxid%" => $data['mxId'],
318
                    "%mapauthor%" => $map->author,
319
                    "%mapname%" => TMString::trimControls($map->name),
320
                ]
321
            );
322
323
            $this->persistMapData($map, $info);
324
            $this->downloadProgressing = false;
325
        } catch (\Exception $e) {
326
            $this->chatNotification->sendMessage(
327
                'expansion_mx.chat.dedicatedexception',
328
                $group, ["%message%" => $e->getMessage()]
329
            );
330
            //  $this->logger->alert("Error while adding map : ".$e->getMessage(), ['exception' => $e]);
331
            $this->downloadProgressing = false;
332
        }
333
334
        if (count($this->addQueue) > 0) {
335
            $map = array_shift($this->addQueue);
336
            $this->chatNotification->sendMessage("expansion_mx.chat.queue", null,
337
                ["%length%" => count($this->addQueue)]);
338
            $this->addMap($data['login'], $map['mxid'], $map['mxsite']);
339
        }
340
    }
341
342
    /**
343
     * @param DedicatedMap $map
344
     * @param MxInfo       $mxInfo
345
     * @throws \Propel\Runtime\Exception\PropelException
346
     */
347
    protected function persistMapData($map, $mxInfo)
348
    {
349
350
        $mapquery = new MapQuery();
351
        $dbMap = $mapquery->findOneByMapuid($map->uId);
352
353
        if ($dbMap) {
354
            $dbMap->fromArray($this->convertMap($map), TableMap::TYPE_FIELDNAME);
355
        } else {
356
            $dbMap = new Map();
357
            $dbMap->fromArray($this->convertMap($map), TableMap::TYPE_FIELDNAME);
358
        }
359
360
        $mxquery = new MxmapQuery();
361
        $mxMap = $mxquery->findOneByTrackuid($map->uId);
362
363
        if ($mxMap) {
364
            $mxMap->fromArray($mxInfo->toArray(), TableMap::TYPE_FIELDNAME);
365
        } else {
366
            $mxMap = new Mxmap();
367
            $mxMap->fromArray($mxInfo->toArray(), TableMap::TYPE_FIELDNAME);
368
        }
369
        $dbMap->addMxmap($mxMap);
370
        $dbMap->save();
371
        $mxMap->save();
372
    }
373
374
    /**
375
     * @param DedicatedMap $map
376
     * @return array
377
     */
378
    private function convertMap($map)
379
    {
380
        $outMap = (array)$map;
381
        $outMap["mapUid"] = $map->uId;
382
383
        return $outMap;
384
385
    }
386
387
    /**
388
     * Remove special characters from map name
389
     *
390
     * @param string $string
391
     * @return mixed
392
     */
393
    protected function cleanString($string)
394
    {
395
        return str_replace(array("/", "\\", ":", ".", "?", "*", '"', "|", "<", ">", "'"), "", $string);
396
    }
397
398
399
    /**
400
     * called at eXpansion init
401
     *
402
     * @return void
403
     */
404
    public function onApplicationInit()
405
    {
406
        // Nothin here.
407
    }
408
409
    /**
410
     * called when init is done and callbacks are enabled
411
     *
412
     * @return void
413
     */
414
    public function onApplicationReady()
415
    {
416
        // Nothin here.
417
    }
418
419
    /**
420
     * called when requesting application stop
421
     *
422
     * @return void
423
     */
424
    public function onApplicationStop()
425
    {
426
        // Nothin here.
427
    }
428
}
429