Player::getBlack_market()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * @property integer $uid
4
 * @property string $user
5
 * @property string $registered
6
 * @property integer $level
7
 * @property integer $status_points
8
 * @property integer $energy
9
 * @property integer $energy_max
10
 * @property integer $energy_missing
11
 * @property integer $energyRequiredForDuel
12
 * @property integer $skill
13
 * @property integer $strength
14
 * @property integer $dollar
15
 * @property integer $gold
16
 * @property integer $xp_all
17
 * @property integer $xp_delta
18
 * @property integer $xp_remaining
19
 * @property integer $last_location
20
 * @property integer $owned_items
21
 * @property integer $owned_baits
22
 * @property string $found_setitem_time
23
 * @property integer $found_setitem_xp
24
 * @property integer $tutorial_mission
25
 * @property integer $in_club
26
 * @property integer $level_percent
27
 * @property integer $refillPerInterval
28
 * @property integer $energyRefillPerInterval
29
 * @property integer $remainingTimeToRefill
30
 * @property integer $justAdvanced
31
 * @property integer $freeSlots
32
 * @property boolean $black_market
33
 * @property integer $skill_extended
34
 * @property string $clubName
35
 */
36
class Player extends CModel implements ISubject
37
{
38
    const ENERGY_REFILL_INTERVAL = 300; //5min
39
40
    private $uid;
41
    private $user;
42
    private $registered;
43
    private $xp_all;
44
    private $xp_delta;
45
    private $xp_recommended;
46
    private $level;
47
    private $status_points;
48
    private $energy_max;
49
    private $energy_incr_at;
50
    private $energy;
51
    private $skill;
52
    private $skill_extended;
53
    private $strength;
54
    private $dollar;
55
    private $gold;
56
    private $last_location;
57
    private $owned_items;
58
    private $owned_baits;
59
    private $found_setitem_time;
60
    private $found_setitem_xp;
61
    private $duel_points;
0 ignored issues
show
Unused Code introduced by
The property $duel_points is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
62
    private $tutorial_mission;
63
    private $in_club;
64
    private $black_market;
65
66
    private $justAdvanced;
67
68
    public function attributeNames()
69
    {
70
        return [];
71
    }
72
73
    public function getUid()
74
    {
75
        return (int)$this->uid;
76
    }
77
78
    public function getUser()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
79
    {
80
        return $this->user;
81
    }
82
83
    public function getRegistered()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
84
    {
85
        return $this->registered;
86
    }
87
88
    public function getLevel()
89
    {
90
        return (int)$this->level;
91
    }
92
93
    public function getStatus_points()
94
    {
95
        return $this->itsMe() ? (int)$this->status_points : 0;
96
    }
97
98
    public function getEnergy()
99
    {
100
        return (int)$this->energy;
101
    }
102
103
    public function getEnergy_max()
104
    {
105
        return (int)$this->energy_max;
106
    }
107
108
    public function getEnergy_missing()
109
    {
110
        return $this->energy_max - $this->energy;
111
    }
112
113
    public function getEnergyRequiredForDuel()
114
    {
115
        return round($this->energy_max / 10);
116
    }
117
118
    public function getSkill()
119
    {
120
        return (int)$this->skill;
121
    }
122
123
    public function getStrength()
124
    {
125
        return (int)$this->strength;
126
    }
127
128
    public function getDollar()
129
    {
130
        return (int)$this->dollar;
131
    }
132
133
    public function getGold()
134
    {
135
        return (int)$this->gold;
136
    }
137
138
    public function getXp_all()
139
    {
140
        return (int)$this->xp_all;
141
    }
142
143
    public function getXp_delta()
144
    {
145
        return (int)$this->xp_delta;
146
    }
147
148
    public function getXp_remaining()
149
    {
150
        return (int)$this->xp_recommended - (int)$this->xp_delta;
151
    }
152
153
    public function getLast_location()
154
    {
155
        return (int)$this->last_location;
156
    }
157
158
    public function getOwned_items()
159
    {
160
        return (int)$this->owned_items;
161
    }
162
163
    public function getOwned_baits()
164
    {
165
        return (int)$this->owned_baits;
166
    }
167
168
    public function getFound_setitem_time()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
169
    {
170
        return $this->found_setitem_time > $this->registered ? $this->found_setitem_time : $this->registered;
171
    }
172
173
    public function getFound_setitem_xp()
174
    {
175
        return (int)$this->found_setitem_xp;
176
    }
177
178
    public function getTutorial_mission()
179
    {
180
        return (int)$this->tutorial_mission;
181
    }
182
183
    public function getIn_club()
184
    {
185
        return (int)$this->in_club;
186
    }
187
188
    public function getLevel_percent()
189
    {
190
        if (!$this->xp_recommended) {
191
            return 0;
192
        }
193
        $percent = (int)$this->xp_delta / ((int)$this->xp_recommended / 100);
194
195
        if ($percent < 0) {
196
            $percent = 0;
197
        }
198
        if ($percent > 100) {
199
            $percent = 100;
200
        }
201
        return $percent;
202
    }
203
204
    public function getRefillPerInterval()
205
    {
206
        return round($this->energy_max / 10);
207
    }
208
209
    public function getEnergyRefillInterval()
210
    {
211
        return self::ENERGY_REFILL_INTERVAL;
212
    }
213
214
    public function getRemainingTimeToRefill()
215
    {
216
        $last = strtotime($this->energy_incr_at);
217
        if ($last < 0) {
218
            $last = 0;
219
        }
220
221
        $remaining = self::ENERGY_REFILL_INTERVAL - (time() - $last);
222
        if ($remaining < 0) {
223
            $remaining = 0;
224
        }
225
226
        return $remaining;
227
    }
228
229
    public function getJustAdvanced()
230
    {
231
        return (int)$this->justAdvanced;
232
    }
233
234
    public function getFreeSlots()
235
    {
236
        return $this->strength - ($this->owned_items + $this->owned_baits);
237
    }
238
239
    public function getBlack_market()
240
    {
241
        return (bool)(strtotime($this->black_market) >= time());
242
    }
243
244
    public function itsMe()
0 ignored issues
show
Coding Style introduced by
itsMe uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
245
    {
246
        return $this->uid == @$_SESSION['uid'];
247
    }
248
249
    public function getSkill_extended()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
250
    {
251
        return $this->skill_extended>0 ? $this->skill_extended : 1;
252
    }
253
254
    public function getClubName()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
255
    {
256
        if (!$this->in_club) {
257
            return false;
258
        }
259
260
        $club = new Club;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
261
        $club->id = $this->in_club;
0 ignored issues
show
Bug introduced by
The property id cannot be accessed from this context as it is declared private in class Club.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
262
        $club->fetchName();
263
        return $club->name;
0 ignored issues
show
Bug introduced by
The property name cannot be accessed from this context as it is declared private in class Club.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
264
    }
265
266
    public function setSubjectId($id)
267
    {
268
        $this->uid = (int)$id;
269
    }
270
271
    public function setOwned_baits($baits)
272
    {
273
        $this->owned_baits = (int)$baits;
274
    }
275
276
    public function setOwned_items($items)
277
    {
278
        $this->owned_items = (int)$items;
279
    }
280
281
    public function activateDuelShield()
282
    {
283
        Yii::trace($this->uid . ': activate duelShield.');
284
        $this->energy = 0;
285
    }
286
287
    public function fetchUser()
288
    {
289
        $user = Yii::app()->db->cache(86400)->createCommand()
290
            ->select('user')
291
            ->from('main')
292
            ->where('uid=:uid', [':uid'=>$this->uid])
293
            ->queryScalar();
294
        if (!$user) {
295
            $user = '???';
296
        }
297
        $this->user = $user;
298
    }
299
300 View Code Duplication
    public function getSubjectName()
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...
301
    {
302
        $name = Yii::app()->db->cache(86400)->createCommand()
303
            ->select('user')
304
            ->from('main')
305
            ->where('uid=:uid', [':uid'=>$this->uid])
306
            ->queryScalar();
307
        if (!$name) {
308
            $name = '???';
309
        }
310
        return $name;
311
    }
312
313
    public function setAllAttributes($uid = 0)
0 ignored issues
show
Coding Style introduced by
setAllAttributes uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
314
    {
315
        $this->setSubjectId( $uid ? $uid : @$_SESSION['uid'] );
316
317
        if (!$this->uid) {
318
            return false;
319
        }
320
321
        //read all from db
322
        $res = Yii::app()->db->createCommand()
323
            ->select('*')
324
            ->from('main')
325
            ->where('uid=:uid', [':uid'=>$this->uid])
326
            ->queryRow();
327
328
        if (!is_array($res)) {
329
            $this->uid = 0;
330
            return false;
331
        }
332
333
        foreach ($res as $k => $v) {
334
            $this->$k = $v;
335
        }
336
    }
337
338
    public function rest()
339
    {
340
        $refillable = $this->energy_max - $this->energy;
341
        if (!$refillable) {
342
            return false; //don't need to rest
343
        }
344
345
        $now = time();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
346
        $last = strtotime($this->energy_incr_at);
347
        if ($last<0) {
348
            $last = 0;
349
        }
350
351
        $interval = $now - $last;
352
        if ($interval < self::ENERGY_REFILL_INTERVAL) {
353
            return false;
354
        }
355
356
        $refillMultiplier = floor($interval / self::ENERGY_REFILL_INTERVAL); //incement energy every 5 minutes
357
358
        $refillSum = $refillMultiplier * $this->refillPerInterval;
359
        if ($refillSum > $refillable) {
360
            $refillSum = $refillable;
361
        }
362
363
        if ($refillSum < 1) {
364
            return false; //don't need to rest
365
        }
366
367
        $this->energy += $refillSum;
368
369
        $remain = 0;
370
        if ($interval <= self::ENERGY_REFILL_INTERVAL * 5) {
371
            $remain = $interval - ($refillMultiplier * self::ENERGY_REFILL_INTERVAL);
372
        }
373
374
        $this->energy_incr_at = date("Y-m-d H:i:s", $now-$remain);
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal Y-m-d H:i:s does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
375
376
        Yii::app()->db->createCommand()
377
            ->update('main', ['energy'=>$this->energy, 'energy_incr_at'=>$this->energy_incr_at], 'uid=:uid', [':uid'=>(int)$this->uid]);
378
    }
379
380
    public function updateAttributes($toIncrement, $toDecrement)
381
    {
382
        $this->logEnergyUsage($toDecrement);
383
        $attributes = [];
384
385
        $toIncrement = $this->incrementLevel($toIncrement);
386
387
        foreach ($toIncrement as $k => $v) {
388
            $newValue = $this->$k + $v;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
389
            $attributes[$k] = $newValue;
390
            $this->$k = $newValue;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
391
392
            if ($k=='dollar') {
393
                (new ProfileBadgeActivator())->triggerDollar($this->uid, $newValue);
394
            }
395
        }
396
397
        //level advance, reset energy
398
        if (isset($attributes['level'])) {
399
            unset($toDecrement['energy']);
400
            Yii::app()->gameLogger->log(['type'=>'level_up']);
401
        }
402
403
        foreach ($toDecrement as $k => $v) {
404
            if ($v > $this->$k) {
405
                $v = $this->$k;
406
            }
407
408
            $newValue = $this->$k - $v;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
409
            $attributes[$k] = $newValue;
410
            $this->$k = $newValue;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
411
        }
412
413
414
        if (!empty($attributes)) {
415
            Yii::app()->db->createCommand()
416
            ->update('main', $attributes, 'uid=:uid', [':uid'=>(int)$this->uid]);
417
        }
418
    }
419
420
    protected function logEnergyUsage($attributes)
421
    {
422
        if (!isset($attributes['energy'])) {
423
            return false;
424
        }
425
426
        //todo: implement redis log
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
427
        $used = $attributes['energy'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
428
        $percent = round($used / ($this->energy_max / 100), 2) * 100;
429
430
        $redis = Yii::app()->redis->getClient();
431
        $key = 'counter:activity:' . date('Ymd');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
432
        $redis->hIncrBy($key, $this->uid, $percent);
433
    }
434
435
    public function rewriteAttributes($attributes)
436
    {
437
        foreach ($attributes as $k => $v) {
438
            $this->$k = $v;
439
        }
440
441
        Yii::app()->db->createCommand()
442
            ->update('main', $attributes, 'uid=:uid', [':uid'=>(int)$this->uid]);
443
    }
444
445
    private function incrementLevel($incr)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
446
    {
447
        if (!isset($incr['xp_delta']) || $incr['xp_delta'] < 1) {
448
            return $incr; //do not touch level
449
        }
450
451
        $remaining = $this->getXp_remaining();
452
        if ($incr['xp_delta'] < $remaining) {
453
            return $incr; //don't advance to next level
454
        }
455
456
        //advance
457
        $incr['level'] = 1;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
458
        $this->xp_delta = $incr['xp_delta'] - $remaining; //set delta
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 9 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
459
        $incr['xp_delta'] = 0; //do not increase further
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
460
        $incr['xp_recommended'] = $this->nextXpRecommended();
461
        $incr['status_points'] = 4;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
462
463
        $this->energy = $this->energy_max;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
464
        $incr['energy'] = 0;
465
466
        $this->justAdvanced = true;
467
468
        (new ProfileBadgeActivator())->triggerLevel($this->uid, $this->level+1);
469
        return $incr;
470
    }
471
472
    private function nextXpRecommended()
473
    {
474
        $recommendations = [
475
            //fromLevel => recommended xp gain to the NEXT level
476
            1 => 3,
477
            5 => 5,
478
            10 => 10,
479
            20 => 15,
480
            30 => 20,
481
            40 => 30,
482
            50 => 10,
483
            80 => 15,
484
            90 => 20,
485
            100 => 20,
486
            120 => 35,
487
            140 => 40,
488
            160 => 30,
489
            180 => 45,
490
            200 => 50,
491
            ];
492
        $search = $this->level+1;
493
        for ($i=$search; $i>0; $i--) {
494
            if (isset($recommendations[$i])) {
495
                return $recommendations[$i];
496
            }
497
        }
498
        return 0;
499
    }
500
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
501