Completed
Push — trunk ( 4322e5...58ab44 )
by SuperNova.WS
04:18
created

flt_t_send_fleet()   C

Complexity

Conditions 9
Paths 80

Size

Total Lines 61
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 9
eloc 28
c 2
b 1
f 0
nc 80
nop 7
dl 0
loc 61
rs 6.7603

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
use DBAL\OldDbChangeSet;
4
use Fleet\DbFleetStatic;
5
use Fleet\Fleet;
6
use Planet\DBStaticPlanet;
7
8
function flt_fleet_speed($user, $fleet, $shipData = []) {
9
  if (!is_array($fleet)) {
10
    $fleet = array($fleet => 1);
11
  }
12
13
  $speeds = array();
14
  if (!empty($fleet)) {
15
    foreach ($fleet as $ship_id => $amount) {
16
      if ($amount && in_array($ship_id, sn_get_groups(array('fleet', 'missile')))) {
17
        $single_ship_data = !empty($shipData[$ship_id]) ? $shipData[$ship_id] : get_ship_data($ship_id, $user);
18
        $speeds[] = $single_ship_data['speed'];
19
      }
20
    }
21
  }
22
23
  return empty($speeds) ? 0 : min($speeds);
24
}
25
26
function flt_get_galaxy_distance() {
27
  return SN::$config->uni_galaxy_distance ? SN::$config->uni_galaxy_distance : UNIVERSE_GALAXY_DISTANCE;
28
}
29
30
function flt_travel_distance($from, $to) {
31
  if ($from['galaxy'] != $to['galaxy']) {
32
    $distance = abs($from['galaxy'] - $to['galaxy']) * flt_get_galaxy_distance();
33
  } elseif ($from['system'] != $to['system']) {
34
    $distance = abs($from['system'] - $to['system']) * 5 * 19 + 2700;
35
  } elseif ($from['planet'] != $to['planet']) {
36
    $distance = abs($from['planet'] - $to['planet']) * 5 + 1000;
37
  } else {
38
    $distance = 5;
39
  }
40
41
  return $distance;
42
}
43
44
45
function fltDistanceAsGalaxy($distance) {
46
  return $distance ? $distance / flt_get_galaxy_distance() : 0;
47
}
48
49
function fltDistanceAsSystem($distance) {
50
  return $distance ? ($distance - 2700) / 5 / 19 : 0;
51
}
52
53
/**
54
 * @param int   $ship_id
55
 * @param int   $speed_percent
56
 * @param array $shipsData
57
 *
58
 * @return float|int
59
 */
60
function flt_get_max_distance($ship_id, $speed_percent = 100, $shipsData = []) {
61
  $single_ship_data = $shipsData[$ship_id];
62
63
  if (!$single_ship_data['capacity'] || !$single_ship_data['consumption']) {
64
    return 0;
65
  }
66
67
  return $distance = floor(($single_ship_data['capacity'] - 1) / $single_ship_data['consumption'] / pow($speed_percent / 100 + 1, 2) * 35000);
0 ignored issues
show
Unused Code introduced by
The assignment to $distance is dead and can be removed.
Loading history...
68
}
69
70
71
/**
72
 * @param         $user_row
73
 * @param         $from
74
 * @param         $to
75
 * @param         $fleet_array
76
 * @param int     $speed_percent
77
 * @param array[] $shipsData - prepared ships data to use in calculations
78
 *
79
 * @return array
80
 */
81
function flt_travel_data($user_row, $from, $to, $fleet_array, $speed_percent = 10, $shipsData = [], $distance = null) {
82
  $distance = $distance === null ? flt_travel_distance($from, $to) : $distance;
83
84
  $consumption = 0;
85
  $capacity = 0;
86
  $duration = 0;
87
88
  $game_fleet_speed = flt_server_flight_speed_multiplier();
89
  $fleet_speed = flt_fleet_speed($user_row, $fleet_array, $shipsData);
90
  if (!empty($fleet_array) && $fleet_speed && $game_fleet_speed) {
91
    $speed_percent = $speed_percent ? max(min($speed_percent, 10), 1) : 10;
92
    $real_speed = $speed_percent * sqrt($fleet_speed);
93
94
    $duration = max(1, round((35000 / $speed_percent * sqrt($distance * 10 / $fleet_speed) + 10) / $game_fleet_speed));
95
96
    foreach ($fleet_array as $ship_id => $ship_count) {
97
      if (!$ship_id || !$ship_count) {
98
        continue;
99
      }
100
101
      $single_ship_data = !empty($shipsData[$ship_id]) ? $shipsData[$ship_id] : get_ship_data($ship_id, $user_row);
102
      $single_ship_data['speed'] = $single_ship_data['speed'] < 1 ? 1 : $single_ship_data['speed'];
103
104
      $consumption += $single_ship_data['consumption'] * $ship_count * pow($real_speed / sqrt($single_ship_data['speed']) / 10 + 1, 2);
105
      $capacity += $single_ship_data['capacity'] * $ship_count;
106
    }
107
108
    $consumption = ceil($distance * $consumption / 35000) + 1;
109
  }
110
111
  return array(
112
    'fleet_speed'            => $fleet_speed,
113
    'distance'               => $distance,
114
    'duration'               => $duration,
115
    'consumption'            => $consumption,
116
    'capacity'               => $capacity,
117
    'hold'                   => $capacity - $consumption,
118
    'transport_effectivness' => $consumption ? $capacity / $consumption : 0,
119
  );
120
}
121
122
function flt_bashing_check($user, $enemy, $planet_dst, $mission, $flight_duration, $fleet_group = 0) {
123
  global $config;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
124
125
  $config_bashing_attacks = $config->fleet_bashing_attacks;
126
  $config_bashing_interval = $config->fleet_bashing_interval;
127
  if (!$config_bashing_attacks) {
128
    // Bashing allowed - protection disabled
129
    return ATTACK_ALLOWED;
130
  }
131
132
  $bashing_result = ATTACK_BASHING;
133
  if ($user['ally_id'] && $enemy['ally_id']) {
134
    $relations = ali_relations($user['ally_id'], $enemy['ally_id']);
135
    if (!empty($relations)) {
136
      $relations = $relations[$enemy['ally_id']];
137
      switch ($relations['alliance_diplomacy_relation']) {
138
        case ALLY_DIPLOMACY_WAR:
139
          if (SN_TIME_NOW - $relations['alliance_diplomacy_time'] <= $config->fleet_bashing_war_delay) {
140
            $bashing_result = ATTACK_BASHING_WAR_DELAY;
141
          } else {
142
            return ATTACK_ALLOWED;
143
          }
144
        break;
145
        // Here goes other relations
146
147
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
148
                default:
149
                  return ATTACK_ALLOWED;
150
                break;
151
        */
152
      }
153
    }
154
  }
155
156
  $time_limit = SN_TIME_NOW + $flight_duration - $config->fleet_bashing_scope;
157
  $bashing_list = array(SN_TIME_NOW);
158
159
  // Retrieving flying fleets
160
  $bashing_fleet_list = DbFleetStatic::fleet_list_bashing($user['id'], $planet_dst);
161
  foreach ($bashing_fleet_list as $fleet_row) {
162
    // Checking for ACS - each ACS count only once
163
    if ($fleet_row['fleet_group']) {
164
      $bashing_list["{$user['id']}_{$fleet_row['fleet_group']}"] = $fleet_row['fleet_start_time'];
165
    } else {
166
      $bashing_list[] = $fleet_row['fleet_start_time'];
167
    }
168
  }
169
170
  // Check for joining to ACS - if there are already fleets in ACS no checks should be done
171
  if ($mission == MT_AKS && $bashing_list["{$user['id']}_{$fleet_group}"]) {
172
    return ATTACK_ALLOWED;
173
  }
174
175
  $query = doquery("SELECT bashing_time FROM `{{bashing}}` WHERE bashing_user_id = {$user['id']} AND bashing_planet_id = {$planet_dst['id']} AND bashing_time >= {$time_limit};");
176
  while ($bashing_row = db_fetch($query)) {
177
    $bashing_list[] = $bashing_row['bashing_time'];
178
  }
179
180
  sort($bashing_list);
181
182
  $last_attack = 0;
183
  $wave = 0;
184
  $attack = 1;
185
  foreach ($bashing_list as &$bash_time) {
186
    $attack++;
187
    if ($bash_time - $last_attack > $config_bashing_interval || $attack > $config_bashing_attacks) {
188
      $attack = 1;
189
      $wave++;
190
    }
191
192
    $last_attack = $bash_time;
193
  }
194
195
  return ($wave > $config->fleet_bashing_waves ? $bashing_result : ATTACK_ALLOWED);
196
}
197
198
/**
199
 * @param array $planet_src - source planet record/vector
200
 * @param array $planet_dst - destination planet record/vector
201
 * @param array $fleet      - array of ship amount [(int)shipId => (float)shipAmount]
202
 * @param int   $mission    - Mission ID
203
 * @param array $options    - [
204
 *                          P_FLEET_ATTACK_RESOURCES_SUM       => (float),
205
 *                          P_FLEET_ATTACK_RES_LIST            => [(int)resId => (float)amount]
206
 *                          P_FLEET_ATTACK_SPEED_PERCENT_TENTH => (int)1..10
207
 *                          P_FLEET_ATTACK_FLEET_GROUP         => (int|string)
208
 *                          P_FLEET_ATTACK_FLYING_COUNT        => (int)
209
 *                          P_FLEET_ATTACK_TARGET_STRUCTURE    => (int) - targeted defense structure snID for MISSILE missions
210
 *                          P_FLEET_ATTACK_STAY_TIME           => (int) - stay HOURS
211
 *                          ]
212
 *
213
 * @return int
214
 */
215
function flt_can_attack($planet_src, $planet_dst, $fleet = [], $mission, $options = []) {
216
  $result = null;
217
218
  return sn_function_call('flt_can_attack', [$planet_src, $planet_dst, $fleet, $mission, $options, &$result]);
219
}
220
221
/**
222
 * @param array $planet_src
223
 * @param array $planet_dst
224
 * @param array $fleet
225
 * @param int   $mission
226
 * @param array $options
227
 * @param int   $result
228
 *
229
 * @return int
230
 * @see flt_can_attack()
231
 */
232
function sn_flt_can_attack($planet_src, $planet_dst, $fleet = [], $mission, $options = [], &$result) {
233
  //TODO: try..catch
234
  global $config, $user;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
235
236
  if ($user['vacation']) {
237
    return $result = ATTACK_OWN_VACATION;
238
  }
239
240
  if (empty($fleet) || !is_array($fleet)) {
241
    return $result = ATTACK_NO_FLEET;
242
  }
243
244
  !is_array($options) ? $options = [] : false;
0 ignored issues
show
introduced by
The condition is_array($options) is always true.
Loading history...
245
246
  $sn_groups_mission = sn_get_groups('missions');
247
  if (!isset($sn_groups_mission[$mission])) {
248
    return $result = ATTACK_MISSION_ABSENT;
249
  }
250
  $sn_data_mission = $sn_groups_mission[$mission];
251
252
//TODO: Проверка на отстуствие ресурсов в нетранспортных миссиях (Транспорт, Передислокация, Колонизация)
253
254
  //TODO: Проверка на наличие ресурсов при Транспорте
255
  // TODO: Проверка на отрицательные ресурсы при транспорте
256
  // TODO: Проверка на перегрузку при транспорте
257
258
  // TODO: В ракетных миссиях могут лететь только ракеты
259
  // TODO: В неракетных миссиях ракеты должны отсутствовать
260
  $ships = 0;
261
  $recyclers = 0;
262
  $spies = 0;
263
  $resources = 0;
264
  $ship_ids = sn_get_groups('fleet');
265
  $resource_ids = sn_get_groups('resources_loot');
266
  foreach ($fleet as $ship_id => $ship_count) {
267
    $is_ship = in_array($ship_id, $ship_ids);
268
    $is_resource = in_array($ship_id, $resource_ids);
269
    if (!$is_ship && !$is_resource) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
270
      // TODO Спецобработчик для Капитана и модулей
271
//      return ATTACK_WRONG_UNIT;
272
    }
273
274
    if ($ship_count < 0) {
275
      return $result = $is_ship ? ATTACK_SHIP_COUNT_WRONG : ATTACK_RESOURCE_COUNT_WRONG;
276
    }
277
278
    if ($ship_count > mrc_get_level($user, $planet_src, $ship_id)) {
279
      // TODO ATTACK_NO_MISSILE
280
      return $result = $is_ship ? ATTACK_NO_SHIPS : ATTACK_NO_RESOURCES;
281
    }
282
283
    if ($is_ship) {
284
      $single_ship_data = get_ship_data($ship_id, $user);
285
      if ($single_ship_data[P_SPEED] <= 0) {
286
        return $result = ATTACK_ZERO_SPEED;
287
      }
288
      $ships += $ship_count;
289
      $recyclers += in_array($ship_id, sn_get_groups('flt_recyclers')) ? $ship_count : 0;
290
      $spies += $ship_id == SHIP_SPY ? $ship_count : 0;
291
    } elseif ($is_resource) {
292
      $resources += $ship_count;
293
    }
294
  }
295
296
  if (empty($resources) && !empty($options[P_FLEET_ATTACK_RES_LIST]) && is_array($options[P_FLEET_ATTACK_RES_LIST])) {
297
    $resources = array_sum($options[P_FLEET_ATTACK_RES_LIST]);
298
  }
299
300
  /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
301
    if($ships < 1) {
302
      return ATTACK_NO_FLEET;
303
    }
304
  */
305
306
  if (
307
    isset($options[P_FLEET_ATTACK_RESOURCES_SUM])
308
    && $options[P_FLEET_ATTACK_RESOURCES_SUM] > 0
309
    && !empty($sn_data_mission['transport'])
310
  ) {
311
    return $result = ATTACK_RESOURCE_FORBIDDEN;
312
  }
313
314
  /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
315
    elseif($mission == MT_TRANSPORT)
316
    {
317
      return ATTACK_TRANSPORT_EMPTY;
318
    }
319
  */
320
321
  $speed = $options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH];
322
  if ($speed && ($speed != intval($speed) || $speed < 1 || $speed > 10)) {
323
    return $result = ATTACK_WRONG_SPEED;
324
  }
325
326
  $travel_data = flt_travel_data($user, $planet_src, $planet_dst, $fleet, $options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH]);
327
328
329
  if (mrc_get_level($user, $planet_src, RES_DEUTERIUM) < $fleet[RES_DEUTERIUM] + $travel_data['consumption']) {
330
    return $result = ATTACK_NO_FUEL;
331
  }
332
333
  if ($travel_data['consumption'] > $travel_data['capacity']) {
334
    return $result = ATTACK_TOO_FAR;
335
  }
336
337
  if ($travel_data['hold'] < $resources) {
338
    return $result = ATTACK_OVERLOADED;
339
  }
340
341
  $fleet_start_time = SN_TIME_NOW + $travel_data['duration'];
342
343
  $fleet_group = $options[P_FLEET_ATTACK_FLEET_GROUP];
344
  if ($fleet_group) {
345
    if ($mission != MT_AKS) {
346
      return $result = ATTACK_WRONG_MISSION;
347
    };
348
349
    $acs = doquery("SELECT * FROM `{{aks}}` WHERE id = '{$fleet_group}' LIMIT 1;", '', true);
350
    if (!$acs['id']) {
351
      return $result = ATTACK_NO_ACS;
352
    }
353
354
    if ($planet_dst['galaxy'] != $acs['galaxy'] || $planet_dst['system'] != $acs['system'] || $planet_dst['planet'] != $acs['planet'] || $planet_dst['planet_type'] != $acs['planet_type']) {
355
      return $result = ATTACK_ACS_WRONG_TARGET;
356
    }
357
358
    if ($fleet_start_time > $acs['ankunft']) {
359
      return $result = ATTACK_ACS_TOO_LATE;
360
    }
361
  }
362
363
  $flying_fleets = $options[P_FLEET_ATTACK_FLYING_COUNT];
364
  if (!$flying_fleets) {
365
    $flying_fleets = DbFleetStatic::fleet_count_flying($user['id']);
366
  }
367
  if (GetMaxFleets($user) <= $flying_fleets && $mission != MT_MISSILE) {
368
    return $result = ATTACK_NO_SLOTS;
369
  }
370
371
  // В одиночку шпионские зонды могут летать только в миссии Шпионаж, Передислокация и Транспорт
372
  if ($ships && $spies && $spies == $ships && !($mission == MT_SPY || $mission == MT_RELOCATE || $mission == MT_TRANSPORT)) {
373
    return $result = ATTACK_SPIES_LONLY;
374
  }
375
376
  // Checking for no planet
377
  if (!$planet_dst['id_owner']) {
378
    if ($mission == MT_COLONIZE && !$fleet[SHIP_COLONIZER]) {
379
      return $result = ATTACK_NO_COLONIZER;
380
    }
381
382
    if ($mission == MT_EXPLORE || $mission == MT_COLONIZE) {
383
      return $result = ATTACK_ALLOWED;
384
    }
385
386
    return $result = ATTACK_NO_TARGET;
387
  }
388
389
  if ($mission == MT_RECYCLE) {
390
    if ($planet_dst['debris_metal'] + $planet_dst['debris_crystal'] <= 0) {
391
      return $result = ATTACK_NO_DEBRIS;
392
    }
393
    if ($recyclers <= 0) {
394
      return $result = ATTACK_NO_RECYCLERS;
395
    }
396
397
    return $result = ATTACK_ALLOWED;
398
  }
399
400
  // Got planet. Checking if it is ours
401
  if ($planet_dst['id_owner'] == $user['id']) {
402
    if ($mission == MT_TRANSPORT || $mission == MT_RELOCATE) {
403
      return $result = ATTACK_ALLOWED;
404
    }
405
406
    return $planet_src['id'] == $planet_dst['id'] ? ATTACK_SAME : ATTACK_OWN;
407
  }
408
409
  // No, planet not ours. Cutting mission that can't be send to not-ours planet
410
  if ($mission == MT_RELOCATE || $mission == MT_COLONIZE || $mission == MT_EXPLORE) {
411
    return $result = ATTACK_WRONG_MISSION;
412
  }
413
414
  $enemy = db_user_by_id($planet_dst['id_owner']);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

414
  $enemy = /** @scrutinizer ignore-deprecated */ db_user_by_id($planet_dst['id_owner']);
Loading history...
415
  // We cannot attack or send resource to users in VACATION mode
416
  if ($enemy['vacation'] && $mission != MT_RECYCLE) {
417
    return $result = ATTACK_VACATION;
418
  }
419
420
  // Multi IP protection
421
  // TODO: Here we need a procedure to check proxies
422
  if (sys_is_multiaccount($user, $enemy)) {
423
    return $result = ATTACK_SAME_IP;
424
  }
425
426
  $user_points = $user['total_points'];
427
  $enemy_points = $enemy['total_points'];
428
429
  // Is it transport? If yes - checking for buffing to prevent mega-alliance destroyer
430
  if ($mission == MT_TRANSPORT) {
431
    if ($user_points >= $enemy_points || $config->allow_buffing) {
432
      return $result = ATTACK_ALLOWED;
433
    } else {
434
      return $result = ATTACK_BUFFING;
435
    }
436
  }
437
438
  // Only aggresive missions passed to this point. HOLD counts as passive but aggresive
439
440
  // Is it admin with planet protection?
441
  if ($planet_dst['id_level'] > $user['authlevel']) {
442
    return $result = ATTACK_ADMIN;
443
  }
444
445
  // Okay. Now skipping protection checks for inactive longer then 1 week
446
  if (!$enemy['onlinetime'] || $enemy['onlinetime'] >= (SN_TIME_NOW - 60 * 60 * 24 * 7)) {
447
    if (
448
      (SN::$gc->general->playerIsNoobByPoints($enemy_points) && !SN::$gc->general->playerIsNoobByPoints($user_points))
449
      ||
450
      (SN::$gc->general->playerIs1stStrongerThen2nd($user_points, $enemy_points))
451
    ) {
452
      if ($mission != MT_HOLD) {
453
        return $result = ATTACK_NOOB;
454
      }
455
      if ($mission == MT_HOLD && !($user['ally_id'] && $user['ally_id'] == $enemy['ally_id'] && $config->ally_help_weak)) {
456
        return $result = ATTACK_NOOB;
457
      }
458
    }
459
  }
460
461
  // Is it HOLD mission? If yes - there should be ally deposit
462
  if ($mission == MT_HOLD) {
463
    if (mrc_get_level($user, $planet_dst, STRUC_ALLY_DEPOSIT)) {
464
      return $result = ATTACK_ALLOWED;
465
    }
466
467
    return $result = ATTACK_NO_ALLY_DEPOSIT;
468
  }
469
470
  if ($mission == MT_SPY) {
471
    return $result = $spies >= 1 ? ATTACK_ALLOWED : ATTACK_NO_SPIES;
472
  }
473
474
  // Is it MISSILE mission?
475
  if ($mission == MT_MISSILE) {
476
    $sn_data_mip = get_unit_param(UNIT_DEF_MISSILE_INTERPLANET);
477
    if (mrc_get_level($user, $planet_src, STRUC_SILO) < $sn_data_mip[P_REQUIRE][STRUC_SILO]) {
478
      return $result = ATTACK_NO_SILO;
479
    }
480
481
    if (!$fleet[UNIT_DEF_MISSILE_INTERPLANET]) {
482
      return $result = ATTACK_NO_MISSILE;
483
    }
484
485
    $distance = abs($planet_dst['system'] - $planet_src['system']);
486
    $mip_range = flt_get_missile_range($user);
487
    if ($distance > $mip_range || $planet_dst['galaxy'] != $planet_src['galaxy']) {
488
      return $result = ATTACK_MISSILE_TOO_FAR;
489
    }
490
491
    if (!empty($options[P_FLEET_ATTACK_TARGET_STRUCTURE]) && !in_array($options[P_FLEET_ATTACK_TARGET_STRUCTURE], sn_get_groups('defense_active'))) {
492
      return $result = ATTACK_WRONG_STRUCTURE;
493
    }
494
  }
495
496
  if ($mission == MT_DESTROY && $planet_dst['planet_type'] != PT_MOON) {
497
    return $result = ATTACK_WRONG_MISSION;
498
  }
499
500
  if ($mission == MT_ATTACK || $mission == MT_AKS || $mission == MT_DESTROY) {
501
    return $result = flt_bashing_check($user, $enemy, $planet_dst, $mission, $travel_data['duration'], $fleet_group);
502
  }
503
504
  return $result = ATTACK_ALLOWED;
505
}
506
507
/**
508
 * @param array $user    - actual user record
509
 * @param array $from    - actual planet record
510
 * @param array $to      - actual planet record
511
 * @param array $fleet   - array of records $unit_id -> $amount
512
 * @param int   $mission - fleet mission
513
 * @param array $options
514
 *
515
 * @return int
516
 * @throws Exception
517
 * @see flt_can_attack()
518
 */
519
function flt_t_send_fleet($user, &$from, $to, $fleet, $resources, $mission, $options = array()) {
520
  $internal_transaction = !sn_db_transaction_check(false) ? sn_db_transaction_start() : false;
521
522
  // TODO Потенциальный дедлок - если успела залочится запись пользователя - хозяина планеты
523
  $user = db_user_by_id($user['id'], true);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_by_id() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

523
  $user = /** @scrutinizer ignore-deprecated */ db_user_by_id($user['id'], true);
Loading history...
524
  $from = sys_o_get_updated($user, $from['id'], SN_TIME_NOW);
525
  $from = $from['planet'];
526
527
//  $fleet = [
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
528
//    202 => 1,
529
//  ];
530
//  $resources = [
531
//    901 => 1,
532
//  ];
533
//  var_dump($fleet);
534
//  var_dump($resources);
535
//  var_dump(mrc_get_level($user, $from, 202));
536
//  var_dump($from['metal']);
537
//  var_dump($from['deuterium']);
538
//  die();
539
540
541
  !is_array($resources) ? $resources = [] : false;
542
  if(empty($options[P_FLEET_ATTACK_RES_LIST])) {
543
    $options[P_FLEET_ATTACK_RES_LIST] = $resources;
544
  }
545
  $can_attack = flt_can_attack($from, $to, $fleet, $mission, $options);
546
  if ($can_attack != ATTACK_ALLOWED) {
547
    $internal_transaction ? sn_db_transaction_rollback() : false;
548
549
    return $can_attack;
550
  }
551
552
  empty($options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH]) ? $options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH] = 10 : false;
553
  $options[P_FLEET_ATTACK_STAY_TIME] = !empty($options[P_FLEET_ATTACK_STAY_TIME]) ? $options[P_FLEET_ATTACK_STAY_TIME] * PERIOD_HOUR : 0;
554
555
  $fleetObj = new Fleet();
556
  $travel_data = $fleetObj
557
    ->setMission($mission)
558
    ->setSourceFromPlanetRecord($from)
559
    ->setDestinationFromPlanetRecord($to)
560
    ->setUnits($fleet)
561
    ->setUnits($resources)
562
    ->setSpeedPercentInTenth($options[P_FLEET_ATTACK_SPEED_PERCENT_TENTH])
563
    ->calcTravelTimes(SN_TIME_NOW, $options[P_FLEET_ATTACK_STAY_TIME]);
564
  $fleetObj->save();
565
566
  $result = fltSendFleetAdjustPlanetResources($from['id'], $resources, $travel_data['consumption']);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
567
568
  $result = fltSendFleetAdjustPlanetUnits($user, $from['id'], $fleet);
569
570
  $internal_transaction ? sn_db_transaction_commit() : false;
571
572
  $from = DBStaticPlanet::db_planet_by_id($from['id']);
573
574
//  var_dump(mrc_get_level($user, $from, 202));
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% 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...
575
//  var_dump($from['metal']);
576
//  var_dump($from['deuterium']);
577
//  die();
578
579
  return ATTACK_ALLOWED;
580
}
581
582
/**
583
 * @param array      $user
584
 * @param int|string $fromId
585
 * @param float[]    $fleet - [(int)shipId => (float)count]
586
 *
587
 * @return bool
588
 */
589
function fltSendFleetAdjustPlanetUnits($user, $fromId, $fleet) {
590
  $result = [];
591
592
  foreach ($fleet as $unit_id => $amount) {
593
    if (floatval($amount) >= 1 && intval($unit_id) && in_array($unit_id, sn_get_groups('fleet'))) {
594
      $result[] = OldDbChangeSet::db_changeset_prepare_unit($unit_id, -$amount, $user, $fromId);
0 ignored issues
show
Deprecated Code introduced by
The function DBAL\OldDbChangeSet::db_changeset_prepare_unit() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

594
      $result[] = /** @scrutinizer ignore-deprecated */ OldDbChangeSet::db_changeset_prepare_unit($unit_id, -$amount, $user, $fromId);
Loading history...
595
    }
596
  }
597
598
  return OldDbChangeSet::db_changeset_apply(['unit' => $result]);
0 ignored issues
show
Deprecated Code introduced by
The function DBAL\OldDbChangeSet::db_changeset_apply() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

598
  return /** @scrutinizer ignore-deprecated */ OldDbChangeSet::db_changeset_apply(['unit' => $result]);
Loading history...
599
}
600
601
/**
602
 * @param int|string $fromId      - Source planet ID
603
 * @param array      $resources   - Array of resources to transfer [(int)resourceId => (float)amount]
604
 * @param int|float  $consumption - Fleet consumption
605
 *
606
 * @return bool
607
 *
608
 * @throws Exception
609
 */
610
function fltSendFleetAdjustPlanetResources($fromId, $resources, $consumption) {
611
  $planetObj = SN::$gc->repoV2->getPlanet($fromId);
612
613
  $planetObj->changeResource(RES_DEUTERIUM, -$consumption);
614
615
  foreach ($resources as $resource_id => $amount) {
616
    if (floatval($amount) >= 1 && intval($resource_id) && in_array($resource_id, sn_get_groups('resources_loot'))) {
617
      $planetObj->changeResource($resource_id, -$amount);
618
    }
619
  }
620
621
  return $planetObj->save();
622
}
623
624
function flt_calculate_ship_to_transport_sort($a, $b) {
625
  return $a['transport_effectivness'] == $b['transport_effectivness'] ? 0 : ($a['transport_effectivness'] > $b['transport_effectivness'] ? -1 : 1);
626
}
627
628
// flt_calculate_ship_to_transport - calculates how many ships need to transport pointed amount of resources
629
// $ship_list - list of available ships
630
// $resource_amount - how much amount of resources need to be transported
631
// $from - transport from
632
// $to - transport to
633
function flt_calculate_fleet_to_transport($ship_list, $resource_amount, $from, $to) {
634
  global $user;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
635
636
  $ship_data = array();
637
  $fleet_array = array();
638
  foreach ($ship_list as $transport_id => $cork) {
639
    $ship_data[$transport_id] = flt_travel_data($user, $from, $to, array($transport_id => 1), 10);
640
  }
641
  uasort($ship_data, 'flt_calculate_ship_to_transport_sort');
642
643
  $fleet_hold = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $fleet_hold is dead and can be removed.
Loading history...
644
  $fleet_capacity = 0;
645
  $fuel_total = $fuel_left = mrc_get_level($user, $from, RES_DEUTERIUM);
646
  foreach ($ship_data as $transport_id => &$ship_info) {
647
    $ship_loaded = min($ship_list[$transport_id], ceil($resource_amount / $ship_info['hold']), floor($fuel_left / $ship_info['consumption']));
648
    if ($ship_loaded) {
649
      $fleet_array[$transport_id] = $ship_loaded;
650
      $resource_amount -= min($resource_amount, $ship_info['hold'] * $ship_loaded);
651
      $fuel_left -= $ship_info['consumption'] * $ship_loaded;
652
653
      $fleet_capacity += $ship_info['capacity'] * $ship_loaded;
654
    }
655
  }
656
657
  return array('fleet' => $fleet_array, 'ship_data' => $ship_data, 'capacity' => $fleet_capacity, 'consumption' => $fuel_total - $fuel_left);
658
}
659