Completed
Branch work-fleets (5b06a4)
by SuperNova.WS
04:52
created

flotenajax.php (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * flotenajax.php
5
 *
6
 * Fleet manager on Ajax (to work in Galaxy view)
7
 *
8
 * @version 2.0 Security checks by Gorlum for http://supernova.ws
9
 *  [!] Full rewrite
10
 *  [+] Added missile attack launch sequience
11
 *  [-] Moved almost all check code to flt_can_attack
12
 * @version 1.1 Security checks by Gorlum for http://supernova.ws
13
 * @version 1
14
 * @copyright 2008 By Chlorel for XNova
15
 **/
16
17
include('common.' . substr(strrchr(__FILE__, '.'), 1));
18
19
define('IN_AJAX', true);
20
21
require_once('includes/includes/flt_functions.php');
22
23
/**
24
 * @throws Exception
25
 */
26
function fleet_ajax() {
27
  global $user;
28
29
  classLocale::$lang->lng_include('universe');
30
  classLocale::$lang->lng_include('fleet');
31
32
  $travel_data = array();
33
34
  // TODO - change to JSON. Message can be sent in JSON-encoded field
35
  header("Content-type: text/html; charset=utf-8");
36
37
  $target_mission = sys_get_param_int('mission');
38
  $sn_group_missions = sn_get_groups('missions');
39
  if(empty($sn_group_missions[$target_mission]['AJAX'])) {
40
    die(classLocale::$lang['gs_c00']);
41
  }
42
43
  // Checking target coordinates validity
44
  $target_coord = array(
45
    'id'          => null,
46
    'id_owner'    => 0,
47
    'galaxy'      => sys_get_param_int('galaxy'),
48
    'system'      => sys_get_param_int('system'),
49
    'planet'      => sys_get_param_int('planet'),
50
    'planet_type' => sys_get_param_int('planet_type'),
51
  );
52
  // fleet_ajax now can send fleets only to existing planets/moons
53
  // TODO - sending colonization and expeditions in 1 click
54
  if(!uni_coordinates_valid($target_coord)) {
55
    die(classLocale::$lang['gs_c02']);
56
  }
57
58
  sn_db_transaction_start();
59
60
  $user = db_user_by_id($user['id'], true);
61
  $planetrow = db_planet_by_id($user['current_planet'], true);
62
63
  // TODO - DEADLOCK CAN BE HERE!!!! We should lock SOURCE and TARGET owners in one query
64
  $target_row = db_planet_by_vector($target_coord);
65
  if(empty($target_row)) {
66
    $target_row = $target_coord;
67
    $target_row['id_owner'] = 0;
68
    // If fleet destination is PT_DEBRIS - then it's actually destination is PT_PLANET // TODO - REMOVE! Debris should be valid DESTINATION planet_type!
69
    $target_row['planet_type'] = $target_row['planet_type'] == PT_DEBRIS ? PT_PLANET : $target_row['planet_type'];
70
  } else {
71
    $target_coord['id'] = $target_row['id'];
72
    $target_coord['id_owner'] = $target_row['id_owner'];
73
  }
74
75
  $fleet_array = array();
76
  switch($target_mission) {
77
    case MT_SPY:
78
      $fleet_array[SHIP_SPY] = min(mrc_get_level($user, $planetrow, SHIP_SPY), abs(classSupernova::$user_options[PLAYER_OPTION_FLEET_SPY_DEFAULT]));
0 ignored issues
show
It seems like $planetrow defined by db_planet_by_id($user['current_planet'], true) on line 61 can also be of type false; however, mrc_get_level() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
79
      $unit_group = 'flt_spies';
80
    break;
81
82
    case MT_RECYCLE:
83
      foreach(sn_get_groups('flt_recyclers') as $unit_id) {
84
        if($unit_count = mrc_get_level($user, $planetrow, $unit_id)) {
0 ignored issues
show
It seems like $planetrow defined by db_planet_by_id($user['current_planet'], true) on line 61 can also be of type false; however, mrc_get_level() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
85
          $fleet_array[$unit_id] = $unit_count;
86
        }
87
      }
88
      $transport_data = flt_calculate_fleet_to_transport($fleet_array, $target_row['debris_metal'] + $target_row['debris_crystal'], $planetrow, $target_row);
89
      $fleet_array = $transport_data['fleet'];
90
      $unit_group = 'flt_recyclers';
91
    break;
92
93
    case MT_MISSILE:
94
      $fleet_array[UNIT_DEF_MISSILE_INTERPLANET] = min(mrc_get_level($user, $planetrow, UNIT_DEF_MISSILE_INTERPLANET), abs(sys_get_param_float('missiles')));
0 ignored issues
show
It seems like $planetrow defined by db_planet_by_id($user['current_planet'], true) on line 61 can also be of type false; however, mrc_get_level() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
95
      $unit_group = 'missile';
96
    break;
97
98
  }
99
100
  $isAttackAllowed = flt_can_attack(
101
    $planetrow,
102
    $target_row,
103
    $fleet_array,
104
    $target_mission,
105
    array(
0 ignored issues
show
array('target_structure'...aram_int('structures')) is of type array<string,integer,{"t..._structure":"integer"}>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
106
      'target_structure' => $target_structure = sys_get_param_int('structures'),
107
    )
108
  );
109
  if($isAttackAllowed != ATTACK_ALLOWED) {
110
    die(classLocale::$lang['fl_attack_error'][$isAttackAllowed]);
111
  }
112
113
  $db_changeset = array();
114
  foreach($fleet_array as $unit_id => $unit_count) {
115
    $db_changeset['unit'][] = sn_db_unit_changeset_prepare($unit_id, -$unit_count, $user, $planetrow);
116
  }
117
118
  if($target_mission == MT_MISSILE) {
119
    $distance = abs($target_coord['system'] - $planetrow['system']);
120
    $duration = round((30 + (60 * $distance)) / flt_server_flight_speed_multiplier());
121
    $arrival = SN_TIME_NOW + $duration;
122
    $travel_data['consumption'] = 0;
123
124
    db_missile_insert($target_coord, $user, $planetrow, $arrival, array_sum($fleet_array), $target_structure);
125
  } else {
126
    $travel_data = flt_travel_data($user, $planetrow, $target_coord, $fleet_array, 10);
127
128
    if($planetrow['deuterium'] < $travel_data['consumption']) {
129
      die(classLocale::$lang['gs_c13']);
130
    }
131
132
    $objFleet = new Fleet();
133
    $objFleet->set_times($travel_data['duration']);
134
    $objFleet->unitsSetFromArray($fleet_array);
135
    $objFleet->mission_type = $target_mission;
136
    $objFleet->set_start_planet($planetrow);
137
    $objFleet->set_end_planet($target_coord);
138
    $objFleet->playerOwnerId = $user['id'];
139
    $objFleet->group_id = 0;
140
    $objFleet->dbInsert();
141
  }
142
143
  db_planet_set_by_id($planetrow['id'], "`deuterium` = `deuterium` - {$travel_data['consumption']}");
144
  db_changeset_apply($db_changeset);
145
  sn_db_transaction_commit();
146
147
  $ships_sent = array();
148
  $ships_sent_js = 0;
149
  foreach($fleet_array as $unit_id => $unit_count) {
150
    $classLocale = classLocale::$lang;
151
    $ships_sent[] = "{$unit_count} {$classLocale['tech'][$unit_id]}";
152
    $ships_sent_js += mrc_get_level($user, $planetrow, $unit_id, false, true);
0 ignored issues
show
It seems like $planetrow defined by db_planet_by_id($user['current_planet'], true) on line 61 can also be of type false; however, mrc_get_level() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
153
  }
154
  $ships_sent = implode(', ', $ships_sent);
155
  $ships_sent_js = "{$unit_group}={$ships_sent_js}";
0 ignored issues
show
The variable $unit_group does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
156
157
  $classLocale1 = classLocale::$lang;
158
  $classLocale2 = classLocale::$lang;
159
  $ResultMessage = "{$classLocale1['gs_sending']} {$ships_sent} {$classLocale2['gs_to']} {$target_coord['galaxy']}:{$target_coord['system']}:{$target_coord['planet']}|{$ships_sent_js}";
160
161
  die($ResultMessage);
162
}
163
164
fleet_ajax();
165