Completed
Push — work-fleets ( 046d2e...0cb966 )
by SuperNova.WS
07:26
created

general.php ➔ setNull()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
/*
4
Function wrapping
5
6
Due glitch in PHP 5.3.1 SuperNova is incompatible with this version
7
Reference: https://bugs.php.net/bug.php?id=50394
8
9
*/
10
11
require_once('general/math.php');
12
require_once('general_pname.php');
13
14
/**
15
 * @param       $func_name
16
 * @param array $func_arg
17
 *
18
 * @return mixed
19
 */
20
function sn_function_call($func_name, $func_arg = array()) {
21
  // All data in classSupernova::$functions should be normalized to valid 'callable' state: '<function_name>'|array('<object_name>', '<method_name>')
22
  $result = null;
23
24
  if (is_array(classSupernova::$functions[$func_name]) && !is_callable(classSupernova::$functions[$func_name])) {
25
    // Chain-callable functions should be made as following:
26
    // 1. Never use incomplete calls with parameters "by default"
27
    // 2. Reserve last parameter for cumulative result
28
    // 3. Use same format for original value and cumulative result (if there is original value)
29
    // 4. Honor cumulative result
30
    // 5. Return cumulative result
31
    foreach (classSupernova::$functions[$func_name] as $func_chain_name) {
32
      // По идее - это уже тут не нужно, потому что оно все должно быть callable к этому моменту
33
      // Но для старых модулей...
34
      if (is_callable($func_chain_name)) {
35
        $result = call_user_func_array($func_chain_name, $func_arg);
36
      }
37
    }
38
  } else {
39
    // TODO: This is left for backward compatibility. Appropriate code should be rewrote!
40
    $func_name = isset(classSupernova::$functions[$func_name]) && is_callable(classSupernova::$functions[$func_name]) ? classSupernova::$functions[$func_name] : ('sn_' . $func_name);
41
    if (is_callable($func_name)) {
42
      $result = call_user_func_array($func_name, $func_arg);
43
    }
44
  }
45
46
  return $result;
47
}
48
49
/**
50
 * @param        $hook_list
51
 * @param        $template
52
 * @param string $hook_type - тип хука 'model' или 'view'
53
 * @param string $page_name - имя страницы, для которого должен был быть выполнен хук
54
 */
55
function execute_hooks(&$hook_list, &$template, $hook_type = null, $page_name = null) {
56
  if (!empty($hook_list)) {
57
    foreach ($hook_list as $hook) {
58
      if (is_callable($hook_call = (is_string($hook) ? $hook : (is_array($hook) ? $hook['callable'] : $hook->callable)))) {
59
        $template = call_user_func($hook_call, $template, $hook_type, $page_name);
60
      }
61
    }
62
  }
63
}
64
65
// ----------------------------------------------------------------------------------------------------------------
66
function sys_file_read($filename) {
67
  return @file_get_contents($filename);
68
}
69
70
function sys_file_write($filename, $content) {
71
  return @file_put_contents($filename, $content, FILE_APPEND);
72
}
73
74
function get_game_speed($plain = false) { return sn_function_call(__FUNCTION__, array($plain, &$result)); }
75
76
function sn_get_game_speed($plain = false, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $plain is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
77
  return $result = classSupernova::$config->game_speed ? classSupernova::$config->game_speed : 1;
78
}
79
80
function flt_server_flight_speed_multiplier($plain = false) { return sn_function_call(__FUNCTION__, array($plain, &$result)); }
81
82
function sn_flt_server_flight_speed_multiplier($plain = false, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $plain is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
83
  return $result = classSupernova::$config->fleet_speed;
84
}
85
86
function game_resource_multiplier($plain = false) { return sn_function_call(__FUNCTION__, array($plain, &$result)); }
87
88
function sn_game_resource_multiplier($plain = false, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $plain is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
89
  return $result = classSupernova::$config->resource_multiplier;
90
}
91
92
/**
93
 * Получение стоимости ММ в валюте сервера
94
 *
95
 * @param bool|false $plain
96
 *
97
 * @return mixed
98
 */
99
function get_mm_cost($plain = false) { return sn_function_call(__FUNCTION__, array($plain, &$result)); }
100
101
function sn_get_mm_cost($plain = false, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $plain is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
102
  return $result = classSupernova::$config->payment_currency_exchange_mm_ ? classSupernova::$config->payment_currency_exchange_mm_ : METAMATTER_DEFAULT_LOT_SIZE;
103
}
104
105
/**
106
 * Получение курса обмены валюты в серверную валюту
107
 *
108
 * @param $currency_symbol
109
 *
110
 * @return float
111
 */
112
function get_exchange_rate($currency_symbol) {
113
  $currency_symbol = strtolower($currency_symbol);
114
  $config_field = 'payment_currency_exchange_' . $currency_symbol;
115
116
  // Заворачиваем получение стоимости ММ через перекрываемую процедуру
117
  $exchange_rate = floatval($currency_symbol == 'mm_' ? get_mm_cost() : classSupernova::$config->$config_field);
118
119
  return $exchange_rate;
120
}
121
122
/**
123
 * pretty_number implementation for SuperNova
124
 *
125
 * $n - number to format
126
 * $floor: (ignored if $limit set)
127
 * integer   - floors to $floor numbers after decimal points
128
 * true      - floors number before format
129
 * otherwise - floors to 2 numbers after decimal points
130
 * $color:
131
 * true    - colors number to green if positive or zero; red if negative
132
 * 0
133
 * numeric - colors number to green if less then $color; red if greater
134
 * $limit:
135
 * 0/false - proceed with $floor
136
 * numeric - divides number to segments by power of $limit and adds 'k' for each segment
137
 * makes sense for 1000, but works with any number
138
 * generally converts "15000" to "15k", "2000000" to "2kk" etc
139
 * $style
140
 * null  - standard result
141
 * true  - return only style class for current params
142
 * false - return array('text' => $ret, 'class' => $class), where $ret - unstyled
143
 */
144
145
/**
146
 * @param float     $n
147
 * @param int|bool  $floor
148
 * @param int|bool  $color
149
 * @param int|bool  $limit
150
 * @param bool|null $style
151
 *
152
 * @return array|float|string
153
 */
154
function pretty_number($n, $floor = true, $color = false, $limit = false, $style = null) {
155
  $n = floatval($n);
156
  if (is_int($floor)) {
157
    $n = round($n, $floor); // , PHP_ROUND_HALF_DOWN
158
  } elseif ($floor === true) {
159
    $n = floor($n);
160
    $floor = 0;
161
  } else {
162
    $floor = 2;
163
  }
164
165
  $ret = $n;
166
167
  $suffix = '';
168
  if ($limit) {
169
    if ($ret > 0) {
170
      while ($ret > $limit) {
171
        $suffix .= 'k';
172
        $ret = round($ret / 1000);
173
      }
174
    } else {
175
      while ($ret < -$limit) {
176
        $suffix .= 'k';
177
        $ret = round($ret / 1000);
178
      }
179
    }
180
  }
181
182
  $ret = number_format($ret, $floor, ',', '.');
183
  $ret .= $suffix;
184
185
  if ($color !== false) {
186
    if ($color === true) {
187
      $class = $n == 0 ? 'zero' : ($n > 0 ? 'positive' : 'negative');
188
    } elseif ($color >= 0) {
189
      $class = $n == $color ? 'zero' : ($n < $color ? 'positive' : 'negative');
190
    } else {
191
      $class = ($n == -$color) ? 'zero' : ($n < -$color ? 'negative' : 'positive');
192
    }
193
194
    if (!isset($style)) {
195
      $ret = "<span class='{$class}'>{$ret}</span>";
196
    } else {
197
      $ret = $style ? $ret = $class : $ret = array('text' => $ret, 'class' => $class);
198
    }
199
  }
200
201
  return $ret;
202
}
203
204
// ----------------------------------------------------------------------------------------------------------------
205
function pretty_time($seconds) {
206
  $day = floor($seconds / (24 * 3600));
207
208
  $sys_day_short = classLocale::$lang['sys_day_short'];
209
210
  return sprintf("%s%02d:%02d:%02d", $day ? "{$day}{$sys_day_short} " : '', floor($seconds / 3600 % 24), floor($seconds / 60 % 60), floor($seconds / 1 % 60));
211
}
212
213
// ----------------------------------------------------------------------------------------------------------------
214
function eco_planet_fields_max($planet) {
215
  return $planet['field_max'] + ($planet['planet_type'] == PT_PLANET ? mrc_get_level($user, $planet, STRUC_TERRAFORMER) * 5 : (mrc_get_level($user, $planet, STRUC_MOON_STATION) * 3));
216
}
217
218
// ----------------------------------------------------------------------------------------------------------------
219
function flt_get_missile_range($user) {
220
  return max(0, mrc_get_level($user, false, TECH_ENGINE_ION) * 5 - 1);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array|null.

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...
221
}
222
223
// ----------------------------------------------------------------------------------------------------------------
224
function GetSpyLevel(&$user) {
225
  return mrc_modify_value($user, false, array(MRC_SPY, TECH_SPY), 0);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array.

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...
226
}
227
228
// ----------------------------------------------------------------------------------------------------------------
229
function GetMaxFleets(&$user) {
230
  return mrc_modify_value($user, false, array(MRC_COORDINATOR, TECH_COMPUTER), 1);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array.

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...
231
}
232
233
// ----------------------------------------------------------------------------------------------------------------
234
// Check input string for forbidden words
235
//
236
function CheckInputStrings($String) {
237
  global $ListCensure;
238
239
  return preg_replace($ListCensure, '*', $String);
240
}
241
242
function is_email($email) {
243
  return (preg_match("/^[-_.[:alnum:]]+@((([[:alnum:]]|[[:alnum:]][[:alnum:]-]*[[:alnum:]])\.)+(ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|com|coop|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|info|int|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mil|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)$|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$/i", $email));
244
}
245
246
function is_id($value) {
247
//  return preg_match('/^\d+$/', $value) && ($value >= 0);
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...
248
  return is_numeric($value) && ($value + 0 >= 0);
249
}
250
251
/**
252
 * @param        $param_name
253
 * @param string $default
254
 *
255
 * @return string|array
256
 */
257
function sys_get_param($param_name, $default = '') {
258
  return $_POST[$param_name] !== null ? $_POST[$param_name] : ($_GET[$param_name] !== null ? $_GET[$param_name] : $default);
259
}
260
261
function sys_get_param_array($param_name, $default = array()) {
262
  return is_array($result = sys_get_param($param_name, $default)) ? $result : array();
0 ignored issues
show
Documentation introduced by
$default is of type array, but the function expects a string.

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...
263
}
264
265
function sys_get_param_id($param_name, $default = 0) {
266
  return is_id($value = sys_get_param($param_name, $default)) ? $value : $default;
267
}
268
269
function sys_get_param_int($param_name, $default = 0) {
270
  $value = sys_get_param($param_name, $default);
271
272
  return $value === 'on' ? 1 : ($value === 'off' ? $default : intval($value));
273
}
274
275
function sys_get_param_float($param_name, $default = 0) {
276
  return floatval(sys_get_param($param_name, $default));
277
}
278
279
function sys_get_param_escaped($param_name, $default = '') {
280
  return db_escape(sys_get_param($param_name, $default));
281
}
282
283
function sys_get_param_date_sql($param_name, $default = '2000-01-01') {
284
  $val = sys_get_param($param_name, $default);
285
286
  return preg_match(PREG_DATE_SQL_RELAXED, $val) ? $val : $default;
287
}
288
289
function sys_get_param_str_unsafe($param_name, $default = '') {
290
  return str_raw2unsafe(sys_get_param($param_name, $default));
291
}
292
293
function sys_get_param_str($param_name, $default = '') {
294
  return db_escape(sys_get_param_str_unsafe($param_name, $default));
295
}
296
297
function sys_get_param_str_both($param_name, $default = '') {
298
  $param = sys_get_param($param_name, $default);
299
  $param_unsafe = str_raw2unsafe($param);
300
301
  return array(
302
    'raw'    => $param,
303
    'unsafe' => $param_unsafe,
304
    'safe'   => db_escape($param_unsafe),
305
  );
306
}
307
308
function sys_get_param_phone($param_name, $default = '') {
0 ignored issues
show
Unused Code introduced by
The parameter $default is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
309
  $phone_raw = sys_get_param_str_unsafe($param_name, $default = '');
310
  if ($phone_raw) {
311
    $phone = $phone_raw[0] == '+' ? '+' : '';
312
    for ($i = 0; $i < strlen($phone_raw); $i++) {
313
      $ord = ord($phone_raw[$i]);
314
      if ($ord >= 48 && $ord <= 57) {
315
        $phone .= $phone_raw[$i];
316
      }
317
    }
318
    $phone = strlen($phone) < 11 ? '' : $phone;
319
  } else {
320
    $phone = '';
321
  }
322
323
  return array('raw' => $phone_raw, 'phone' => $phone);
324
}
325
326
function GetPhalanxRange($phalanx_level) {
327
  return $phalanx_level > 1 ? pow($phalanx_level, 2) - 1 : 0;
328
}
329
330
function CheckAbandonPlanetState(&$planet) {
331
  if ($planet['destruyed'] && $planet['destruyed'] <= SN_TIME_NOW) {
332
    DBStaticPlanet::db_planet_delete_by_id($planet['id']);
333
  }
334
}
335
336
function eco_get_total_cost($unit_id, $unit_level) {
337
  static $rate, $sn_group_resources_all, $sn_group_resources_loot;
338
  if (!$rate) {
339
    $sn_group_resources_all = sn_get_groups('resources_all');
340
    $sn_group_resources_loot = sn_get_groups('resources_loot');
341
342
    $rate[RES_METAL] = classSupernova::$config->rpg_exchange_metal;
343
    $rate[RES_CRYSTAL] = classSupernova::$config->rpg_exchange_crystal / classSupernova::$config->rpg_exchange_metal;
344
    $rate[RES_DEUTERIUM] = classSupernova::$config->rpg_exchange_deuterium / classSupernova::$config->rpg_exchange_metal;
345
  }
346
347
  $unit_cost_data = get_unit_param($unit_id, 'cost');
348
  if (!is_array($unit_cost_data)) {
349
    return array('total' => 0);
350
  }
351
  $factor = isset($unit_cost_data['factor']) ? $unit_cost_data['factor'] : 1;
352
  $cost_array = array(BUILD_CREATE => array(), 'total' => 0);
353
  $unit_level = $unit_level > 0 ? $unit_level : 0;
354
  foreach ($unit_cost_data as $resource_id => $resource_amount) {
355
    if (!in_array($resource_id, $sn_group_resources_all)) {
356
      continue;
357
    }
358
    $cost_array[BUILD_CREATE][$resource_id] = round($resource_amount * ($factor == 1 ? $unit_level : ((1 - pow($factor, $unit_level)) / (1 - $factor))));
359
    if (in_array($resource_id, $sn_group_resources_loot)) {
360
      $cost_array['total'] += $cost_array[BUILD_CREATE][$resource_id] * $rate[$resource_id];
361
    }
362
  }
363
364
  return $cost_array;
365
}
366
367
function sn_unit_purchase($unit_id) { }
0 ignored issues
show
Unused Code introduced by
The parameter $unit_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
368
369
function sn_unit_relocate($unit_id, $from, $to) { }
0 ignored issues
show
Unused Code introduced by
The parameter $unit_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $from is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $to is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
370
371
/**
372
 * @param array|bool|null $user
373
 * @param array|null      $planet
374
 * @param int             $unit_id
375
 * @param bool            $for_update
376
 * @param bool            $plain
377
 *
378
 * @return mixed
379
 */
380
function mrc_get_level(&$user, $planet = array(), $unit_id, $for_update = false, $plain = false) { return sn_function_call(__FUNCTION__, array(&$user, $planet, $unit_id, $for_update, $plain, &$result)); }
381
382
function sn_mrc_get_level(&$user, $planet = array(), $unit_id, $for_update = false, $plain = false, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $for_update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
383
  $mercenary_level = 0;
384
  $unit_db_name = pname_resource_name($unit_id);
385
386
  if (in_array($unit_id, sn_get_groups(array('plans', 'mercenaries', 'tech', 'artifacts')))) {
387
    $unit = DBStaticUnit::db_get_unit_by_location($user['id'], LOC_USER, $user['id'], $unit_id);
388
    $mercenary_level = is_array($unit) && $unit['unit_level'] ? $unit['unit_level'] : 0;
389
  } elseif (in_array($unit_id, sn_get_groups(array('structures', 'fleet', 'defense')))) {
390
    $unit = DBStaticUnit::db_get_unit_by_location(isset($user['id']) ? $user['id'] : $planet['id_owner'], LOC_PLANET, $planet['id'], $unit_id);
391
    $mercenary_level = is_array($unit) && $unit['unit_level'] ? $unit['unit_level'] : 0;
392
  } elseif (in_array($unit_id, sn_get_groups('governors'))) {
393
    $mercenary_level = $unit_id == $planet['PLANET_GOVERNOR_ID'] ? $planet['PLANET_GOVERNOR_LEVEL'] : 0;
394
  } elseif ($unit_id == RES_DARK_MATTER) {
395
    $mercenary_level = $user[$unit_db_name] + ($plain || $user['user_as_ally'] ? 0 : classSupernova::$auth->account->account_metamatter);
396
  } elseif ($unit_id == RES_METAMATTER) {
397
    $mercenary_level = classSupernova::$auth->account->account_metamatter; //$user[$unit_db_name];
398
  } elseif (in_array($unit_id, sn_get_groups(array('resources_loot'))) || $unit_id == UNIT_SECTOR) {
399
    $mercenary_level = !empty($planet) ? $planet[$unit_db_name] : $user[$unit_db_name];
400
  }
401
402
  return $result = $mercenary_level;
403
}
404
405
function mrc_modify_value(&$user, $planet = array(), $mercenaries, $value) { return sn_function_call(__FUNCTION__, array(&$user, $planet, $mercenaries, $value)); }
406
407
function sn_mrc_modify_value(&$user, $planet = array(), $mercenaries, $value, $base_value = null) {
408
  if (!is_array($mercenaries)) {
409
    $mercenaries = array($mercenaries);
410
  }
411
412
  $base_value = isset($base_value) ? $base_value : $value;
413
414
  foreach ($mercenaries as $mercenary_id) {
415
    $mercenary_level = mrc_get_level($user, $planet, $mercenary_id);
416
417
    $mercenary = get_unit_param($mercenary_id);
418
    $mercenary_bonus = $mercenary['bonus'];
419
420
    switch ($mercenary['bonus_type']) {
421
      case BONUS_PERCENT_CUMULATIVE:
422
        $value *= 1 + $mercenary_level * $mercenary_bonus / 100;
423
      break;
424
425
      case BONUS_PERCENT:
426
        $mercenary_level = $mercenary_bonus < 0 && $mercenary_level * $mercenary_bonus < -90 ? -90 / $mercenary_bonus : $mercenary_level;
427
        $value += $base_value * $mercenary_level * $mercenary_bonus / 100;
428
      break;
429
430
      case BONUS_ADD:
431
        $value += $mercenary_level * $mercenary_bonus;
432
      break;
433
434
      case BONUS_ABILITY:
435
        $value = $mercenary_level ? $mercenary_level : 0;
436
      break;
437
438
      default:
439
      break;
440
    }
441
  }
442
443
  return $value;
444
}
445
446
// Generates random string of $length symbols from $allowed_chars charset
447
function sys_random_string($length = 16, $allowed_chars = SN_SYS_SEC_CHARS_ALLOWED) {
448
  $allowed_length = strlen($allowed_chars);
449
450
  $random_string = '';
451
  for ($i = 0; $i < $length; $i++) {
452
    $random_string .= $allowed_chars[mt_rand(0, $allowed_length - 1)];
453
  }
454
455
  return $random_string;
456
}
457
458
function js_safe_string($string) {
459
  return str_replace(array("\r", "\n"), array('\r', '\n'), addslashes($string));
460
}
461
462
function sys_safe_output($string) {
463
  return str_replace(array("&", "\"", "<", ">", "'"), array("&amp;", "&quot;", "&lt;", "&gt;", "&apos;"), $string);
464
}
465
466
function sys_user_options_pack(&$user) {
467
  global $user_option_list;
468
469
  $options = '';
470
  $option_list = array();
471
  foreach ($user_option_list as $option_group_id => $option_group) {
472
    $option_list[$option_group_id] = array();
473
    foreach ($option_group as $option_name => $option_value) {
474
      if (!isset($user[$option_name])) {
475
        $user[$option_name] = $option_value;
476
      } elseif ($user[$option_name] == '') {
477
        $user[$option_name] = 0;
478
      }
479
      $options .= "{$option_name}^{$user[$option_name]}|";
480
      $option_list[$option_group_id][$option_name] = $user[$option_name];
481
    }
482
  }
483
484
  $user['options'] = $options;
485
  $user['option_list'] = $option_list;
486
487
  return $options;
488
}
489
490
function sys_user_options_unpack(&$user) {
491
  global $user_option_list;
492
493
  $option_list = array();
494
  $option_string_list = explode('|', $user['options']);
495
496
  foreach ($option_string_list as $option_string) {
497
    list($option_name, $option_value) = explode('^', $option_string);
498
    $option_list[$option_name] = $option_value;
499
  }
500
501
  $final_list = array();
502
  foreach ($user_option_list as $option_group_id => $option_group) {
503
    $final_list[$option_group_id] = array();
504
    foreach ($option_group as $option_name => $option_value) {
505
      if (!isset($option_list[$option_name])) {
506
        $option_list[$option_name] = $option_value;
507
      }
508
      $user[$option_name] = $final_list[$option_group_id][$option_name] = $option_list[$option_name];
509
    }
510
  }
511
512
  $user['option_list'] = $final_list;
513
514
  return $final_list;
515
}
516
517
function sys_unit_str2arr($fleet_string) {
518
  $fleet_array = array();
519
  if (!empty($fleet_string)) {
520
    $arrTemp = explode(';', $fleet_string);
521
    foreach ($arrTemp as $temp) {
522
      if ($temp) {
523
        $temp = explode(',', $temp);
524
        if (!empty($temp[0]) && !empty($temp[1])) {
525
          $fleet_array[$temp[0]] += $temp[1];
526
        }
527
      }
528
    }
529
  }
530
531
  return $fleet_array;
532
}
533
534
function sys_unit_arr2str($unit_list) {
535
  $fleet_string = array();
536
  if (isset($unit_list)) {
537
    if (!is_array($unit_list)) {
538
      $unit_list = array($unit_list => 1);
539
    }
540
541
    foreach ($unit_list as $unit_id => $unit_count) {
542
      if ($unit_id && $unit_count) {
543
        $fleet_string[] = "{$unit_id},{$unit_count}";
544
      }
545
    }
546
  }
547
548
  return implode(';', $fleet_string);
549
}
550
551
function mymail($email_unsafe, $title, $body, $from = '', $html = false) {
552
  $from = trim($from ? $from : classSupernova::$config->game_adminEmail);
553
554
  $head = '';
555
  $head .= "Content-Type: text/" . ($html ? 'html' : 'plain') . "; charset=utf-8 \r\n";
556
  $head .= "Date: " . date('r') . " \r\n";
557
  $classConfig = classSupernova::$config;
558
  $head .= "Return-Path: {$classConfig->game_adminEmail} \r\n";
559
  $head .= "From: {$from} \r\n";
560
  $head .= "Sender: {$from} \r\n";
561
  $head .= "Reply-To: {$from} \r\n";
562
  // $head .= "Organization: {$org} \r\n";
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% 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...
563
  $head .= "X-Sender: {$from} \r\n";
564
  $head .= "X-Priority: 3 \r\n";
565
  $body = str_replace("\r\n", "\n", $body);
566
  $body = str_replace("\n", "\r\n", $body);
567
568
  if ($html) {
569
    $body = '<html><head><base href="' . SN_ROOT_VIRTUAL . '"></head><body>' . nl2br($body) . '</body></html>';
570
  }
571
572
  $title = '=?UTF-8?B?' . base64_encode($title) . '?=';
573
574
  return @mail($email_unsafe, $title, $body, $head);
0 ignored issues
show
Security Header Injection introduced by
$email_unsafe can contain request data and is used in request header context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in includes/general.php on line 258
  2. sys_get_param() returns tainted data
    in includes/general.php on line 290
  3. Data is passed through strip_tags(), and Data is passed through trim()
    in vendor/includes/general.php on line 1289
  4. sys_get_param_str_unsafe() returns tainted data, and auth_local::$input_email_unsafe is assigned
    in includes/classes/auth_local.php on line 362
  5. Tainted property auth_local::$input_email_unsafe is read, and $email_unsafe is assigned
    in includes/classes/auth_local.php on line 205
  6. $email_unsafe is passed to mymail()
    in includes/classes/auth_local.php on line 238

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
575
}
576
577
function sys_time_human($time, $full = false) {
578
  $seconds = $time % 60;
579
  $time = floor($time / 60);
580
  $minutes = $time % 60;
581
  $time = floor($time / 60);
582
  $hours = $time % 24;
583
  $time = floor($time / 24);
584
585
  $classLocale = classLocale::$lang;
586
587
  return
588
    ($full || $time ? "{$time} {$classLocale['sys_day']}&nbsp;" : '') .
589
    ($full || $hours ? "{$hours} {$classLocale['sys_hrs']}&nbsp;" : '') .
590
    ($full || $minutes ? "{$minutes} {$classLocale['sys_min']}&nbsp;" : '') .
591
    ($full || !$time || $seconds ? "{$seconds} {$classLocale['sys_sec']}" : '');
592
}
593
594
function sys_time_human_system($time) {
595
  return $time ? date(FMT_DATE_TIME_SQL, $time) . " ({$time}), " . sys_time_human(SN_TIME_NOW - $time) : '{NEVER}';
596
}
597
598
function sys_redirect($url) {
599
  header("Location: {$url}");
600
  ob_end_flush();
601
  die();
602
}
603
604
// TODO Для полноценного функионирования апдейтера пакет функций, включая эту должен быть вынесен раньше - или грузить general.php до апдейтера
605
function sys_get_unit_location($user, $planet, $unit_id) { return sn_function_call(__FUNCTION__, array($user, $planet, $unit_id)); }
606
607
function sn_sys_get_unit_location($user, $planet, $unit_id) {
0 ignored issues
show
Unused Code introduced by
The parameter $user is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $planet is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
608
  return get_unit_param($unit_id, 'location');
609
}
610
611
function sn_ali_fill_user_ally(&$user) {
612
  if (!$user['ally_id']) {
613
    return;
614
  }
615
616
  if (!isset($user['ally'])) {
617
    $user['ally'] = DBStaticAlly::db_ally_get_by_id($user['ally_id']);
618
  }
619
620
  if (!isset($user['ally']['player'])) {
621
    $user['ally']['player'] = DBStaticUser::db_user_by_id($user['ally']['ally_user_id'], true, '*', false);
622
  }
623
}
624
625
function sn_get_url_contents($url) {
626
  if (function_exists('curl_init')) {
627
    $crl = curl_init();
628
    $timeout = 5;
629
    curl_setopt($crl, CURLOPT_URL, $url);
630
    curl_setopt($crl, CURLOPT_RETURNTRANSFER, 1);
631
    curl_setopt($crl, CURLOPT_CONNECTTIMEOUT, $timeout);
632
    $return = curl_exec($crl);
633
    curl_close($crl);
634
  } else {
635
    $return = @file_get_contents($url);
636
  }
637
638
  return $return;
639
}
640
641
function get_engine_data($user, $engine_info) {
642
  $sn_data_tech_bonus = get_unit_param($engine_info['tech'], 'bonus');
643
644
  $user_tech_level = intval(mrc_get_level($user, null, $engine_info['tech']));
645
646
  $engine_info['speed_base'] = $engine_info['speed'];
647
  $tech_bonus = ($user_tech_level - $engine_info['min_level']) * $sn_data_tech_bonus / 100;
648
  $tech_bonus = $tech_bonus < -0.9 ? -0.95 : $tech_bonus;
649
  $engine_info['speed'] = floor(mrc_modify_value($user, false, array(MRC_NAVIGATOR), $engine_info['speed']) * (1 + $tech_bonus));
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a array.

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...
650
651
  $engine_info['consumption_base'] = $engine_info['consumption'];
652
  $tech_bonus = ($user_tech_level - $engine_info['min_level']) * $sn_data_tech_bonus / 1000;
653
  $tech_bonus = $tech_bonus > 0.5 ? 0.5 : ($tech_bonus < 0 ? $tech_bonus * 2 : $tech_bonus);
654
  $engine_info['consumption'] = ceil($engine_info['consumption'] * (1 - $tech_bonus));
655
656
  return $engine_info;
657
}
658
659
function get_ship_data($ship_id, $user) {
660
  $ship_data = array();
661
  if (in_array($ship_id, Fleet::$snGroupFleetAndMissiles)) {
662
    $engines = get_unit_param($ship_id, 'engine');
663
    empty($engines) ? $engines = array() : false;
664
    foreach ($engines as $engine_info) {
665
      $tech_level = intval(mrc_get_level($user, null, $engine_info['tech']));
666
      if (empty($ship_data) || $tech_level >= $engine_info['min_level']) {
667
        $ship_data = $engine_info;
668
        $ship_data['tech_level'] = $tech_level;
669
      }
670
    }
671
    $ship_data = get_engine_data($user, $ship_data);
672
    $ship_data['capacity'] = get_unit_param($ship_id, 'capacity');
673
  }
674
675
  return $ship_data;
676
}
677
678
if (!function_exists('strptime')) {
679
  function strptime($date, $format) {
680
    $masks = array(
681
      '%d' => '(?P<d>[0-9]{2})',
682
      '%m' => '(?P<m>[0-9]{2})',
683
      '%Y' => '(?P<Y>[0-9]{4})',
684
      '%H' => '(?P<H>[0-9]{2})',
685
      '%M' => '(?P<M>[0-9]{2})',
686
      '%S' => '(?P<S>[0-9]{2})',
687
      // usw..
688
    );
689
690
    $rexep = "#" . strtr(preg_quote($format), $masks) . "#";
691
    if (preg_match($rexep, $date, $out)) {
692
      $ret = array(
693
        "tm_sec"  => (int)$out['S'],
694
        "tm_min"  => (int)$out['M'],
695
        "tm_hour" => (int)$out['H'],
696
        "tm_mday" => (int)$out['d'],
697
        "tm_mon"  => $out['m'] ? $out['m'] - 1 : 0,
698
        "tm_year" => $out['Y'] > 1900 ? $out['Y'] - 1900 : 0,
699
      );
700
    } else {
701
      $ret = false;
702
    }
703
704
    return $ret;
705
  }
706
}
707
708
function sn_sys_sector_buy($redirect = 'overview.php') {
709
  global $user, $planetrow;
710
711
  if (!sys_get_param_str('sector_buy') || $planetrow['planet_type'] != PT_PLANET) {
712
    return;
713
  }
714
715
  sn_db_transaction_start();
716
  $user = DBStaticUser::db_user_by_id($user['id'], true, '*');
717
  $planetrow = DBStaticPlanet::db_planet_by_id($planetrow['id'], true, '*');
718
  // Тут не надо делать обсчет - ресурсы мы уже посчитали, очередь (и количество зданий) - тоже
719
  $sector_cost = eco_get_build_data($user, $planetrow, UNIT_SECTOR, mrc_get_level($user, $planetrow, UNIT_SECTOR), true);
720
  $sector_cost = $sector_cost[BUILD_CREATE][RES_DARK_MATTER];
721
  if ($sector_cost <= mrc_get_level($user, null, RES_DARK_MATTER)) {
722
    $planet_name_text = uni_render_planet($planetrow);
723
    if (rpg_points_change($user['id'], RPG_SECTOR, -$sector_cost, sprintf(classLocale::$lang['sys_sector_purchase_log'],
724
        $user['username'], $user['id'], $planet_name_text, classLocale::$lang['sys_planet_type'][$planetrow['planet_type']], $planetrow['id'], $sector_cost)
725
    )) {
726
      $sector_db_name = pname_resource_name(UNIT_SECTOR);
727
      DBStaticPlanet::db_planet_update_set_by_id($planetrow['id'], "{$sector_db_name} = {$sector_db_name} + 1");
728
    } else {
729
      sn_db_transaction_rollback();
730
    }
731
  }
732
  sn_db_transaction_commit();
733
734
  sys_redirect($redirect);
735
}
736
737
/**
738
 * @param           $functions
739
 * @param           $handler_list
740
 * @param sn_module $class_module_name
741
 * @param string    $sub_type
742
 */
743
function sn_sys_handler_add(&$functions, $handler_list, $class_module_name = '', $sub_type = '') {
744
  if (isset($handler_list) && is_array($handler_list) && !empty($handler_list)) {
745
    foreach ($handler_list as $function_name => $function_data) {
746
      $override_with = '';
747
      if (is_string($function_data)) {
748
        $override_with = &$function_data;
749
      } elseif (isset($function_data['callable'])) {
750
        $override_with = &$function_data['callable'];
751
      }
752
753
      $overwrite = $override_with[0] == '*';
754
      if ($overwrite) {
755
        $override_with = substr($override_with, 1);
756
      }
757
758
      if (($point_position = strpos($override_with, '.')) === false && $class_module_name) {
759
        $override_with = array($class_module_name, $override_with);
760
      } elseif ($point_position == 0) {
761
        $override_with = substr($override_with, 1);
762
      } elseif ($point_position > 0) {
763
        $override_with = array(substr($override_with, 0, $point_position), substr($override_with, $point_position + 1));
764
      }
765
766
      if ($overwrite) {
767
        $functions[$function_name] = array();
768
        $function_data = array('callable' => $override_with);
769
      } elseif (!isset($functions[$function_name])) {
770
        $functions[$function_name] = array();
771
        $sn_function_name = 'sn_' . $function_name . ($sub_type ? '_' . $sub_type : '');
772
        $functions[$function_name][] = $sn_function_name;
773
      }
774
775
      $functions[$function_name][] = $function_data;
776
    }
777
  }
778
}
779
780
// TODO - поменять название
781
// Может принимать: (array)$user, $nick_render_array, $nick_render_array_html, $nick_render_string_compact
782
function player_nick_render_to_html($result, $options = false) {
783
  // TODO - обрабатывать разные случаи: $user, $render_nick_array, $string
784
785
  if (is_string($result) && strpos($result, ':{i:')) {
786
    $result = player_nick_uncompact($result);
787
  }
788
789
  if (is_array($result)) {
790
    if (isset($result['id'])) {
791
      $result = player_nick_render_current_to_array($result, $options);
792
    }
793
    if (!isset($result[NICK_HTML])) {
794
      $result = player_nick_render_array_to_html($result);
795
    }
796
    unset($result[NICK_HTML]);
797
    ksort($result);
798
    $result = implode('', $result);
799
  }
800
801
  return $result;
802
}
803
804
805
function player_nick_compact($nick_array) {
806
  ksort($nick_array);
807
808
  return serialize($nick_array);
809
}
810
811
function player_nick_uncompact($nick_string) {
812
  try {
813
    $result = unserialize($nick_string);
814
  } catch (exception $e) {
815
    $result = strpos($nick_string, ':{i:') ? null : $nick_string; // fallback if it is already string - for old chat strings, for example
816
  }
817
818
  return $result;
819
}
820
821
function player_nick_render_array_to_html($nick_array) { return sn_function_call(__FUNCTION__, array($nick_array, &$result)); }
822
823
function sn_player_nick_render_array_to_html($nick_array, &$result) {
824
  global $user;
825
826
  // ALL STRING ARE UNSAFE!!!
827
  if (isset($nick_array[NICK_BIRTHSDAY])) {
828
    $result[NICK_BIRTHSDAY] = '<img src="design/images/birthday.png" />';
829
  }
830
831
  if (isset($nick_array[NICK_VACATION])) {
832
    $result[NICK_VACATION] = '<img src="design/images/icon_vacation.png" />';
833
  }
834
835
  if (isset($nick_array[NICK_GENDER])) {
836
    $result[NICK_GENDER] = '<img src="' . ($user['dpath'] ? $user['dpath'] : DEFAULT_SKINPATH) . 'images/gender_' . $nick_array[NICK_GENDER] . '.png" />';
837
  }
838
839
  if (isset($nick_array[NICK_AUTH_LEVEL]) || isset($nick_array[NICK_PREMIUM])) {
840
    switch ($nick_array[NICK_AUTH_LEVEL]) {
841
      case 4:
842
        $highlight = classSupernova::$config->chat_highlight_developer;
843
      break;
844
845
      case 3:
846
        $highlight = classSupernova::$config->chat_highlight_admin;
847
      break;
848
849
      case 2:
850
        $highlight = classSupernova::$config->chat_highlight_operator;
851
      break;
852
853
      case 1:
854
        $highlight = classSupernova::$config->chat_highlight_moderator;
855
      break;
856
857
      default:
858
        $highlight = isset($nick_array[NICK_PREMIUM]) ? classSupernova::$config->chat_highlight_premium : '';
859
    }
860
861
    if ($highlight) {
862
      list($result[NICK_HIGHLIGHT], $result[NICK_HIGHLIGHT_END]) = explode('$1', $highlight);
863
    }
864
  }
865
866 View Code Duplication
  if (isset($nick_array[NICK_CLASS])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across 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...
867
    $result[NICK_CLASS] = '<span ' . $nick_array[NICK_CLASS] . '>';
868
    $result[NICK_CLASS_END] = '</span>';
869
  }
870
871
  $result[NICK_NICK] = sys_safe_output($nick_array[NICK_NICK]);
872
873 View Code Duplication
  if (isset($nick_array[NICK_ALLY])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across 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...
874
    $result[NICK_ALLY] = '[' . sys_safe_output($nick_array[NICK_ALLY]) . ']';
875
  }
876
877
  $result[NICK_HTML] = true;
878
879
  return $result;
880
}
881
882
function player_nick_render_current_to_array($render_user, $options = false) { return sn_function_call(__FUNCTION__, array($render_user, $options, &$result)); }
883
884
function sn_player_nick_render_current_to_array($render_user, $options = false, &$result) {
885
  if ($render_user['user_birthday'] && ($options === true || isset($options['icons']) || isset($options['birthday'])) && (date('Y', SN_TIME_NOW) . date('-m-d', strtotime($render_user['user_birthday'])) == date('Y-m-d', SN_TIME_NOW))) {
886
    $result[NICK_BIRTHSDAY] = '';
887
  }
888
889
  if ($options === true || (isset($options['icons']) && $options['icons']) || (isset($options['gender']) && $options['gender'])) {
890
    $result[NICK_GENDER] = $render_user['gender'] == GENDER_UNKNOWN ? 'unknown' : ($render_user['gender'] == GENDER_FEMALE ? 'female' : 'male');
891
  }
892
893
  if (($options === true || (isset($options['icons']) && $options['icons']) || (isset($options['vacancy']) && $options['vacancy'])) && $render_user['vacation']) {
894
    $result[NICK_VACATION] = $render_user['vacation'];
895
  }
896
897
  if ($options === true || (isset($options['color']) && $options['color'])) {
898
    if ($user_auth_level = $render_user['authlevel']) {
899
      $result[NICK_AUTH_LEVEL] = $user_auth_level;
900
    }
901
    if ($user_premium = mrc_get_level($render_user, null, UNIT_PREMIUM)) {
902
      $result[NICK_PREMIUM] = $user_premium;
903
    }
904
  }
905
906
  if ((isset($options['class']) && $options['class'])) {
907
    $result[NICK_CLASS] = (isset($result_options[NICK_CLASS]) ? ' ' . $result_options[NICK_CLASS] : '') . $options['class'];
0 ignored issues
show
Bug introduced by
The variable $result_options does not exist. Did you mean $options?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
908
  }
909
910
  if ($render_user['ally_tag'] && ($options === true || (isset($options['ally']) && $options['ally']))) {
911
    $result[NICK_ALLY] = $render_user['ally_tag'];
912
  }
913
914
  $result[NICK_NICK] = $render_user['username'];
915
916
  return $result;
917
}
918
919
920
// TODO sys_stat_get_user_skip_list() ПЕРЕДЕЛАТЬ!
921
function sys_stat_get_user_skip_list() {
922
  $result = array();
923
924
  $user_skip_list = array();
925
926
  if (classSupernova::$config->stats_hide_admins) {
927
    $user_skip_list[] = '`authlevel` > 0';
928
  }
929
930
  if (classSupernova::$config->stats_hide_player_list) {
931
    $temp = explode(',', classSupernova::$config->stats_hide_player_list);
932
    foreach ($temp as $user_id) {
933
      $user_id = floatval($user_id);
934
      if ($user_id) {
935
        $user_skip_list[] = '`id` = ' . $user_id;
936
      }
937
    }
938
  }
939
940
  if (!empty($user_skip_list)) {
941
    $user_skip_list = implode(' OR ', $user_skip_list);
942
    $user_skip_query = DBStaticUser::db_user_list($user_skip_list);
943
    if (!empty($user_skip_query)) {
944
      foreach ($user_skip_query as $user_skip_row) {
945
        $result[$user_skip_row['id']] = $user_skip_row['id'];
946
      }
947
    }
948
  }
949
950
  return $result;
951
}
952
953
/**
954
 * @param int|float|string $unit_id
955
 * @param null|string|int  $param_name
956
 * @param null|array       $user
957
 * @param null|array       $planet
958
 *
959
 * @return mixed
960
 */
961
function get_unit_param($unit_id, $param_name = null, $user = null, $planet = null) { return sn_function_call(__FUNCTION__, array($unit_id, $param_name, $user, $planet, &$result)); }
962
963
function sn_get_unit_param($unit_id, $param_name = null, $user = null, $planet = null, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $user is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $planet is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
964
  global $sn_data;
965
966
  $result = isset($sn_data[$unit_id])
967
    ? ($param_name === null
968
      ? $sn_data[$unit_id]
969
      : (isset($sn_data[$unit_id][$param_name]) ? $sn_data[$unit_id][$param_name] : $result)
970
    )
971
    : $result;
972
973
  return $result;
974
}
975
976
/**
977
 * @param $groups
978
 *
979
 * @return array
980
 */
981
function sn_get_groups($groups) { return sn_function_call(__FUNCTION__, array($groups, &$result)); }
982
983
/**
984
 * @param $groups
985
 * @param $result
986
 *
987
 * @return array
988
 */
989
function sn_sn_get_groups($groups, &$result) {
990
  $result = is_array($result) ? $result : array();
991
  foreach ($groups = is_array($groups) ? $groups : array($groups) as $group_name) {
992
    $result += is_array($a_group = get_unit_param(UNIT_GROUP, $group_name)) ? $a_group : array();
993
  }
994
995
  return $result;
996
}
997
998
function isInGroup($groups, $unitId) {
999
  $group = sn_get_groups($groups);
1000
1001
  return !empty($group[$unitId]);
1002
}
1003
1004
// Format $value to ID
1005
/**
1006
 * @param     $value
1007
 * @param int $default
1008
 *
1009
 * @return float|int
1010
 */
1011
function idval($value, $default = 0) {
1012
  $value = floatval($value);
1013
1014
  return preg_match('#^(\d*)#', $value, $matches) && $matches[1] ? floatval($matches[1]) : $default;
1015
}
1016
1017
function unit_requirements_render($user, $planetrow, $unit_id, $field = 'require') { return sn_function_call(__FUNCTION__, array($user, $planetrow, $unit_id, $field, &$result)); }
1018
1019
function sn_unit_requirements_render($user, $planetrow, $unit_id, $field = 'require', &$result) {
1020
  $sn_data_unit = get_unit_param($unit_id);
1021
1022
  $result = is_array($result) ? $result : array();
1023
  if ($sn_data_unit[$field] && !($sn_data_unit[P_UNIT_TYPE] == UNIT_MERCENARIES && classSupernova::$config->empire_mercenary_temporary)) {
1024
    foreach ($sn_data_unit[$field] as $require_id => $require_level) {
1025
      $level_got = mrc_get_level($user, $planetrow, $require_id);
1026
      $level_basic = mrc_get_level($user, $planetrow, $require_id, false, true);
1027
      $result[] = array(
1028
        'NAME'             => classLocale::$lang['tech'][$require_id],
1029
        //'CLASS' => $require_level > $level_got ? 'negative' : ($require_level == $level_got ? 'zero' : 'positive'),
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...
1030
        'REQUEREMENTS_MET' => intval($require_level <= $level_got ? REQUIRE_MET : REQUIRE_MET_NOT),
1031
        'LEVEL_REQUIRE'    => $require_level,
1032
        'LEVEL'            => $level_got,
1033
        'LEVEL_BASIC'      => $level_basic,
1034
        'LEVEL_BONUS'      => max(0, $level_got - $level_basic),
1035
        'ID'               => $require_id,
1036
      );
1037
    }
1038
  }
1039
1040
  return $result;
1041
}
1042
1043
function ally_get_ranks(&$ally) {
1044
  global $ally_rights;
1045
1046
  $ranks = array();
1047
1048
  if ($ally['ranklist']) {
1049
    $str_ranks = explode(';', $ally['ranklist']);
1050
    foreach ($str_ranks as $str_rank) {
1051
      if (!$str_rank) {
1052
        continue;
1053
      }
1054
1055
      $tmp = explode(',', $str_rank);
1056
      $rank_id = count($ranks);
1057
      foreach ($ally_rights as $key => $value) {
1058
        $ranks[$rank_id][$value] = $tmp[$key];
1059
      }
1060
    }
1061
  }
1062
1063
  return $ranks;
1064
}
1065
1066
function sys_player_new_adjust($user_id, $planet_id) { return sn_function_call(__FUNCTION__, array($user_id, $planet_id, &$result)); }
1067
1068
function sn_sys_player_new_adjust($user_id, $planet_id, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $user_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $planet_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1069
  return $result;
1070
}
1071
1072
function array_merge_recursive_numeric($array1, $array2) {
1073
  if (!empty($array2) && is_array($array2)) {
1074
    foreach ($array2 as $key => $value) {
1075
      $array1[$key] = !isset($array1[$key]) || !is_array($array1[$key]) ? $value : array_merge_recursive_numeric($array1[$key], $value);
1076
    }
1077
  }
1078
1079
  return $array1;
1080
}
1081
1082
function sn_sys_array_cumulative_sum(&$array) {
1083
  $accum = 0;
1084
  foreach ($array as &$value) {
1085
    $accum += $value;
1086
    $value = $accum;
1087
  }
1088
}
1089
1090
function planet_density_price_chart($planet_row) {
1091
  $sn_data_density = sn_get_groups('planet_density');
1092
  $density_price_chart = array();
1093
1094
  foreach ($sn_data_density as $density_id => $density_data) {
1095
    // Отсекаем записи с RARITY = 0 - служебные записи и супер-ядра
1096
    $density_data[UNIT_PLANET_DENSITY_RARITY] ? $density_price_chart[$density_id] = $density_data[UNIT_PLANET_DENSITY_RARITY] : false;
1097
  }
1098
  unset($density_price_chart[PLANET_DENSITY_NONE]);
1099
1100
  $total_rarity = array_sum($density_price_chart);
1101
1102
  foreach ($density_price_chart as &$density_data) {
1103
    $density_data = ceil($total_rarity / $density_data * $planet_row['field_max'] * PLANET_DENSITY_TO_DARK_MATTER_RATE);
1104
  }
1105
1106
  return $density_price_chart;
1107
}
1108
1109
function sn_sys_planet_core_transmute(&$user, &$planetrow) {
1110
  if (!sys_get_param_str('transmute')) {
1111
    return array();
1112
  }
1113
1114
  try {
1115 View Code Duplication
    if ($planetrow['planet_type'] != PT_PLANET) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1116
      throw new exception(classLocale::$lang['ov_core_err_not_a_planet'], ERR_ERROR);
1117
    }
1118
1119
    if ($planetrow['density_index'] == ($new_density_index = sys_get_param_id('density_type'))) {
1120
      throw new exception(classLocale::$lang['ov_core_err_same_density'], ERR_WARNING);
1121
    }
1122
1123
    sn_db_transaction_start();
1124
    $user = DBStaticUser::db_user_by_id($user['id'], true, '*');
1125
    $planetrow = DBStaticPlanet::db_planet_by_id($planetrow['id'], true, '*');
1126
1127
    $planet_density_index = $planetrow['density_index'];
1128
1129
    $density_price_chart = planet_density_price_chart($planetrow);
1130
    if (!isset($density_price_chart[$new_density_index])) {
1131
      // Hack attempt
1132
      throw new exception(classLocale::$lang['ov_core_err_denisty_type_wrong'], ERR_ERROR);
1133
    }
1134
1135
    $user_dark_matter = mrc_get_level($user, null, RES_DARK_MATTER);
1136
    $transmute_cost = $density_price_chart[$new_density_index];
1137
    if ($user_dark_matter < $transmute_cost) {
1138
      throw new exception(classLocale::$lang['ov_core_err_no_dark_matter'], ERR_ERROR);
1139
    }
1140
1141
    $sn_data_planet_density = sn_get_groups('planet_density');
1142
    $prev_density_index = PLANET_DENSITY_NONE;
1143
    foreach ($sn_data_planet_density as $key => $value) {
1144
      if ($key == $new_density_index) {
1145
        break;
1146
      }
1147
      $prev_density_index = $key;
1148
    }
1149
1150
    $new_density = round(($sn_data_planet_density[$new_density_index][UNIT_PLANET_DENSITY] + $sn_data_planet_density[$prev_density_index][UNIT_PLANET_DENSITY]) / 2);
1151
1152
    rpg_points_change($user['id'], RPG_PLANET_DENSITY_CHANGE, -$transmute_cost,
1153
      array(
0 ignored issues
show
Documentation introduced by
array('Planet %1$s ID %2...y_index], $new_density) is of type array<integer,?,{"0":"st...,"7":"?","8":"double"}>, but the function expects a string.

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...
1154
        'Planet %1$s ID %2$d at coordinates %3$s changed density type from %4$d "%5$s" to %6$d "%7$s". New density is %8$d kg/m3',
1155
        $planetrow['name'],
1156
        $planetrow['id'],
1157
        uni_render_coordinates($planetrow),
1158
        $planet_density_index,
1159
        classLocale::$lang['uni_planet_density_types'][$planet_density_index],
1160
        $new_density_index,
1161
        classLocale::$lang['uni_planet_density_types'][$new_density_index],
1162
        $new_density
1163
      )
1164
    );
1165
1166
    DBStaticPlanet::db_planet_update_set_by_id($planetrow['id'], "`density` = {$new_density}, `density_index` = {$new_density_index}");
1167
    sn_db_transaction_commit();
1168
1169
    $planetrow['density'] = $new_density;
1170
    $planetrow['density_index'] = $new_density_index;
1171
    $result = array(
1172
      'STATUS'  => ERR_NONE,
1173
      'MESSAGE' => sprintf(classLocale::$lang['ov_core_err_none'], classLocale::$lang['uni_planet_density_types'][$planet_density_index], classLocale::$lang['uni_planet_density_types'][$new_density_index], $new_density),
1174
    );
1175
  } catch (exception $e) {
1176
    sn_db_transaction_rollback();
1177
    $result = array(
1178
      'STATUS'  => $e->getCode(),
1179
      'MESSAGE' => $e->getMessage(),
1180
    );
1181
  }
1182
1183
  return $result;
1184
}
1185
1186
function sn_module_get_active_count($group = '*') {
1187
  $active_modules = 0;
1188
  if (isset(sn_module::$sn_module_list[$group]) && is_array(sn_module::$sn_module_list[$group])) {
1189
    foreach (sn_module::$sn_module_list[$group] as $payment_module) {
1190
      $active_modules += $payment_module->manifest['active'];
1191
    }
1192
  }
1193
1194
  return $active_modules;
1195
}
1196
1197
function get_resource_exchange() {
1198
  static $rates;
1199
1200
  if (!$rates) {
1201
    $rates = array(
1202
      RES_METAL       => 'rpg_exchange_metal',
1203
      RES_CRYSTAL     => 'rpg_exchange_crystal',
1204
      RES_DEUTERIUM   => 'rpg_exchange_deuterium',
1205
      RES_DARK_MATTER => 'rpg_exchange_darkMatter',
1206
    );
1207
1208
    foreach ($rates as &$rate) {
1209
      $rate = classSupernova::$config->$rate;
1210
    }
1211
  }
1212
1213
  return $rates;
1214
}
1215
1216
function get_unit_cost_in(&$cost, $in_resource = RES_METAL) {
0 ignored issues
show
Unused Code introduced by
The parameter $in_resource is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1217
  static $rates;
1218
1219
  if (!$rates) {
1220
    $rates = get_resource_exchange();
1221
  }
1222
1223
  $metal_cost = 0;
1224
  foreach ($cost as $resource_id => $resource_value) {
1225
    $metal_cost += $rates[$resource_id] * $resource_value;
1226
  }
1227
1228
  return $metal_cost;
1229
}
1230
1231
/**
1232
 * @param array $user
1233
 * @param int   $astrotech
1234
 *
1235
 * @return int
1236
 */
1237
function get_player_max_expeditons(&$user, $astrotech = -1) { return sn_function_call(__FUNCTION__, array(&$user, $astrotech, &$result)); }
1238
1239
/**
1240
 * @param     $user
1241
 * @param int $astrotech
1242
 * @param int $result
1243
 *
1244
 * @return float|int
1245
 */
1246
function sn_get_player_max_expeditons(&$user, $astrotech = -1, &$result = 0) {
1247
  if ($astrotech == -1) {
1248
    if (!isset($user[UNIT_PLAYER_EXPEDITIONS_MAX])) {
1249
      $astrotech = mrc_get_level($user, null, TECH_ASTROTECH);
1250
      $user[UNIT_PLAYER_EXPEDITIONS_MAX] = $astrotech >= 1 ? floor(sqrt($astrotech - 1)) : 0;
1251
    }
1252
1253
    return $result += $user[UNIT_PLAYER_EXPEDITIONS_MAX];
1254
  } else {
1255
    return $result += $astrotech >= 1 ? floor(sqrt($astrotech - 1)) : 0;
1256
  }
1257
}
1258
1259
function get_player_max_expedition_duration(&$user, $astrotech = -1) {
1260
  return $astrotech == -1 ? mrc_get_level($user, null, TECH_ASTROTECH) : $astrotech;
1261
}
1262
1263
function get_player_max_colonies(&$user, $astrotech = -1) {
1264
  if ($astrotech == -1) {
1265
    if (!isset($user[UNIT_PLAYER_COLONIES_MAX])) {
1266
1267
      $expeditions = get_player_max_expeditons($user);
1268
      $astrotech = mrc_get_level($user, null, TECH_ASTROTECH);
1269
      $colonies = $astrotech - $expeditions;
1270
1271
      $user[UNIT_PLAYER_COLONIES_MAX] = classSupernova::$config->player_max_colonies < 0 ? $colonies : min(classSupernova::$config->player_max_colonies, $colonies);
1272
    }
1273
1274
    return $user[UNIT_PLAYER_COLONIES_MAX];
1275 View Code Duplication
  } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1276
    $expeditions = get_player_max_expeditons($user, $astrotech);
1277
    // $astrotech = mrc_get_level($user, false, TECH_ASTROTECH);
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...
1278
    $colonies = $astrotech - $expeditions;
1279
1280
    return classSupernova::$config->player_max_colonies < 0 ? $colonies : min(classSupernova::$config->player_max_colonies, $colonies);
1281
  }
1282
}
1283
1284
function get_player_current_colonies(&$user) {
1285
  return $user[UNIT_PLAYER_COLONIES_CURRENT] = isset($user[UNIT_PLAYER_COLONIES_CURRENT]) ? $user[UNIT_PLAYER_COLONIES_CURRENT] : max(0, DBStaticPlanet::db_planet_count_by_type($user['id']) - 1);
1286
}
1287
1288
function str_raw2unsafe($raw) {
1289
  return trim(strip_tags($raw));
1290
}
1291
1292
function ip2longu($ip) {
1293
  return sprintf('%u', floatval(ip2long($ip)));
1294
}
1295
1296
1297
function sn_powerup_get_price_matrix($powerup_id, $powerup_unit = false, $level_max = null, $plain = false) { return sn_function_call(__FUNCTION__, array($powerup_id, $powerup_unit, $level_max, $plain, &$result)); }
1298
1299
function sn_sn_powerup_get_price_matrix($powerup_id, $powerup_unit = false, $level_max = null, $plain = false, &$result) {
0 ignored issues
show
Unused Code introduced by
The parameter $plain is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1300
  global $sn_powerup_buy_discounts;
1301
1302
  $result = array();
1303
1304
  $powerup_data = get_unit_param($powerup_id);
1305
  $is_upgrade = !empty($powerup_unit) && $powerup_unit;
1306
1307
  $level_current = $term_original = $time_left = 0;
1308
  if ($is_upgrade) {
1309
    $time_finish = strtotime($powerup_unit['unit_time_finish']);
1310
    $time_left = max(0, $time_finish - SN_TIME_NOW);
1311
    if ($time_left > 0) {
1312
      $term_original = $time_finish - strtotime($powerup_unit['unit_time_start']);
1313
      $level_current = $powerup_unit['unit_level'];
1314
    }
1315
  }
1316
1317
  $level_max = $level_max > $powerup_data[P_MAX_STACK] ? $level_max : $powerup_data[P_MAX_STACK];
1318
  $original_cost = 0;
1319
  for ($i = 1; $i <= $level_max; $i++) {
1320
    $base_cost = eco_get_total_cost($powerup_id, $i);
1321
    $base_cost = $base_cost[BUILD_CREATE][RES_DARK_MATTER];
1322
    foreach ($sn_powerup_buy_discounts as $period => $discount) {
1323
      $upgrade_price = floor($base_cost * $discount * $period / PERIOD_MONTH);
1324
      $result[$i][$period] = $upgrade_price;
1325
      $original_cost = $is_upgrade && $i == $level_current && $period <= $term_original ? $upgrade_price : $original_cost;
1326
    }
1327
  }
1328
1329
  if ($is_upgrade && $time_left) {
1330
    $term_original = round($term_original / PERIOD_DAY);
1331
    $time_left = min(floor($time_left / PERIOD_DAY), $term_original);
1332
    $cost_left = $term_original > 0 ? ceil($time_left / $term_original * $original_cost) : 0;
1333
1334
    array_walk_recursive($result, function (&$value) use ($cost_left) {
1335
      $value -= $cost_left;
1336
    });
1337
  }
1338
1339
  return $result;
1340
}
1341
1342
/**
1343
 * @param template $template
1344
 * @param array    $note_row
1345
 */
1346
function note_assign(&$template, $note_row) {
1347
  global $note_priority_classes;
1348
1349
  $template->assign_block_vars('note', array(
1350
    'ID'                     => $note_row['id'],
1351
    'TIME'                   => $note_row['time'],
1352
    'TIME_TEXT'              => date(FMT_DATE_TIME, $note_row['time']),
1353
    'PRIORITY'               => $note_row['priority'],
1354
    'PRIORITY_CLASS'         => $note_priority_classes[$note_row['priority']],
1355
    'PRIORITY_TEXT'          => classLocale::$lang['sys_notes_priorities'][$note_row['priority']],
1356
    'TITLE'                  => htmlentities($note_row['title'], ENT_COMPAT, 'UTF-8'),
1357
    'GALAXY'                 => intval($note_row['galaxy']),
1358
    'SYSTEM'                 => intval($note_row['system']),
1359
    'PLANET'                 => intval($note_row['planet']),
1360
    'PLANET_TYPE'            => intval($note_row['planet_type']),
1361
    'PLANET_TYPE_TEXT'       => classLocale::$lang['sys_planet_type'][$note_row['planet_type']],
1362
    'PLANET_TYPE_TEXT_SHORT' => classLocale::$lang['sys_planet_type_sh'][$note_row['planet_type']],
1363
    'TEXT'                   => sys_bbcodeParse(htmlentities($note_row['text'], ENT_COMPAT, 'UTF-8')),
1364
    'TEXT_EDIT'              => htmlentities($note_row['text'], ENT_COMPAT, 'UTF-8'),
1365
    'STICKY'                 => intval($note_row['sticky']),
1366
  ));
1367
}
1368
1369
function sn_version_compare_extra($version) {
1370
  static $version_regexp = '#(\d+)([a-f])(\d+)(?:\.(\d+))*#';
1371
  preg_match($version_regexp, $version, $version);
1372
  unset($version[0]);
1373
  $version[2] = ord($version[2]) - ord('a');
1374
1375
  return implode('.', $version);
1376
}
1377
1378
function sn_version_compare($ver1, $ver2) {
1379
  return version_compare(sn_version_compare_extra($ver1), sn_version_compare_extra($ver2));
1380
}
1381
1382
function sn_setcookie($name, $value = null, $expire = null, $path = SN_ROOT_RELATIVE, $domain = null, $secure = null, $httponly = null) {
1383
  $_COOKIE[$name] = $value;
1384
1385
  return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
1386
}
1387
1388
function market_get_autoconvert_cost() {
1389
  return classSupernova::$config->rpg_cost_exchange ? classSupernova::$config->rpg_cost_exchange * 3 : 3000;
1390
}
1391
1392
function print_rr($var, $capture = false) {
1393
  $print = '<pre>' . htmlspecialchars(print_r($var, true)) . '</pre>';
1394
  if ($capture) {
1395
    return $print;
1396
  } else {
1397
    print($print);
1398
  }
1399
}
1400
1401
function can_capture_planet() { return sn_function_call(__FUNCTION__, array(&$result)); }
1402
1403
function sn_can_capture_planet(&$result) {
1404
  return $result = false;
1405
}
1406
1407
/**
1408
 * Возвращает информацию об IPv4 адресах пользователя
1409
 *
1410
 * НЕ ПОДДЕРЖИВАЕТ IPv6!
1411
 *
1412
 * @return array
1413
 */
1414
// OK v4
1415
function sec_player_ip() {
1416
  // TODO - IPv6 support
1417
  $ip = array(
1418
    'ip'          => $_SERVER["REMOTE_ADDR"],
1419
    'proxy_chain' => $_SERVER["HTTP_X_FORWARDED_FOR"]
1420
      ? $_SERVER["HTTP_X_FORWARDED_FOR"]
1421
      : ($_SERVER["HTTP_CLIENT_IP"]
1422
        ? $_SERVER["HTTP_CLIENT_IP"]
1423
        : '' // $_SERVER["REMOTE_ADDR"]
1424
      ),
1425
  );
1426
1427
  return array_map('db_escape', $ip);
1428
}
1429
1430
/**
1431
 * Converts unix timestamp to SQL DateTime
1432
 *
1433
 * @param int $value
1434
 *
1435
 * @return string|null
1436
 */
1437
function unixTimeStampToSqlString($value) {
1438
  $result = !empty($value) ? date(FMT_DATE_TIME_SQL, $value) : null;
1439
1440
  return $result ? $result : null;
1441
}
1442
1443
/**
1444
 * Converts SQL DateTime to unix timestamp
1445
 *
1446
 * @param $value
1447
 *
1448
 * @return int
1449
 */
1450
function sqlStringToUnixTimeStamp($value) {
1451
  $result = !empty($value) ? strtotime($value) : 0;
1452
1453
  return $result ? $result : 0;
1454
}
1455
1456
/**
1457
 * @param mixed $value
1458
 *
1459
 * @return mixed|null
1460
 */
1461
function nullIfEmpty($value) {
1462
  return !empty($value) ? $value : null;
1463
}
1464
1465
1466
/**
1467
 * @param $sort_option
1468
 * @param $sort_option_inverse
1469
 *
1470
 * @return mixed
1471
 */
1472
function sortUnitRenderedList(&$ListToSort, $sort_option, $sort_option_inverse) {
1473
  if ($sort_option || $sort_option_inverse != PLAYER_OPTION_SORT_ORDER_PLAIN) {
1474
    switch ($sort_option) {
1475
      case PLAYER_OPTION_SORT_NAME:
1476
        $sort_option_field = 'NAME';
1477
      break;
1478
      case PLAYER_OPTION_SORT_SPEED:
1479
        $sort_option_field = 'SPEED';
1480
      break;
1481
      case PLAYER_OPTION_SORT_COUNT:
1482
        $sort_option_field = 'AMOUNT';
1483
      break;
1484
      case PLAYER_OPTION_SORT_ID:
1485
        $sort_option_field = 'ID';
1486
      break;
1487
      case PLAYER_OPTION_SORT_CREATE_TIME_LENGTH:
1488
        $sort_option_field = 'TIME_SECONDS';
1489
      break;
1490
      default:
1491
        $sort_option_field = '__INDEX';
1492
      break;
1493
    }
1494
    $sort_option_inverse_closure = $sort_option_inverse ? -1 : 1;
1495
    usort($ListToSort, function ($a, $b) use ($sort_option_field, $sort_option_inverse_closure) {
1496
      return $a[$sort_option_field] < $b[$sort_option_field] ? -1 * $sort_option_inverse_closure : (
1497
      $a[$sort_option_field] > $b[$sort_option_field] ? 1 * $sort_option_inverse_closure : 0
1498
      );
1499
    });
1500
  }
1501
1502
}
1503
1504
function checkReturnRef(&$ref1, &$ref2) {
1505
  if (isset($ref1['id'])) {
1506
    $ref1['id']++;
1507
    pdump($ref1['id']);
1508
    pdump($ref2['id']);
1509
    if ($ref2['id'] == $ref1['id']) {
1510
      pdump('ok');
1511
    } else {
1512
      pdie('failed');
1513
    }
1514
    $ref2['id']--;
1515
    if ($ref2['id'] == $ref1['id']) {
1516
      pdump('ok');
1517
    } else {
1518
      pdie('failed');
1519
    }
1520
  }
1521
1522
}
1523
1524
function setNull(&$item) {
1525
  $item = null;
1526
}
1527