MxKarmaService::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 13
cp 0
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 5
crap 2
1
<?php
2
3
/*
4
 * Copyright (C) 2014 Reaby
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
namespace eXpansion\Bundle\MxKarma\Services;
21
22
use eXpansion\Bundle\MxKarma\Entity\MxRating;
23
use eXpansion\Bundle\MxKarma\Entity\MxVote;
24
use eXpansion\Framework\Core\Helpers\Http;
25
use eXpansion\Framework\Core\Helpers\Structures\HttpResult;
26
use eXpansion\Framework\Core\Services\Application\AbstractApplication;
27
use eXpansion\Framework\Core\Services\Application\Dispatcher;
28
use eXpansion\Framework\Core\Services\Console;
29
use eXpansion\Framework\Core\Storage\GameDataStorage;
30
use eXpansion\Framework\Core\Storage\MapStorage;
31
use Maniaplanet\DedicatedServer\Structures\GameInfos;
32
use Maniaplanet\DedicatedServer\Structures\Map;
33
34
/**
35
 * Description of Connection
36
 *
37
 * @author Reaby
38
 */
39
class MxKarmaService
40
{
41
42
    const EVENT_CONNECT = "expansion.mxkarma.connect";
43
    const EVENT_VOTESAVE = "expansion.mxkarma.votesave";
44
    const EVENT_VOTELOAD = 'expansion.mxkarma.voteload';
45
    const EVENT_DISCONNECT = 'expansion.mxkarma.disconnect';
46
47
    private $address = "http://karma.mania-exchange.com/api2/";
48
    private $options = [CURLOPT_HTTPHEADER => ["Content-Type:application/json"]];
49
50
    private $connected = false;
51
52
    private $sessionKey = null;
53
54
    private $sessionSeed = null;
55
56
    /** @var MxRating */
57
    private $ratings = null;
58
    /**
59
     * @var Dispatcher
60
     */
61
    private $dispatcher;
62
    /**
63
     * @var GameDataStorage
64
     */
65
    private $gameDataStorage;
66
    /**
67
     * @var MapStorage
68
     */
69
    private $mapStorage;
70
    /**
71
     * @var Console
72
     */
73
    private $console;
74
75
    /** @var Http */
76
    private $http;
77
    /**
78
     * @var string
79
     */
80
    private $apiKey;
81
    /**
82
     * @var string
83
     */
84
    private $serverLogin;
85
86
    /**
87
     * Connection constructor.
88
     *
89
     * @param Dispatcher      $dispatcher
90
     * @param Http            $http
91
     * @param GameDataStorage $gameDataStorage
92
     * @param MapStorage      $mapStorage
93
     * @param Console         $console
94
     */
95
    public function __construct(
96
        Dispatcher $dispatcher,
97
        Http $http,
98
        GameDataStorage $gameDataStorage,
99
        MapStorage $mapStorage,
100
        Console $console
101
    ) {
102
        $this->dispatcher = $dispatcher;
103
        $this->http = $http;
104
        $this->gameDataStorage = $gameDataStorage;
105
        $this->mapStorage = $mapStorage;
106
        $this->console = $console;
107
    }
108
109
110
    /**
111
     * connect to MX karma
112
     *
113
     * @param string $serverLogin
114
     * @param string $apikey
115
     * @return  void
116
     */
117
    public function connect($serverLogin, $apikey)
118
    {
119
        $this->apiKey = $apikey;
120
        $this->serverLogin = $serverLogin;
121
122
        if (empty($this->apiKey)) {
123
            $this->console->writeln('MxKarma error: You need to define a api key');
124
125
            return;
126
        }
127
128
        if (empty($this->serverLogin)) {
129
            $this->console->writeln('MxKarma error: You need to define server login');
130
131
            return;
132
        }
133
134
        $params = [
135
            "serverLogin" => $serverLogin,
136
            "applicationIdentifier" => "eXpansion v ".AbstractApplication::EXPANSION_VERSION,
137
            "testMode" => "false",
138
        ];
139
140
        $this->console->writeln('> MxKarma attempting to connect...');
141
        $this->http->get(
142
            $this->buildUrl(
143
                "startSession", $params),
144
            [$this, "xConnect"]
145
        );
146
    }
147
148
    /**
149
     * @param HttpResult $result
150
     */
151
    public function xConnect(HttpResult $result)
152
    {
153
154
        if ($result->hasError()) {
155
            $this->console->writeln('> MxKarma connection failure: $f00'.$result->getError());
156
            $this->disconnect();
157
158
            return;
159
        }
160
161
        $data = $this->getObject($result->getResponse());
162
163
        if ($data === null) {
164
            return;
165
        }
166
167
        $this->sessionKey = $data->sessionKey;
168
        $this->sessionSeed = $data->sessionSeed;
169
170
        $outHash = hash("sha512", ($this->apiKey.$this->sessionSeed));
171
172
        $params = array("sessionKey" => $this->sessionKey, "activationHash" => $outHash);
173
        $this->console->writeln('> MxKarma attempting to activate session...');
174
        $this->http->get(
175
            $this->buildUrl("activateSession", $params),
176
            [$this, "xActivate"],
177
            [],
178
            $this->options
179
        );
180
    }
181
182 View Code Duplication
    public function xActivate(HttpResult $result)
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...
183
    {
184
185
        if ($result->hasError()) {
186
            $this->console->writeln('> MxKarma activation failure: $f00'.$result->getError());
187
188
            return;
189
        }
190
191
        $data = $this->getObject($result->getResponse());
192
193
        if ($data === null) {
194
            return;
195
        }
196
197
        if ($data->activated) {
198
            $this->connected = true;
199
            $this->console->writeln('> MxKarma connection $0f0success!');
200
            $this->dispatcher->dispatch(self::EVENT_CONNECT, []);
201
        }
202
    }
203
204
    /**
205
     * loads votes from server
206
     * @param array $players
207
     * @param bool  $getVotesOnly
208
     */
209
    public function loadVotes($players = array(), $getVotesOnly = false)
210
    {
211
        if (!$this->connected) {
212
            $this->console->writeln('> MxKarma trying to load votes when not connected: $ff0aborting!');
213
214
            return;
215
        }
216
217
        $this->console->writeln('> MxKarma attempting to load votes...');
218
        $params = array("sessionKey" => $this->sessionKey);
219
        $postData = [
220
            "gamemode" => $this->getGameMode(),
221
            "titleid" => $this->gameDataStorage->getVersion()->titleId,
222
            "mapuid" => $this->mapStorage->getCurrentMap()->uId,
223
            "getvotesonly" => $getVotesOnly,
224
            "playerlogins" => $players,
225
        ];
226
227
        $this->http->post(
228
            $this->buildUrl("getMapRating", $params),
229
            json_encode($postData),
230
            array($this, "xGetRatings"),
231
            [],
232
            $this->options
233
        );
234
    }
235
236
    /**
237
     * @param Map      $map
238
     * @param int      $time time in seconds from BeginMap to EndMap
239
     * @param MxVote[] $votes
240
     */
241
    public function saveVotes(Map $map, $time, $votes)
242
    {
243
        if (!$this->connected) {
244
            $this->console->writeln('> MxKarma not connected, aborting save votes');
245
246
            return;
247
        }
248
249
        $params = array("sessionKey" => $this->sessionKey);
250
251
        $postData = array(
252
            "gamemode" => $this->getGameMode(),
253
            "titleid" => $this->gameDataStorage->getVersion()->titleId,
254
            "mapuid" => $map->uId,
255
            "mapname" => $map->name,
256
            "mapauthor" => $map->author,
257
            "isimport" => false,
258
            "maptime" => $time,
259
            "votes" => $votes,
260
        );
261
262
        $this->console->writeln('> MxKarma attempting to save votes...');
263
        $this->http->post(
264
            $this->buildUrl("saveVotes", $params),
265
            json_encode($postData),
266
            [$this, "xSaveVotes"],
267
            [],
268
            $this->options
269
        );
270
    }
271
272
    /**
273
     * @param HttpResult $result
274
     */
275 View Code Duplication
    public function xSaveVotes(HttpResult $result)
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...
276
    {
277
278
        if ($result->hasError()) {
279
            $this->console->writeln('> MxKarma save votes failure: $f00'.$result->getError());
280
281
            return;
282
        }
283
284
        $data = $this->getObject($result->getResponse());
285
286
        if ($data === null) {
287
            return;
288
        }
289
        $this->console->writeln('> MxKarma save votes $0f0success!');
290
        $this->dispatcher->dispatch(self::EVENT_VOTESAVE, ["updated" => $data->updated]);
291
    }
292
293
    /**
294
     * @param HttpResult $result
295
     * @return MxRating|null
296
     */
297
    public function xGetRatings(HttpResult $result)
298
    {
299
300
        if ($result->hasError()) {
301
            $this->console->writeln('> MxKarma load votes failure: $f00'.$result->getError());
302
303
            return null;
304
        }
305
306
        $data = $this->getObject($result->getResponse());
307
308
        if ($data === null) {
309
            return null;
310
        }
311
        try {
312
            $this->ratings = new MXRating();
313
            $this->ratings->append($data);
314
315
            $this->console->writeln('> MxKarma load $0f0success!');
316
            $this->dispatcher->dispatch(self::EVENT_VOTELOAD, ["ratings" => $this->ratings]);
317
318
            return $this->ratings;
319
        } catch (\Exception $ex) {
320
            return null;
321
        }
322
323
    }
324
325
    /**
326
     * @return string
327
     */
328
    public function getGameMode()
329
    {
330
        $gamemode = "";
331
        switch ($this->gameDataStorage->getGameInfos()->gameMode) {
332
            case GameInfos::GAMEMODE_SCRIPT:
333
                $gamemode = strtolower($this->gameDataStorage->getGameInfos()->scriptName);
334
                break;
335
            case GameInfos::GAMEMODE_ROUNDS:
336
                $gamemode = "Rounds";
337
                break;
338
            case GameInfos::GAMEMODE_CUP:
339
                $gamemode = "Cup";
340
                break;
341
            case GameInfos::GAMEMODE_TEAM:
342
                $gamemode = "Team";
343
                break;
344
            case GameInfos::GAMEMODE_LAPS:
345
                $gamemode = "Laps";
346
                break;
347
            case GameInfos::GAMEMODE_TIMEATTACK:
348
                $gamemode = "TimeAttack";
349
                break;
350
        }
351
352
        return $gamemode;
353
    }
354
355
    /**
356
     * @param string $data json data
357
     *
358
     * @return object|null
359
     */
360
    public function getObject($data)
361
    {
362
        $obj = (object)json_decode($data);
363
364
        if ($obj->success === false) {
365
            $this->handleErrors($obj);
366
367
            return null;
368
        }
369
370
        return $obj->data;
371
    }
372
373
    /**
374
     * @param object $obj
375
     */
376
    public function handleErrors($obj)
377
    {
378
        switch ($obj->data->code) {
379
            case 1:
380
                $this->console->writeln('> MxKarma $fffinternal server error');
381
                break;
382
            case 2:
383
                $this->console->writeln('> MxKarma $fffSession key is invalid (not activated, expired or got disabled).');
384
                break;
385
            case 3:
386
                $this->console->writeln('> MxKarma $fffSome parameters are not provided.');
387
                break;
388
            case 4:
389
                $this->console->writeln('> MxKarma $fffAPI key not found or suspended.');
390
                $this->disconnect();
391
                break;
392
            case 5:
393
                $this->console->writeln('> MxKarma $fffServer not found or suspended.');
394
                $this->disconnect();
395
                break;
396
            case 6:
397
                $this->console->writeln('> MxKarma $fffServer is banned.');
398
                $this->disconnect();
399
                break;
400
            case 7:
401
                $this->console->writeln('> MxKarma $fffCross-server call rejected.');
402
                break;
403
            case 8:
404
                $this->console->writeln('> MxKarma $fffInvalid activation hash provided, session closed.');
405
                $this->disconnect();
406
                break;
407
            case 9:
408
                $this->console->writeln('> MxKarma $fffSession already active.');
409
                $this->disconnect();
410
                break;
411
            case 10:
412
                $this->console->writeln('> MxKarma $fffUnsupported Content-Type.');
413
                break;
414
            case 11:
415
                $this->console->writeln('> MxKarma $fffToo many logins requested.');
416
                break;
417
            case 12:
418
                $this->console->writeln('> MxKarma $fffInvalid JSON or invalid structure.');
419
                break;
420
            case 13:
421
                $this->console->writeln('> MxKarma $fffMalformed vote request.');
422
                break;
423
            case 14:
424
                $this->console->writeln('> MxKarma $fffno votes cast - please do not make requests if there are no votes!');
425
                break;
426
            case 15:
427
                $this->console->writeln('> MxKarma $ffftoo many import votes - request a limit raise if needed');
428
                break;
429
            case 16:
430
                $this->console->writeln('> MxKarma $fffImport rejected.');
431
                break;
432
            default:
433
                $this->console->writeln('> MxKarma $fffUnknown api error');
434
                break;
435
        }
436
437
        //   Dispatcher::dispatch(new MXKarmaEvent(MXKarmaEvent::ON_ERROR, $origin, $obj->data->code, $obj->data->message));
438
    }
439
440
    /**
441
     * @param string $method
442
     * @param array  $params
443
     *
444
     * @return string
445
     */
446
    private function buildUrl($method, $params)
447
    {
448
        $url = $this->address.$method;
449
450
        return $url."?".http_build_query($params);
451
    }
452
453
    /**
454
     * @return bool
455
     */
456
    public function isConnected()
457
    {
458
        return $this->connected;
459
    }
460
461
    /**
462
     *
463
     */
464
    public function disconnect()
465
    {
466
        $this->connected = false;
467
        $this->console->writeln('> MxKarma $f00disconnected!');
468
        $this->dispatcher->dispatch(self::EVENT_DISCONNECT, []);
469
    }
470
471
}
472