Completed
Pull Request — master (#329)
by De Cramer
03:46
created

DedimaniaService::processRecord()   C

Complexity

Conditions 12
Paths 9

Size

Total Lines 78
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 46
nc 9
nop 3
dl 0
loc 78
rs 5.1746
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: php_r
5
 * Date: 27.2.2018
6
 * Time: 10.06
7
 */
8
9
namespace eXpansionExperimantal\Bundle\Dedimania\Services;
10
11
12
use eXpansionExperimantal\Bundle\Dedimania\Classes\IXR_Base64;
13
use eXpansionExperimantal\Bundle\Dedimania\Structures\DedimaniaPlayer;
14
use eXpansionExperimantal\Bundle\Dedimania\Structures\DedimaniaRecord;
15
use eXpansion\Framework\Core\Services\Application\Dispatcher;
16
use eXpansion\Framework\Core\Storage\PlayerStorage;
17
18
class DedimaniaService
19
{
20
    /**
21
     * @var DedimaniaRecord[]
22
     */
23
    protected $dedimaniaRecords = [];
24
    protected $serverMaxRank = 15;
25
    /** @var DedimaniaPlayer[] */
26
    protected $players = [];
27
    /**
28
     * @var Dispatcher
29
     */
30
    private $dispatcher;
31
32
    /** @var DedimaniaRecord[] */
33
    private $recordsByLogin = [];
34
35
    /** @var int[] */
36
    private $ranksByLogin = [];
37
38
39
    private $VReplay = "";
40
    private $GReplay = "";
41
42
    /** @var PlayerStorage */
43
    private $playerStorage;
44
45
    /** @var string */
46
    private $GReplayOwner;
47
48
    private $disabled = false;
49
50
    /**
51
     * DedimaniaService constructor.
52
     * @param Dispatcher    $dispatcher
53
     * @param PlayerStorage $playerStorage
54
     */
55
    public function __construct(
56
        Dispatcher $dispatcher,
57
        PlayerStorage $playerStorage
58
    ) {
59
        $this->dispatcher = $dispatcher;
60
        $this->playerStorage = $playerStorage;
61
    }
62
63
    /**
64
     * @return DedimaniaRecord[]
65
     */
66
    public function getDedimaniaRecords(): array
67
    {
68
        return $this->recordsByLogin;
69
    }
70
71
    /**
72
     * @param DedimaniaRecord[] $dedimaniaRecords
73
     */
74
    public function setDedimaniaRecords($dedimaniaRecords)
75
    {
76
        $this->setDisabled(false);
77
        $this->recordsByLogin = [];
78
        $this->ranksByLogin = [];
79
        $records = [];
80
        foreach ($dedimaniaRecords as $record) {
81
            $this->recordsByLogin[$record->login] = $record;
82
            $this->ranksByLogin[$record->login] = intval($record->rank);
83
            $records[] = $record;
84
        }
85
86
        $this->dispatcher->dispatch('expansion.dedimania.records.load', [$records]);
87
    }
88
89
    public function getRecord($login)
90
    {
91
        if (isset($this->recordsByLogin[$login])) {
92
            return $this->recordsByLogin[$login];
93
        }
94
95
        return null;
96
    }
97
98
99
    /**
100
     * Check and Add a new record, if needed
101
     *
102
     * @param string $login
103
     * @param int    $score
104
     * @param int[]  $checkpoints
105
     *
106
     * @return DedimaniaRecord|false
107
     */
108
    public function processRecord($login, $score, $checkpoints)
109
    {
110
        if ($this->isDisabled()) {
111
            echo "disabled state.\n";
112
113
            return false;
114
        }
115
116
        $tempRecords = $this->recordsByLogin;
117
        $tempPositions = $this->ranksByLogin;
118
119
        if (isset($this->recordsByLogin[$login])) {
120
            $record = $this->recordsByLogin[$login];
121
        } else {
122
            $record = new DedimaniaRecord($login);
123
            $pla = $this->playerStorage->getPlayerInfo($login);
124
            $record->nickName = $pla->getNickName();
125
        }
126
127
        $tempRecords[$login] = clone $record;
128
        $oldRecord = clone $record;
129
130
        // if better time
131
        if ($score < $oldRecord->best || $oldRecord->best == -1) {
132
            $record->best = $score;
133
            $record->checks = implode(",", $checkpoints);
134
            $tempRecords[$login] = $record;
135
136
            // sort and update new rank
137
            uasort($tempRecords, [$this, "compare"]);
138
139
            if (!isset($this->players[$login])) {
140
                echo "player $login not connected\n";
141
142
                return false;
143
            }
144
145
            $player = $this->players[$login];
146
147
            // recalculate ranks for records
148
            $rank = 1;
149
            $newRecord = false;
150
            foreach ($tempRecords as $key => $tempRecord) {
151
                $tempRecords[$key]->rank = $rank;
152
                $tempPositions[$key] = $rank;
153
154
                if ($tempRecord->login == $login && ($rank <= $this->serverMaxRank || $rank <= $player->maxRank) && $rank < 100) {
155
                    $newRecord = $tempRecords[$login];
156
                }
157
158
                $rank++;
159
            }
160
161
162
            $tempRecords = array_slice($tempRecords, 0, 100, true);
163
            $tempPositions = array_slice($tempPositions, 0, 100, true);
164
165
            if ($newRecord) {
166
                $this->recordsByLogin = $tempRecords;
167
                $outRecords = usort($tempRecords, [$this, 'compare']);
168
169
                $this->ranksByLogin = $tempPositions;
0 ignored issues
show
Documentation Bug introduced by
It seems like $tempPositions of type array<integer|string,integer> is incompatible with the declared type array<integer,integer> of property $ranksByLogin.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
170
                $params = [
171
                    $newRecord,
172
                    $oldRecord,
173
                    $outRecords,
174
                    $newRecord->rank,
175
                    $oldRecord->rank,
176
                ];
177
178
                $this->dispatcher->dispatch("expansion.dedimania.records.update", [$params]);
179
180
                return $newRecord;
181
            }
182
        }
183
184
        return false;
185
    }
186
187
    /**
188
     * @param DedimaniaRecord $a
189
     * @param DedimaniaRecord $b
190
     * @return int
191
     */
192
    public function compare($a, $b)
193
    {
194
        if ($a->best == $b->best) {
195
            return 0;
196
        }
197
198
        return ($a->best > $b->best) ? 1 : -1;
199
    }
200
201
202
    /**
203
     * @return mixed
204
     */
205
    public function getServerMaxRank()
206
    {
207
        return $this->serverMaxRank;
208
    }
209
210
    /**
211
     * @param mixed $serverMaxRank
212
     */
213
    public function setServerMaxRank($serverMaxRank)
214
    {
215
        $this->serverMaxRank = $serverMaxRank;
216
    }
217
218
    /**
219
     * @return DedimaniaPlayer[]
220
     */
221
    public function getPlayers(): array
222
    {
223
        return $this->players;
224
    }
225
226
    /**
227
     * @param DedimaniaPlayer[] $players
228
     */
229
    public function setPlayers(array $players)
230
    {
231
        foreach ($players as $player) {
232
            $this->connectPlayer($player);
233
        }
234
    }
235
236
    /** @param DedimaniaPlayer $player */
237
    public function connectPlayer($player)
238
    {
239
        $this->players[$player->login] = $player;
240
        $this->dispatcher->dispatch("expansion.dedimania.player.connect", [$player]);
241
    }
242
243
    /**
244
     * @param $login
245
     */
246
    public function disconnectPlayer($login)
247
    {
248
        if (isset($this->players[$login])) {
249
            $this->dispatcher->dispatch("expansion.dedimania.player.disconnect", [clone $this->players[$login]]);
250
            unset($this->players[$login]);
251
        }
252
    }
253
254
255
    /**
256
     * @return string
257
     */
258
    public function getVReplay()
259
    {
260
        return $this->VReplay;
261
    }
262
263
    /**
264
     * @param string $VReplay
265
     */
266
    public function setVReplay($VReplay)
267
    {
268
        $this->VReplay = $VReplay;
269
    }
270
271
    /**
272
     * @return array
273
     */
274
    public function getGReplay()
275
    {
276
        return [$this->GReplayOwner, $this->GReplay];
277
    }
278
279
    /**
280
     * @param string     $login
281
     * @param IXR_Base64 $GReplay
282
     */
283
    public function setGReplay($login, $GReplay)
284
    {
285
        $this->GReplayOwner = $login;
286
        $this->GReplay = $GReplay;
0 ignored issues
show
Documentation Bug introduced by
It seems like $GReplay of type object<eXpansionExperima...nia\Classes\IXR_Base64> is incompatible with the declared type string of property $GReplay.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
287
    }
288
289
    /**
290
     * @return string|false
291
     */
292
    public function isDisabled()
293
    {
294
        return $this->disabled;
295
    }
296
297
    /**
298
     * @param string|false $disabled
299
     */
300
    public function setDisabled($disabled)
301
    {
302
        $this->disabled = $disabled;
0 ignored issues
show
Documentation Bug introduced by
It seems like $disabled can also be of type string. However, the property $disabled is declared as type boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
303
    }
304
305
306
}