Completed
Pull Request — master (#280)
by
unknown
03:35
created

MxKarmaService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 7
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 11
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->getTitle(),
222
            "mapuid" => $this->mapStorage->getCurrentMap()->uId,
223
            "getvotesonly" => $getVotesOnly,
224
            "playerlogins" => $players,
225
        ];
226
        $this->http->post(
227
            $this->buildUrl("getMapRating", $params),
228
            json_encode($postData),
229
            array($this, "xGetRatings"),
230
            [],
231
            $this->options
232
        );
233
    }
234
235
    /**
236
     * @param Map      $map
237
     * @param int      $time time in seconds from BeginMap to EndMap
238
     * @param MxVote[] $votes
239
     */
240
    public function saveVotes(Map $map, $time, $votes)
241
    {
242
        if (!$this->connected) {
243
            $this->console->writeln('> MxKarma not connected, aborting save votes');
244
245
            return;
246
        }
247
248
        $params = array("sessionKey" => $this->sessionKey);
249
        $postData = array(
250
            "gamemode" => $this->getGameMode(),
251
            "titleid" => $this->gameDataStorage->getTitle(),
252
            "mapuid" => $map->uId,
253
            "mapname" => $map->name,
254
            "mapauthor" => $map->author,
255
            "isimport" => false,
256
            "maptime" => $time,
257
            "votes" => $votes,
258
        );
259
260
261
        $this->console->writeln('> MxKarma attempting to save votes...');
262
        $this->http->post(
263
            $this->buildUrl("saveVotes", $params),
264
            json_encode($postData),
265
            [$this, "xSaveVotes"],
266
            [],
267
            $this->options
268
        );
269
    }
270
271
    /**
272
     * @param HttpResult $result
273
     */
274 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...
275
    {
276
277
        if ($result->hasError()) {
278
            $this->console->writeln('> MxKarma save votes failure: $f00'.$result->getError());
279
280
            return;
281
        }
282
283
        $data = $this->getObject($result->getResponse());
284
285
        if ($data === null) {
286
            return;
287
        }
288
        $this->console->writeln('> MxKarma save votes $0f0success!');
289
        $this->dispatcher->dispatch(self::EVENT_VOTESAVE, ["updated" => $data->updated]);
290
    }
291
292
    /**
293
     * @param HttpResult $result
294
     * @return MxRating|null
295
     */
296
    public function xGetRatings(HttpResult $result)
297
    {
298
299
        if ($result->hasError()) {
300
            $this->console->writeln('> MxKarma load votes failure: $f00'.$result->getError());
301
302
            return null;
303
        }
304
305
        $data = $this->getObject($result->getResponse());
306
307
        if ($data === null) {
308
          return null;
309
        }
310
        try {
311
            $this->ratings = new MXRating();
312
            $this->ratings->append($data);
313
314
            $this->console->writeln('> MxKarma load $0f0success!');
315
            $this->dispatcher->dispatch(self::EVENT_VOTELOAD, ["ratings" => $this->ratings]);
316
317
            return $this->ratings;
318
        } catch (\Exception $ex) {
319
            return null;
320
        }
321
322
    }
323
324
    /**
325
     * @return string
326
     */
327
    public function getGameMode()
328
    {
329
        $gamemode = "";
330
        switch ($this->gameDataStorage->getGameInfos()->gameMode) {
331
            case GameInfos::GAMEMODE_SCRIPT:
332
                $gamemode = strtolower($this->gameDataStorage->getGameInfos()->scriptName);
333
                break;
334
            case GameInfos::GAMEMODE_ROUNDS:
335
                $gamemode = "Rounds";
336
                break;
337
            case GameInfos::GAMEMODE_CUP:
338
                $gamemode = "Cup";
339
                break;
340
            case GameInfos::GAMEMODE_TEAM:
341
                $gamemode = "Team";
342
                break;
343
            case GameInfos::GAMEMODE_LAPS:
344
                $gamemode = "Laps";
345
                break;
346
            case GameInfos::GAMEMODE_TIMEATTACK:
347
                $gamemode = "TimeAttack";
348
                break;
349
        }
350
351
        return $gamemode;
352
    }
353
354
    /**
355
     * @param string $data json data
356
     *
357
     * @return object|null
358
     */
359
    public function getObject($data)
360
    {
361
        $obj = (object)json_decode($data);
362
363
        if ($obj->success === false) {
364
            $this->handleErrors($obj);
365
366
            return null;
367
        }
368
369
        return $obj->data;
370
    }
371
372
    /**
373
     * @param object $obj
374
     */
375
    public function handleErrors($obj)
376
    {
377
        switch ($obj->data->code) {
378
            case 1:
379
                $this->console->writeln('> MxKarma $fffinternal server error');
380
                break;
381
            case 2:
382
                $this->console->writeln('> MxKarma $fffSession key is invalid (not activated, expired or got disabled).');
383
                break;
384
            case 3:
385
                $this->console->writeln('> MxKarma $fffSome parameters are not provided.');
386
                break;
387
            case 4:
388
                $this->console->writeln('> MxKarma $fffAPI key not found or suspended.');
389
                $this->disconnect();
390
                break;
391
            case 5:
392
                $this->console->writeln('> MxKarma $fffServer not found or suspended.');
393
                $this->disconnect();
394
                break;
395
            case 6:
396
                $this->console->writeln('> MxKarma $fffServer is banned.');
397
                $this->disconnect();
398
                break;
399
            case 7:
400
                $this->console->writeln('> MxKarma $fffCross-server call rejected.');
401
                break;
402
            case 8:
403
                $this->console->writeln('> MxKarma $fffInvalid activation hash provided, session closed.');
404
                $this->disconnect();
405
                break;
406
            case 9:
407
                $this->console->writeln('> MxKarma $fffSession already active.');
408
                $this->disconnect();
409
                break;
410
            case 10:
411
                $this->console->writeln('> MxKarma $fffUnsupported Content-Type.');
412
                break;
413
            case 11:
414
                $this->console->writeln('> MxKarma $fffToo many logins requested.');
415
                break;
416
            case 12:
417
                $this->console->writeln('> MxKarma $fffInvalid JSON or invalid structure.');
418
                break;
419
            case 13:
420
                $this->console->writeln('> MxKarma $fffMalformed vote request.');
421
                break;
422
            case 14:
423
                $this->console->writeln('> MxKarma $fffno votes cast - please do not make requests if there are no votes!');
424
                break;
425
            case 15:
426
                $this->console->writeln('> MxKarma $ffftoo many import votes - request a limit raise if needed');
427
                break;
428
            case 16:
429
                $this->console->writeln('> MxKarma $fffImport rejected.');
430
                break;
431
            default:
432
                $this->console->writeln('> MxKarma $fffUnknown api error');
433
                break;
434
        }
435
436
        //   Dispatcher::dispatch(new MXKarmaEvent(MXKarmaEvent::ON_ERROR, $origin, $obj->data->code, $obj->data->message));
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
437
    }
438
439
    /**
440
     * @param string $method
441
     * @param array  $params
442
     *
443
     * @return string
444
     */
445
    private function buildUrl($method, $params)
446
    {
447
        $url = $this->address.$method;
448
        return $url."?".http_build_query($params);
449
    }
450
451
    /**
452
     * @return bool
453
     */
454
    public function isConnected()
455
    {
456
        return $this->connected;
457
    }
458
459
    /**
460
     *
461
     */
462
    public function disconnect()
463
    {
464
        $this->connected = false;
465
        $this->console->writeln('> MxKarma $f00disconnected!');
466
        $this->dispatcher->dispatch(self::EVENT_DISCONNECT, []);
467
    }
468
469
}
470