Completed
Push — work-fleets ( 9cd586...f0ff6c )
by SuperNova.WS
04:56
created

Fleet::dbGetLockById()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 113
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 113
rs 8.2857
cc 1
eloc 29
nc 1
nop 1

How to fix   Long Method   

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
/**
4
 * Class Fleet
5
 *
6
 * @property int dbId
7
 * @property int playerOwnerId
8
 * @property int group_id
9
 * @property int mission_type
10
 * @property int target_owner_id
11
 * @property int is_returning
12
 *
13
 * @property int time_launch
14
 * @property int time_arrive_to_target
15
 * @property int time_mission_job_complete
16
 * @property int time_return_to_source
17
 *
18
 * @property int fleet_start_planet_id
19
 * @property int fleet_start_galaxy
20
 * @property int fleet_start_system
21
 * @property int fleet_start_planet
22
 * @property int fleet_start_type
23
 *
24
 * @property int fleet_end_planet_id
25
 * @property int fleet_end_galaxy
26
 * @property int fleet_end_system
27
 * @property int fleet_end_planet
28
 * @property int fleet_end_type
29
 *
30
 */
31
class Fleet extends UnitContainer {
32
33
34
  // DBRow inheritance *************************************************************************************************
35
36
  /**
37
   * Table name in DB
38
   *
39
   * @var string
40
   */
41
  protected static $_table = 'fleets';
42
  /**
43
   * Name of ID field in DB
44
   *
45
   * @var string
46
   */
47
  protected static $_dbIdFieldName = 'fleet_id';
48
  /**
49
   * DB_ROW to Class translation scheme
50
   *
51
   * @var array
52
   */
53
  protected static $_properties = array(
54
    'dbId'          => array(
55
      P_DB_FIELD => 'fleet_id',
56
    ),
57
    'playerOwnerId' => array(
58
      P_DB_FIELD => 'fleet_owner',
59
    ),
60
    'mission_type'  => array(
61
      P_DB_FIELD   => 'fleet_mission',
62
      P_FUNC_INPUT => 'intval',
63
    ),
64
65
    'target_owner_id' => array(
66
      P_DB_FIELD => 'fleet_target_owner',
67
    ),
68
    'group_id'        => array(
69
      P_DB_FIELD => 'fleet_group',
70
    ),
71
    'is_returning'    => array(
72
      P_DB_FIELD   => 'fleet_mess',
73
      P_FUNC_INPUT => 'intval',
74
    ),
75
76
    'shipCount' => array(
77
      P_DB_FIELD  => 'fleet_amount',
78
// TODO - CHECK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% 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...
79
//      P_FUNC_OUTPUT => 'get_ship_count',
80
//      P_DB_FIELDS_LINKED => array(
81
//        'fleet_amount',
82
//      ),
83
      P_READ_ONLY => true,
84
    ),
85
86
    'time_launch' => array(
87
      P_DB_FIELD => 'start_time',
88
    ),
89
90
91
    'time_arrive_to_target'     => array(
92
      P_DB_FIELD => 'fleet_start_time',
93
    ),
94
    'time_mission_job_complete' => array(
95
      P_DB_FIELD => 'fleet_end_stay',
96
    ),
97
    'time_return_to_source'     => array(
98
      P_DB_FIELD => 'fleet_end_time',
99
    ),
100
101
    'fleet_start_planet_id' => array(
102
      P_DB_FIELD   => 'fleet_start_planet_id',
103
      P_FUNC_INPUT => 'nullIfEmpty',
104
    ),
105
106
107
    'fleet_start_galaxy' => array(
108
      P_DB_FIELD => 'fleet_start_galaxy',
109
    ),
110
    'fleet_start_system' => array(
111
      P_DB_FIELD => 'fleet_start_system',
112
    ),
113
    'fleet_start_planet' => array(
114
      P_DB_FIELD => 'fleet_start_planet',
115
    ),
116
    'fleet_start_type'   => array(
117
      P_DB_FIELD => 'fleet_start_type',
118
    ),
119
120
    'fleet_end_planet_id' => array(
121
      P_DB_FIELD   => 'fleet_end_planet_id',
122
      P_FUNC_INPUT => 'nullIfEmpty',
123
    ),
124
    'fleet_end_galaxy'    => array(
125
      P_DB_FIELD => 'fleet_end_galaxy',
126
    ),
127
    'fleet_end_system'    => array(
128
      P_DB_FIELD => 'fleet_end_system',
129
    ),
130
    'fleet_end_planet'    => array(
131
      P_DB_FIELD => 'fleet_end_planet',
132
    ),
133
    'fleet_end_type'      => array(
134
      P_DB_FIELD => 'fleet_end_type',
135
    ),
136
137
138
    'resource_list' => array(
139
      P_METHOD_EXTRACT   => 'resourcesExtract',
140
      P_METHOD_INJECT    => 'resourcesInject',
141
      P_DB_FIELDS_LINKED => array(
142
        'fleet_resource_metal',
143
        'fleet_resource_crystal',
144
        'fleet_resource_deuterium',
145
      ),
146
    ),
147
  );
148
149
150
  // UnitContainer inheritance *****************************************************************************************
151
  /**
152
   * Type of this location
153
   *
154
   * @var int $locationType
155
   */
156
  protected static $locationType = LOC_FLEET;
157
158
159
  // New properties ****************************************************************************************************
160
  /**
161
   * `fleet_owner`
162
   *
163
   * @var int
164
   */
165
  protected $_playerOwnerId = 0;
166
  /**
167
   * `fleet_group`
168
   *
169
   * @var int
170
   */
171
  protected $_group_id = 0;
172
173
  /**
174
   * `fleet_mission`
175
   *
176
   * @var int
177
   */
178
  protected $_mission_type = 0;
179
180
  /**
181
   * `fleet_target_owner`
182
   *
183
   * @var int
184
   */
185
  protected $_target_owner_id = null;
186
187
  /**
188
   * @var array
189
   */
190
  protected $resource_list = array(
191
    RES_METAL     => 0,
192
    RES_CRYSTAL   => 0,
193
    RES_DEUTERIUM => 0,
194
  );
195
196
197
  /**
198
   * `fleet__mess` - Флаг возвращающегося флота
199
   *
200
   * @var int
201
   */
202
  protected $_is_returning = 0;
203
  /**
204
   * `start_time` - Время отправления - таймштамп взлёта флота из точки отправления
205
   *
206
   * @var int $_time_launch
207
   */
208
  protected $_time_launch = 0; // `start_time` = SN_TIME_NOW
209
  /**
210
   * `fleet_start_time` - Время прибытия в точку миссии/время начала выполнения миссии
211
   *
212
   * @var int $_time_arrive_to_target
213
   */
214
  protected $_time_arrive_to_target = 0; // `fleet_start_time` = SN_TIME_NOW + $time_travel
215
  /**
216
   * `fleet_end_stay` - Время окончания миссии в точке назначения
217
   *
218
   * @var int $_time_mission_job_complete
219
   */
220
  protected $_time_mission_job_complete = 0; // `fleet_end_stay`
221
  /**
222
   * `fleet_end_time` - Время возвращения флота после окончания миссии
223
   *
224
   * @var int $_time_return_to_source
225
   */
226
  protected $_time_return_to_source = 0; // `fleet_end_time`
227
228
229
  protected $_fleet_start_planet_id = null;
230
  protected $_fleet_start_galaxy = 0;
231
  protected $_fleet_start_system = 0;
232
  protected $_fleet_start_planet = 0;
233
  protected $_fleet_start_type = PT_ALL;
234
235
  protected $_fleet_end_planet_id = null;
236
  protected $_fleet_end_galaxy = 0;
237
  protected $_fleet_end_system = 0;
238
  protected $_fleet_end_planet = 0;
239
  protected $_fleet_end_type = PT_ALL;
240
241
  // Missile properties
242
  public $missile_target = 0;
243
244
  // Fleet event properties
245
  public $fleet_start_name = '';
246
  public $fleet_end_name = '';
247
  public $ov_label = '';
248
  public $ov_this_planet = '';
249
  public $event_time = 0;
250
251
  protected $resource_delta = array();
252
  protected $resource_replace = array();
253
254
255
  /**
256
   * Returns location's player owner ID
257
   *
258
   * @return int
259
   */
260
  // TODO - REMOVE! TEMPORARY UNTIL THERE BE FULLLY FUNCTIONAL Player CLASS AND FLEETS WOULD BE LOCATED ON PLANET OR PLAYER!!!!!
261
  public function getPlayerOwnerId() {
262
    return $this->_dbId;
263
  }
264
265
  /**
266
   * Fleet constructor.
267
   */
268
  public function __construct() {
269
    parent::__construct();
270
  }
271
272
  public function isEmpty() {
273
    return !$this->resourcesGetTotal() && !$this->shipsGetTotal();
274
  }
275
276
//  public function getPlayerOwnerId() {
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
277
//    return $this->playerOwnerId;
278
//  }
279
280
  /**
281
   * Initializes Fleet from user params and posts it to DB
282
   */
283
  public function dbInsert() {
284
    // WARNING! MISSION TIMES MUST BE SET WITH set_times() method!
285
    // TODO - more checks!
286
    if(empty($this->_time_launch)) {
287
      die('Fleet time not set!');
288
    }
289
290
    parent::dbInsert();
291
  }
292
293
294
  /* FLEET DB ACCESS =================================================================================================*/
295
296
  /**
297
   * LOCK - Lock all records which can be used with mission
298
   *
299
   * @param $mission_data
300
   * @param $fleet_id
301
   *
302
   * @return array|bool|mysqli_result|null
303
   */
304
  public function dbLockFlying(&$mission_data) {
305
    // Тупо лочим всех юзеров, чьи флоты летят или улетают с координат отбытия/прибытия $fleet_row
306
    // Что бы делать это умно - надо учитывать fleet__mess во $fleet_row и в таблице fleets
307
308
    $fleet_id_safe = idval($this->_dbId);
309
310
    return doquery(
311
    // Блокировка самого флота
312
      "SELECT 1 FROM {{fleets}} AS f " .
313
314
      // Блокировка всех юнитов, принадлежащих этому флоту
315
      "LEFT JOIN {{unit}} as unit ON unit.unit_location_type = " . static::$locationType . " AND unit.unit_location_id = f.fleet_id " .
316
317
      // Блокировка всех прилетающих и улетающих флотов, если нужно
318
      // TODO - lock fleets by COORDINATES
319
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{fleets}} AS fd ON fd.fleet_end_planet_id = f.fleet_end_planet_id OR fd.fleet_start_planet_id = f.fleet_end_planet_id " : '') .
320
      // Блокировка всех юнитов, принадлежащих прилетающим и улетающим флотам - ufd = unit_fleet_destination
321
      ($mission_data['dst_fleets'] ? "LEFT JOIN {{unit}} AS ufd ON ufd.unit_location_type = " . static::$locationType . " AND ufd.unit_location_id = fd.fleet_id " : '') .
322
323
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{users}} AS ud ON ud.id = f.fleet_target_owner " : '') .
324
      // Блокировка всех юнитов, принадлежащих владельцу планеты-цели
325
      ($mission_data['dst_user'] || $mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS unit_player_dest ON unit_player_dest.unit_player_id = ud.id " : '') .
326
      // Блокировка планеты-цели
327
      ($mission_data['dst_planet'] ? "LEFT JOIN {{planets}} AS pd ON pd.id = f.fleet_end_planet_id " : '') .
328
      // Блокировка всех юнитов, принадлежащих планете-цели - НЕ НУЖНО. Уже залочили ранее, как принадлежащие игроку-цели
329
//      ($mission_data['dst_planet'] ? "LEFT JOIN {{unit}} AS upd ON upd.unit_location_type = " . LOC_PLANET . " AND upd.unit_location_id = pd.id " : '') .
330
331
332
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{users}} AS us ON us.id = f.fleet_owner " : '') .
333
      // Блокировка всех юнитов, принадлежащих владельцу флота
334
      ($mission_data['src_user'] || $mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS unit_player_src ON unit_player_src.unit_player_id = us.id " : '') .
335
      // Блокировка планеты отправления
336
      ($mission_data['src_planet'] ? "LEFT JOIN {{planets}} AS ps ON ps.id = f.fleet_start_planet_id " : '') .
337
      // Блокировка всех юнитов, принадлежащих планете с которой юниты были отправлены - НЕ НУЖНО. Уже залочили ранее, как принадлежащие владельцу флота
338
//      ($mission_data['src_planet'] ? "LEFT JOIN {{unit}} AS ups ON ups.unit_location_type = " . LOC_PLANET . " AND ups.unit_location_id = ps.id " : '') .
339
340
      "WHERE f.fleet_id = {$fleet_id_safe} GROUP BY 1 FOR UPDATE"
341
    );
342
  }
343
344
  /**
345
   * Lock all fields that belongs to operation
346
   *
347
   * @param $dbId
348
   *
349
   * @internal param DBLock $dbRow - Object that accumulates locks
350
   *
351
   */
352
  // TODO = make static
353
  public function dbGetLockById($dbId) {
354
    doquery(
355
    // Блокировка самого флота
356
      "SELECT 1 FROM {{fleets}} AS FLEET0 " .
357
      // Lock fleet owner
358
      "LEFT JOIN {{users}} as USER0 on USER0.id = FLEET0.fleet_owner " .
359
      // Блокировка всех юнитов, принадлежащих этому флоту
360
      "LEFT JOIN {{unit}} as UNIT0 ON UNIT0.unit_location_type = " . LOC_FLEET . " AND UNIT0.unit_location_id = FLEET0.fleet_id " .
361
362
      // Без предварительной выборки неизвестно - куда летит этот флот.
363
      // Поэтому надо выбирать флоты, чьи координаты прибытия ИЛИ отбытия совпадают с координатами прибытия ИЛИ отбытия текущего флота.
364
      // Получаем матрицу 2х2 - т.е. 4 подзапроса.
365
      // При блокировке всегда нужно выбирать И лпанету, И луну - поскольку при бое на орбите луны обломки падают на орбиту планеты.
366
      // Поэтому тип планеты не указывается
367
368
      // Lock fleet heading to destination planet. Only if FLEET0.fleet_mess == 0
369
      "LEFT JOIN {{fleets}} AS FLEET1 ON
370
        FLEET1.fleet_mess = 0 AND FLEET0.fleet_mess = 0 AND
371
        FLEET1.fleet_end_galaxy = FLEET0.fleet_end_galaxy AND
372
        FLEET1.fleet_end_system = FLEET0.fleet_end_system AND
373
        FLEET1.fleet_end_planet = FLEET0.fleet_end_planet
374
      " .
375
      // Блокировка всех юнитов, принадлежащих этим флотам
376
      "LEFT JOIN {{unit}} as UNIT1 ON UNIT1.unit_location_type = " . LOC_FLEET . " AND UNIT1.unit_location_id = FLEET1.fleet_id " .
377
      // Lock fleet owner
378
      "LEFT JOIN {{users}} as USER1 on USER1.id = FLEET1.fleet_owner " .
379
380
      "LEFT JOIN {{fleets}} AS FLEET2 ON
381
        FLEET2.fleet_mess = 1   AND FLEET0.fleet_mess = 0 AND
382
        FLEET2.fleet_start_galaxy = FLEET0.fleet_end_galaxy AND
383
        FLEET2.fleet_start_system = FLEET0.fleet_end_system AND
384
        FLEET2.fleet_start_planet = FLEET0.fleet_end_planet
385
      " .
386
      // Блокировка всех юнитов, принадлежащих этим флотам
387
      "LEFT JOIN {{unit}} as UNIT2 ON
388
        UNIT2.unit_location_type = " . LOC_FLEET . " AND
389
        UNIT2.unit_location_id = FLEET2.fleet_id
390
      " .
391
      // Lock fleet owner
392
      "LEFT JOIN {{users}} as USER2 on
393
        USER2.id = FLEET2.fleet_owner
394
      " .
395
396
      // Lock fleet heading to source planet. Only if FLEET0.fleet_mess == 1
397
      "LEFT JOIN {{fleets}} AS FLEET3 ON
398
        FLEET3.fleet_mess = 0 AND FLEET0.fleet_mess = 1 AND
399
        FLEET3.fleet_end_galaxy = FLEET0.fleet_start_galaxy AND
400
        FLEET3.fleet_end_system = FLEET0.fleet_start_system AND
401
        FLEET3.fleet_end_planet = FLEET0.fleet_start_planet
402
      " .
403
      // Блокировка всех юнитов, принадлежащих этим флотам
404
      "LEFT JOIN {{unit}} as UNIT3 ON
405
        UNIT3.unit_location_type = " . LOC_FLEET . " AND
406
        UNIT3.unit_location_id = FLEET3.fleet_id
407
      " .
408
      // Lock fleet owner
409
      "LEFT JOIN {{users}} as USER3 on USER3.id = FLEET3.fleet_owner " .
410
411
      "LEFT JOIN {{fleets}} AS FLEET4 ON
412
        FLEET4.fleet_mess = 1   AND FLEET0.fleet_mess = 1 AND
413
        FLEET4.fleet_start_galaxy = FLEET0.fleet_start_galaxy AND
414
        FLEET4.fleet_start_system = FLEET0.fleet_start_system AND
415
        FLEET4.fleet_start_planet = FLEET0.fleet_start_planet
416
      " .
417
      // Блокировка всех юнитов, принадлежащих этим флотам
418
      "LEFT JOIN {{unit}} as UNIT4 ON
419
        UNIT4.unit_location_type = " . LOC_FLEET . " AND
420
        UNIT4.unit_location_id = FLEET4.fleet_id
421
      " .
422
      // Lock fleet owner
423
      "LEFT JOIN {{users}} as USER4 on
424
        USER4.id = FLEET4.fleet_owner
425
      " .
426
427
428
429
      // Locking start planet
430
      "LEFT JOIN {{planets}} AS PLANETS5 ON
431
        FLEET0.fleet_mess = 1 AND
432
        PLANETS5.galaxy = FLEET0.fleet_start_galaxy AND
433
        PLANETS5.system = FLEET0.fleet_start_system AND
434
        PLANETS5.planet = FLEET0.fleet_start_planet
435
      " .
436
      // Lock planet owner
437
      "LEFT JOIN {{users}} as USER5 on
438
        USER5.id = PLANETS5.id_owner
439
      " .
440
      // Блокировка всех юнитов, принадлежащих этой планете
441
      "LEFT JOIN {{unit}} as UNIT5 ON
442
        UNIT5.unit_location_type = " . LOC_PLANET . " AND
443
        UNIT5.unit_location_id = PLANETS5.id
444
      " .
445
446
447
      // Locking destination planet
448
      "LEFT JOIN {{planets}} AS PLANETS6 ON
449
        FLEET0.fleet_mess = 0 AND
450
        PLANETS6.galaxy = FLEET0.fleet_end_galaxy AND
451
        PLANETS6.system = FLEET0.fleet_end_system AND
452
        PLANETS6.planet = FLEET0.fleet_end_planet
453
      " .
454
      // Lock planet owner
455
      "LEFT JOIN {{users}} as USER6 on
456
        USER6.id = PLANETS6.id_owner
457
      " .
458
      // Блокировка всех юнитов, принадлежащих этой планете
459
      "LEFT JOIN {{unit}} as UNIT6 ON
460
        UNIT6.unit_location_type = " . LOC_PLANET . " AND
461
        UNIT6.unit_location_id = PLANETS6.id
462
      " .
463
      "WHERE FLEET0.fleet_id = {$dbId} GROUP BY 1 FOR UPDATE"
464
    );
465
  }
466
467
468
469
  /* FLEET HELPERS =====================================================================================================*/
470
  /**
471
   * Forcibly returns fleet before time outs
472
   */
473
  public function commandReturn() {
474
    $ReturnFlyingTime = ($this->_time_mission_job_complete != 0 && $this->_time_arrive_to_target < SN_TIME_NOW ? $this->_time_arrive_to_target : SN_TIME_NOW) - $this->_time_launch + SN_TIME_NOW + 1;
475
476
    $this->markReturned();
477
478
    // Считаем, что флот уже долетел TODO
479
    $this->time_arrive_to_target = SN_TIME_NOW;
480
    // Убираем флот из группы
481
    $this->group_id = 0;
482
    // Отменяем работу в точке назначения
483
    $this->time_mission_job_complete = 0;
484
    // TODO - правильно вычслять время возвращения - по проделанному пути, а не по старому времени возвращения
485
    $this->time_return_to_source = $ReturnFlyingTime;
486
487
    // Записываем изменения в БД
488
    $this->dbSave();
489
490
    if($this->_group_id) {
491
      // TODO: Make here to delete only one AKS - by adding aks_fleet_count to AKS table
492
      db_fleet_aks_purge();
493
    }
494
  }
495
496
497
498
499
500
  /**
501
   * @return array
502
   */
503
  public function target_coordinates_without_type() {
504
    return array(
505
      'galaxy' => $this->_fleet_end_galaxy,
506
      'system' => $this->_fleet_end_system,
507
      'planet' => $this->_fleet_end_planet,
508
    );
509
  }
510
511
  /**
512
   * @return array
513
   */
514
  public function target_coordinates_typed() {
515
    return array(
516
      'galaxy' => $this->_fleet_end_galaxy,
517
      'system' => $this->_fleet_end_system,
518
      'planet' => $this->_fleet_end_planet,
519
      'type'   => $this->_fleet_end_type,
520
    );
521
  }
522
523
  /**
524
   * @return array
525
   */
526
  public function launch_coordinates_typed() {
527
    return array(
528
      'galaxy' => $this->_fleet_start_galaxy,
529
      'system' => $this->_fleet_start_system,
530
      'planet' => $this->_fleet_start_planet,
531
      'type'   => $this->_fleet_start_type,
532
    );
533
  }
534
535
536
537
  /**
538
   * Sets object fields for fleet return
539
   */
540
  public function markReturned() {
541
    // TODO - Проверка - а не возвращается ли уже флот?
542
    $this->is_returning = 1;
543
  }
544
545
  public function isReturning() {
546
    return 1 == $this->_is_returning;
547
  }
548
549
  public function markReturnedAndSave() {
550
    $this->markReturned();
551
    $this->dbSave();
552
  }
553
554
  /**
555
   * Parses extended unit_array which can include not only ships but resources, captains etc
556
   *
557
   * @param $unit_array
558
   */
559
  // TODO - separate shipList and unitList
560
  public function unitsSetFromArray($unit_array) {
561
    foreach($unit_array as $unit_id => $unit_count) {
562
      $unit_count = floatval($unit_count);
563
      if(!$unit_count) {
564
        continue;
565
      }
566
567
      if($this->isShip($unit_id)) {
568
        $this->unitList->unitSetCount($unit_id, $unit_count);
569
      } elseif($this->isResource($unit_id)) {
570
        $this->resource_list[$unit_id] = $unit_count;
571
      } else {
572
        throw new Exception('Trying to pass to fleet non-resource and non-ship ' . var_export($unit_array, true), ERR_ERROR);
573
      }
574
    }
575
  }
576
577
578
  /**
579
   * Sets fleet timers based on flight duration, time on mission (HOLD/EXPLORE) and fleet departure time.
580
   *
581
   * @param int $time_to_travel - flight duration in seconds
582
   * @param int $time_on_mission - time on mission in seconds
583
   * @param int $group_sync_delta_time - delta time to adjust fleet arrival time if fleet is a part of group (i.e. ACS)
584
   * @param int $flight_departure - fleet departure from source planet timestamp. Allows to send fleet in future or in past
585
   */
586
  public function set_times($time_to_travel, $time_on_mission = 0, $group_sync_delta_time = 0, $flight_departure = SN_TIME_NOW) {
587
    $this->_time_launch = $flight_departure;
588
589
    $this->_time_arrive_to_target = $this->_time_launch + $time_to_travel + $group_sync_delta_time;
590
    $this->_time_mission_job_complete = $time_on_mission ? $this->_time_arrive_to_target + $time_on_mission : 0;
591
    $this->_time_return_to_source = ($this->_time_mission_job_complete ? $this->_time_mission_job_complete : $this->_time_arrive_to_target) + $time_to_travel;
592
  }
593
594
595
  public function parse_missile_db_row($missile_db_row) {
596
//    $this->_reset();
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
597
598
    if(empty($missile_db_row) || !is_array($missile_db_row)) {
599
      return;
600
    }
601
602
//      $planet_start = db_planet_by_vector($irak_original, 'fleet_start_', false, 'name');
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% 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...
603
//      $irak_original['fleet_start_name'] = $planet_start['name'];
604
    $this->missile_target = $missile_db_row['primaer'];
605
606
    $this->_dbId = -$missile_db_row['id'];
607
    $this->_playerOwnerId = $missile_db_row['fleet_owner'];
608
    $this->_mission_type = MT_MISSILE;
609
610
    $this->_target_owner_id = $missile_db_row['fleet_target_owner'];
611
612
    $this->_group_id = 0;
613
    $this->_is_returning = 0;
614
615
    $this->_time_launch = 0; // $irak['start_time'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
616
    $this->_time_arrive_to_target = 0; // $irak['fleet_start_time'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
617
    $this->_time_mission_job_complete = 0; // $irak['fleet_end_stay'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
618
    $this->_time_return_to_source = $missile_db_row['fleet_end_time'];
619
620
    $this->_fleet_start_planet_id = !empty($missile_db_row['fleet_start_planet_id']) ? $missile_db_row['fleet_start_planet_id'] : null;
621
    $this->_fleet_start_galaxy = $missile_db_row['fleet_start_galaxy'];
622
    $this->_fleet_start_system = $missile_db_row['fleet_start_system'];
623
    $this->_fleet_start_planet = $missile_db_row['fleet_start_planet'];
624
    $this->_fleet_start_type = $missile_db_row['fleet_start_type'];
625
626
    $this->_fleet_end_planet_id = !empty($missile_db_row['fleet_end_planet_id']) ? $missile_db_row['fleet_end_planet_id'] : null;
627
    $this->_fleet_end_galaxy = $missile_db_row['fleet_end_galaxy'];
628
    $this->_fleet_end_system = $missile_db_row['fleet_end_system'];
629
    $this->_fleet_end_planet = $missile_db_row['fleet_end_planet'];
630
    $this->_fleet_end_type = $missile_db_row['fleet_end_type'];
631
632
    $this->unitList->unitSetCount(UNIT_DEF_MISSILE_INTERPLANET, $missile_db_row['fleet_amount']);
633
  }
634
635
636
  /**
637
   * @param $from
638
   */
639
  public function set_start_planet($from) {
640
    $this->fleet_start_planet_id = intval($from['id']) ? $from['id'] : null;
641
    $this->fleet_start_galaxy = $from['galaxy'];
642
    $this->fleet_start_system = $from['system'];
643
    $this->fleet_start_planet = $from['planet'];
644
    $this->fleet_start_type = $from['planet_type'];
645
  }
646
647
  /**
648
   * @param $to
649
   */
650
  public function set_end_planet($to) {
651
    $this->target_owner_id = intval($to['id_owner']) ? $to['id_owner'] : 0;
652
    $this->fleet_end_planet_id = intval($to['id']) ? $to['id'] : null;
653
    $this->fleet_end_galaxy = $to['galaxy'];
654
    $this->fleet_end_system = $to['system'];
655
    $this->fleet_end_planet = $to['planet'];
656
    $this->fleet_end_type = $to['planet_type'];
657
  }
658
659
660
661
  // UnitList/Ships access ***************************************************************************************************
662
663
  // TODO - перекрывать пожже - для миссайл-флотов и дефенс-флотов
664
  protected function isShip($unit_id) {
665
    return UnitShip::is_in_group($unit_id);
666
  }
667
668
  /**
669
   * Set unit count of $unit_id to $unit_count
670
   * If there is no $unit_id - it will be created and saved to DB on dbSave
671
   *
672
   * @param int $unit_id
673
   * @param int $unit_count
674
   */
675
  public function shipSetCount($unit_id, $unit_count = 0) {
676
    $this->shipAdjustCount($unit_id, $unit_count, true);
677
  }
678
679
  /**
680
   * Adjust unit count of $unit_id by $unit_count - or just replace value
681
   * If there is no $unit_id - it will be created and saved to DB on dbSave
682
   *
683
   * @param int  $unit_id
684
   * @param int  $unit_count
685
   * @param bool $replace_value
686
   */
687
  public function shipAdjustCount($unit_id, $unit_count = 0, $replace_value = false) {
688
    $this->unitList->unitAdjustCount($unit_id, $unit_count, $replace_value);
689
  }
690
691
  public function shipGetCount($unit_id) {
692
    return $this->unitList->unitGetCount($unit_id);
693
  }
694
695
  public function shipsCountApplyLossMultiplier($ships_lost_multiplier) {
696
    $this->unitList->unitsCountApplyLossMultiplier($ships_lost_multiplier);
697
  }
698
699
  /**
700
   * Returns ship list in fleet
701
   */
702
  public function shipsGetArray() {
703
    return $this->unitList->unitsGetArray();
704
  }
705
706
  public function shipsGetTotal() {
707
    return $this->unitList->unitsCount();
708
  }
709
710
  public function shipsGetCapacity() {
711
    return $this->unitList->unitsCapacity();
712
  }
713
714
  public function shipsGetHoldFree() {
715
    return max(0, $this->shipsGetCapacity() - $this->resourcesGetTotal());
716
  }
717
718
  public function shipsGetTotalById($ship_id) {
719
    return $this->unitList->unitsCountById($ship_id);
720
  }
721
722
  /**
723
   * Возвращает ёмкость переработчиков во флоте
724
   *
725
   * @param array $recycler_info
726
   *
727
   * @return int
728
   *
729
   * @version 41a6.71
730
   */
731
  public function shipsGetCapacityRecyclers(array $recycler_info) {
732
    $recyclers_incoming_capacity = 0;
733
    $fleet_data = $this->shipsGetArray();
734
    foreach($recycler_info as $recycler_id => $recycler_data) {
735
      $recyclers_incoming_capacity += $fleet_data[$recycler_id] * $recycler_data['capacity'];
736
    }
737
738
    return $recyclers_incoming_capacity;
739
  }
740
741
  /**
742
   * Restores fleet or resources to planet
743
   *
744
   * @param bool $start
745
   * @param int  $result
746
   *
747
   * @return int
748
   */
749
  // TODO - split to functions
750
  public function shipsLand($start = true, &$result = CACHE_NOTHING) {
751
    sn_db_transaction_check(true);
752
753
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
754
    if($this->isEmpty()) {
755
      return $result;
756
    }
757
758
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
759
760
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
761
    // TODO Проверить от многократного срабатывания !!!
762
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
763
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
764
765
    // Узнаем ИД владельца планеты.
766
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
767
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
768
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
769
    // Блокируем пользователя
770
    // TODO - вообще-то нам уже известен пользователь в МЛФ - так что можно просто передать его сюда
771
    $user = db_user_by_id($planet_arrival['id_owner'], true);
772
773
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
774
    // Флот, который возвращается на захваченную планету, пропадает
775
    // Ship landing is possible only to fleet owner's planet
776
    if($this->getPlayerOwnerId() == $planet_arrival['id_owner']) {
777
      $db_changeset = array();
778
779
      $fleet_array = $this->shipsGetArray();
780
      foreach($fleet_array as $ship_id => $ship_count) {
781
        if($ship_count) {
782
          $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship_count, $user, $planet_arrival['id']);
783
        }
784
      }
785
786
      // Adjusting ship amount on planet
787
      if(!empty($db_changeset)) {
788
        db_changeset_apply($db_changeset);
789
      }
790
791
      // Restoring resources to planet
792
      $this->resourcesUnload($start, $result);
793
    }
794
795
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
796
797
    $result = RestoreFleetToPlanet($this, $start, $result);
798
799
    $this->dbDelete();
800
801
    return $result;
802
  }
803
804
805
  // Resources access ***************************************************************************************************
806
807
  /**
808
   * Extracts resources value from db_row
809
   *
810
   * @param array $db_row
811
   *
812
   * @internal param Fleet $that
813
   * @version 41a6.71
814
   */
815
  protected function resourcesExtract(array &$db_row) {
816
    $this->resource_list = array(
817
      RES_METAL     => !empty($db_row['fleet_resource_metal']) ? floor($db_row['fleet_resource_metal']) : 0,
818
      RES_CRYSTAL   => !empty($db_row['fleet_resource_crystal']) ? floor($db_row['fleet_resource_crystal']) : 0,
819
      RES_DEUTERIUM => !empty($db_row['fleet_resource_deuterium']) ? floor($db_row['fleet_resource_deuterium']) : 0,
820
    );
821
  }
822
823
  protected function resourcesInject(array &$db_row) {
824
    $db_row['fleet_resource_metal'] = $this->resource_list[RES_METAL];
825
    $db_row['fleet_resource_crystal'] = $this->resource_list[RES_CRYSTAL];
826
    $db_row['fleet_resource_deuterium'] = $this->resource_list[RES_DEUTERIUM];
827
  }
828
829
  /**
830
   * Set current resource list from array of units
831
   *
832
   * @param array $resource_list
833
   */
834
  public function resourcesSet($resource_list) {
835
    if(!empty($this->propertiesAdjusted['resource_list'])) {
836
      throw new PropertyAccessException('Property "resource_list" already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::unitSetResourceList', ERR_ERROR);
837
    }
838
    $this->resourcesAdjust($resource_list, true);
839
  }
840
841
  /**
842
   * Updates fleet resource list with deltas
843
   *
844
   * @param $resource_delta_list
845
   */
846
  public function resourcesAdjust($resource_delta_list, $replace_value = false) {
847
    !is_array($resource_delta_list) ? $resource_delta_list = array() : false;
848
849
    foreach($resource_delta_list as $resource_id => $unit_delta) {
850
      if(!UnitResourceLoot::is_in_group($resource_id) || !($unit_delta = floor($unit_delta))) {
851
        // Not a resource or no resources - continuing
852
        continue;
853
      }
854
855
      if($replace_value) {
856
        $this->resource_list[$resource_id] = $unit_delta;
857
      } else {
858
        $this->resource_list[$resource_id] += $unit_delta;
859
        // Preparing changes
860
        $this->resource_delta[$resource_id] += $unit_delta;
861
        $this->propertiesAdjusted['resource_list'] = 1;
862
      }
863
864
      // Check for negative unit value
865
      if($this->resource_list[$resource_id] < 0) {
866
        // TODO
867
        throw new Exception('Resource ' . $resource_id . ' will become negative in ' . get_called_class() . '::unitAdjustResourceList', ERR_ERROR);
868
      }
869
    }
870
  }
871
872
  public function resourcesGetTotal() {
873
    return empty($this->resource_list) || !is_array($this->resource_list) ? 0 : array_sum($this->resource_list);
874
  }
875
876
  /**
877
   * @param array $rate
878
   *
879
   * @return float
880
   */
881
  public function resourcesGetTotalInMetal(array $rate) {
882
    return
883
      $this->resource_list[RES_METAL] * $rate[RES_METAL]
884
      + $this->resource_list[RES_CRYSTAL] * $rate[RES_CRYSTAL] / $rate[RES_METAL]
885
      + $this->resource_list[RES_DEUTERIUM] * $rate[RES_DEUTERIUM] / $rate[RES_METAL];
886
  }
887
888
  /**
889
   * Returns resource list in fleet
890
   */
891
  // TODO
892
  public function resourcesGetList() {
893
    return $this->resource_list;
894
  }
895
896
  public function resourcesReset() {
897
    $this->resourcesSet(array(
898
      RES_METAL     => 0,
899
      RES_CRYSTAL   => 0,
900
      RES_DEUTERIUM => 0,
901
    ));
902
  }
903
904
  /**
905
   * Restores fleet or resources to planet
906
   *
907
   * @param bool $start
908
   * @param bool $only_resources
0 ignored issues
show
Bug introduced by
There is no parameter named $only_resources. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
909
   * @param int  $result
910
   *
911
   * @return int
912
   */
913
  public function resourcesUnload($start = true, &$result = CACHE_NOTHING) {
914
    sn_db_transaction_check(true);
915
916
    // Если флот уже обработан - не существует или возращается - тогда ничего не делаем
917
    if(!$this->resourcesGetTotal()) {
918
      return $result;
919
    }
920
921
    $coordinates = $start ? $this->launch_coordinates_typed() : $this->target_coordinates_typed();
922
923
    // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!!
924
    // TODO Проверить от многократного срабатывания !!!
925
    // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока
926
    // TODO поменять на владельца планеты - когда его будут возвращать всегда !!!
927
928
929
    // Узнаем ИД владельца планеты.
930
    // С блокировкой, поскольку эта функция может быть вызвана только из менеджера летящих флотов.
931
    // А там уже всё заблокировано как надо и повторная блокировка не вызовет дедлок.
932
    $planet_arrival = db_planet_by_vector($coordinates, '', true);
933
934
    // TODO - Проверка, что планета всё еще существует на указанных координатах, а не телепортировалась, не удалена хозяином, не уничтожена врагом
935
936
    // Restoring resources to planet
937
    if($this->resourcesGetTotal()) {
938
      $fleet_resources = $this->resourcesGetList();
939
      db_planet_set_by_id($planet_arrival['id'],
940
        "`metal` = `metal` + '{$fleet_resources[RES_METAL]}', `crystal` = `crystal` + '{$fleet_resources[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$fleet_resources[RES_DEUTERIUM]}'");
941
    }
942
943
    $this->resourcesReset();
944
    $this->markReturned();
945
946
    $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST);
947
948
    return $result;
949
  }
950
951
952
  protected function isResource($unit_id) {
953
    return UnitResourceLoot::is_in_group($unit_id);
954
  }
955
956
}
957