Test Failed
Push — trunk ( 769658...cc4c01 )
by SuperNova.WS
15:09
created

flt_server_flight_speed_multiplier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
use Fleet\MissionExplore;
5
6
require_once('general_math.php');
7
require_once('general_compatibility.php');
8
require_once('general_params.php');
9
require_once('general_nickRender.php');
10
require_once('general_formatters.php');
11
require_once('general_validators.php');
12
require_once('general_unitFunctions.php');
13
require_once('general_playerFunctions.php');
14
require_once('general_planetFunctions.php');
15
require_once('general_urlAndHttp.php');
16
17
require_once('general_pname.php');
18
19
// HOOKS AND HANDLERS ----------------------------------------------------------------------------------------------------------------
20
/**
21
 * Function wrapping
22
 *
23
 * Due glitch in PHP 5.3.1 SuperNova is incompatible with this version
24
 * Reference: https://bugs.php.net/bug.php?id=50394
25
 *
26
 * @param string $func_name
27
 * @param array  $func_arg
28
 *
29
 * @return mixed
30
 */
31
function sn_function_call($func_name, $func_arg = array()) {
32
  global $functions; // All data in $functions should be normalized to valid 'callable' state: '<function_name>'|array('<object_name>', '<method_name>')
33
34
  if (is_array($functions[$func_name]) && !is_callable($functions[$func_name])) {
35
    // Chain-callable functions should be made as following:
36
    // 1. Never use incomplete calls with parameters "by default"
37
    // 2. Reserve last parameter for cumulative result
38
    // 3. Use same format for original value and cumulative result (if there is original value)
39
    // 4. Honor cumulative result
40
    // 5. Return cumulative result
41
    foreach ($functions[$func_name] as $func_chain_name) {
42
      // По идее - это уже тут не нужно, потому что оно все должно быть callable к этому моменту
43
      // Но для старых модулей...
44
      if (is_callable($func_chain_name)) {
45
        $result = call_user_func_array($func_chain_name, $func_arg);
46
      }
47
    }
48
  } else {
49
    // TODO: This is left for backward compatibility. Appropriate code should be rewrote!
50
    $func_name = isset($functions[$func_name]) && is_callable($functions[$func_name]) ? $functions[$func_name] : ('sn_' . $func_name);
51
    if (is_callable($func_name)) {
52
      $result = call_user_func_array($func_name, $func_arg);
53
    }
54
  }
55
56
  return $result;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.
Loading history...
57
}
58
59
/**
60
 * @param        $hook_list
61
 * @param        $template
62
 * @param string $hook_type - тип хука 'model' или 'view'
63
 * @param string $page_name - имя страницы, для которого должен был быть выполнен хук
64
 */
65
function execute_hooks(&$hook_list, &$template, $hook_type = null, $page_name = null) {
66
  if (!empty($hook_list)) {
67
    foreach ($hook_list as $hook) {
68
      if (is_callable($hook_call = (is_string($hook) ? $hook : (is_array($hook) ? $hook['callable'] : $hook->callable)))) {
69
        $template = call_user_func($hook_call, $template, $hook_type, $page_name);
70
      }
71
    }
72
  }
73
}
74
75
function sn_sys_handler_add(&$functions, $handler_list, $class_module_name = '', $sub_type = '') {
76
  if (isset($handler_list) && is_array($handler_list) && !empty($handler_list)) {
77
    foreach ($handler_list as $function_name => $function_data) {
78
      sys_handler_add_one($functions, $function_name, $function_data, $class_module_name, $sub_type);
79
    }
80
  }
81
}
82
83
/**
84
 * Adding one handler for specific function name
85
 *
86
 * @param callable[][] $functions
87
 * @param string       $function_name
88
 * @param string|array $function_data
89
 * @param string       $class_module_name
90
 * @param string       $sub_type
91
 */
92
function sys_handler_add_one(&$functions, $function_name, $function_data, $class_module_name, $sub_type) {
93
  if (is_string($function_data)) {
94
    $override_with = &$function_data;
95
  } elseif (isset($function_data['callable'])) {
96
    $override_with = &$function_data['callable'];
97
  }
98
99
  $overwrite = $override_with[0] == '*';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $override_with does not seem to be defined for all execution paths leading up to this point.
Loading history...
100
  $prepend   = $override_with[0] == '+';
101
  if ($overwrite || $prepend) {
102
    $override_with = substr($override_with, 1);
103
  }
104
105
  if (($point_position = strpos($override_with, '.')) === false && $class_module_name) {
106
    $override_with = array($class_module_name, $override_with);
107
  } elseif ($point_position == 0) {
108
    $override_with = substr($override_with, 1);
109
  } elseif ($point_position > 0) {
110
    $override_with = array(substr($override_with, 0, $point_position), substr($override_with, $point_position + 1));
111
  }
112
113
  if ($overwrite) {
114
    $functions[$function_name] = array();
115
  } elseif (!isset($functions[$function_name])) {
116
    $functions[$function_name] = array();
117
    $sn_function_name          = 'sn_' . $function_name . ($sub_type ? '_' . $sub_type : '');
118
    //if(is_callable($sn_function_name))
119
    {
120
      $functions[$function_name][] = $sn_function_name;
121
    }
122
  }
123
124
  if ($prepend) {
125
    array_unshift($functions[$function_name], $function_data);
126
  } else {
127
    $functions[$function_name][] = $function_data;
128
  }
129
}
130
131
132
// FLEET FUNCTIONS -----------------------------------------------------------------------------------------------------
133
/**
134
 * @param MissionExplore $result
135
 *
136
 * @return MissionExplore
137
 */
138
function flt_mission_explore_addon_object($result) { return sn_function_call('flt_mission_explore_addon_object', [$result]); }
139
140
/**
141
 * @param MissionExplore $result
142
 *
143
 * @return MissionExplore
144
 */
145
function sn_flt_mission_explore_addon_object($result) {
146
  return $result;
147
}
148
149
// FILE FUNCTIONS ----------------------------------------------------------------------------------------------------------------
150
function sys_file_read($filename) {
151
  return @file_get_contents($filename);
152
}
153
154
function sys_file_write($filename, $content) {
155
  return @file_put_contents($filename, $content, FILE_APPEND);
156
}
157
158
function sn_sys_load_php_files($dir_name, $load_extension = 'php') {
159
  if (file_exists($dir_name)) {
160
    $dir = opendir($dir_name);
161
    while (($file = readdir($dir)) !== false) {
162
      if ($file == '..' || $file == '.') {
163
        continue;
164
      }
165
166
      $full_filename = $dir_name . $file;
167
      $extension     = substr($full_filename, -strlen($load_extension));
168
      if ($extension == $load_extension) {
169
        require_once($full_filename);
170
      }
171
    }
172
  }
173
}
174
175
176
// GLOBAL DATA FUNCTIONS -----------------------------------------------------------------------------------------------
177
/**
178
 * Simple wrapper to get base or calculated value for supplied unitSnId
179
 *
180
 * @param int  $unitSnId
181
 * @param bool $plain
182
 *
183
 * @return float|int
184
 */
185
function getValueFromStorage($unitSnId, $plain = false) {
186
  $valueObject = SN::$gc->valueStorage->getValueObject($unitSnId);
187
188
  return $plain ? $valueObject->base : $valueObject->getValue();
189
}
190
191
/**
192
 * Get game resource multiplier aka mining speed
193
 *
194
 * @param bool $plain
195
 *
196
 * @return float|int
197
 */
198
function game_resource_multiplier($plain = false) {
199
  return getValueFromStorage(UNIT_SERVER_SPEED_MINING, $plain);
0 ignored issues
show
Bug introduced by
UNIT_SERVER_SPEED_MINING of type string is incompatible with the type integer expected by parameter $unitSnId of getValueFromStorage(). ( Ignorable by Annotation )

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

199
  return getValueFromStorage(/** @scrutinizer ignore-type */ UNIT_SERVER_SPEED_MINING, $plain);
Loading history...
200
}
201
202
/**
203
 * Get game speed aka manufacturing speed
204
 *
205
 * @param bool $plain
206
 *
207
 * @return float|int
208
 */
209
function get_game_speed($plain = false) {
210
  return getValueFromStorage(UNIT_SERVER_SPEED_BUILDING, $plain);
0 ignored issues
show
Bug introduced by
UNIT_SERVER_SPEED_BUILDING of type string is incompatible with the type integer expected by parameter $unitSnId of getValueFromStorage(). ( Ignorable by Annotation )

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

210
  return getValueFromStorage(/** @scrutinizer ignore-type */ UNIT_SERVER_SPEED_BUILDING, $plain);
Loading history...
211
}
212
213
/**
214
 * Получение стоимости ММ в валюте сервера
215
 *
216
 * @param bool|false $plain
217
 *
218
 * @return mixed
219
 */
220
function get_mm_cost($plain = false) {
221
  $result = null;
222
223
  return sn_function_call('get_mm_cost', array($plain, &$result));
224
}
225
226
function sn_get_mm_cost($plain = false, &$result) {
227
  return $result = SN::$config->payment_currency_exchange_mm_ ? SN::$config->payment_currency_exchange_mm_ : 20000;
228
}
229
230
/**
231
 * Получение курса обмены валюты в серверную валюту
232
 *
233
 * @param $currency_symbol
234
 *
235
 * @return float
236
 */
237
function get_exchange_rate($currency_symbol) {
238
  $currency_symbol = strtolower($currency_symbol);
239
  $config_field    = 'payment_currency_exchange_' . $currency_symbol;
240
241
  // Заворачиваем получение стоимости ММ через перекрываемую процедуру
242
  $exchange_rate = floatval($currency_symbol == 'mm_' ? get_mm_cost() : SN::$config->$config_field);
243
244
  return $exchange_rate;
245
}
246
247
function sys_stat_get_user_skip_list() {
248
  $result = array();
249
250
  $user_skip_list = array();
251
252
  if (SN::$config->stats_hide_admins) {
253
    $user_skip_list[] = '`authlevel` > ' . AUTH_LEVEL_REGISTERED;
254
  }
255
256
  if (SN::$config->stats_hide_player_list) {
257
    $temp = explode(',', SN::$config->stats_hide_player_list);
258
    foreach ($temp as $user_id) {
259
      if ($user_id = floatval($user_id)) {
260
        $user_skip_list[] = '`id` = ' . $user_id;
261
      }
262
    }
263
  }
264
265
  if (!empty($user_skip_list)) {
266
    $user_skip_list  = implode(' OR ', $user_skip_list);
267
    $user_skip_query = db_user_list($user_skip_list);
0 ignored issues
show
Deprecated Code introduced by
The function db_user_list() 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

267
    $user_skip_query = /** @scrutinizer ignore-deprecated */ db_user_list($user_skip_list);
Loading history...
268
    if (!empty($user_skip_query)) {
269
      foreach ($user_skip_query as $user_skip_row) {
270
        $result[$user_skip_row['id']] = $user_skip_row['id'];
271
      }
272
    }
273
  }
274
275
  return $result;
276
}
277
278
function market_get_autoconvert_cost() {
279
  return SN::$config->rpg_cost_exchange ? SN::$config->rpg_cost_exchange * 3 : 3000;
0 ignored issues
show
Bug Best Practice introduced by
The property rpg_cost_exchange does not exist on classConfig. Since you implemented __get, consider adding a @property annotation.
Loading history...
280
}
281
282
function sn_powerup_get_price_matrix($powerup_id, $powerup_unit = false, $level_max = null, $plain = false) {
283
  $result = null;
284
285
  return sn_function_call('sn_powerup_get_price_matrix', array($powerup_id, $powerup_unit, $level_max, $plain, &$result));
286
}
287
288
function sn_sn_powerup_get_price_matrix($powerup_id, $powerup_unit = false, $level_max = null, $plain = false, &$result) {
289
  global $sn_powerup_buy_discounts;
290
291
  $result = array();
292
293
  $powerup_data = get_unit_param($powerup_id);
294
  $is_upgrade   = !empty($powerup_unit) && $powerup_unit;
295
296
  $level_current = $term_original = $time_left = 0;
297
  if ($is_upgrade) {
298
    $time_finish = strtotime($powerup_unit['unit_time_finish']);
299
    $time_left   = max(0, $time_finish - SN_TIME_NOW);
300
    if ($time_left > 0) {
301
      $term_original = $time_finish - strtotime($powerup_unit['unit_time_start']);
302
      $level_current = $powerup_unit['unit_level'];
303
    }
304
  }
305
306
  $level_max     = $level_max > $powerup_data[P_MAX_STACK] ? $level_max : $powerup_data[P_MAX_STACK];
307
  $original_cost = 0;
308
  for ($i = 1; $i <= $level_max; $i++) {
309
    $base_cost = eco_get_total_cost($powerup_id, $i);
310
    $base_cost = $base_cost[BUILD_CREATE][RES_DARK_MATTER];
311
    foreach ($sn_powerup_buy_discounts as $period => $discount) {
312
      $upgrade_price       = floor($base_cost * $discount * $period / PERIOD_MONTH);
313
      $result[$i][$period] = $upgrade_price;
314
      $original_cost       = $is_upgrade && $i == $level_current && $period <= $term_original ? $upgrade_price : $original_cost;
315
    }
316
  }
317
318
  if ($is_upgrade && $time_left) {
319
    $term_original = round($term_original / PERIOD_DAY);
320
    $time_left     = min(floor($time_left / PERIOD_DAY), $term_original);
321
    $cost_left     = $term_original > 0 ? ceil($time_left / $term_original * $original_cost) : 0;
322
323
    array_walk_recursive($result, function (&$value) use ($cost_left) {
324
      $value -= $cost_left;
325
    });
326
  }
327
328
  return $result;
329
}
330
331
/**
332
 * @param $price_matrix_plain
333
 * @param $price_matrix_original
334
 * @param $price_matrix_upgrade
335
 * @param $user_dark_matter
336
 *
337
 * @return array
338
 *
339
 * Used in player_premium and interface_batch_operation modules
340
 */
341
function price_matrix_templatize(&$price_matrix_plain, &$price_matrix_original, &$price_matrix_upgrade, $user_dark_matter) {
342
  $prices = array();
343
  foreach ($price_matrix_original as $level_num => $level_data) {
344
    $price_per_period = array();
345
    foreach ($level_data as $period => $price) {
346
      $price_per_period[$period] = array(
347
        'PERIOD'             => $period,
348
        'PRICE_ORIGIN'       => $price,
349
        'PRICE_ORIGIN_TEXT'  => HelperString::numberFloorAndFormat($price),
350
        'PRICE_ORIGIN_CLASS' => prettyNumberGetClass($price, $user_dark_matter),
351
        'PRICE_UPGRADE'      => $price_matrix_upgrade[$level_num][$period],
352
        'PRICE_UPGRADE_TEXT' => HelperString::numberFloorAndFormat($price_matrix_upgrade[$level_num][$period]),
353
      );
354
      if (isset($price_matrix_plain[$level_num][$period])) {
355
        $price_per_period[$period] += array(
356
          'PRICE_PLAIN_PERCENT' => ceil(100 - ($price / $price_matrix_plain[$level_num][$period]) * 100),
357
          'PRICE_PLAIN'         => $price_matrix_plain[$level_num][$period],
358
          'PRICE_PLAIN_TEXT'    => HelperString::numberFloorAndFormat($price_matrix_plain[$level_num][$period]),
359
        );
360
      }
361
    }
362
363
    $prices[$level_num] = array(
364
      '.'     => array('period' => $price_per_period),
365
      'LEVEL' => $level_num,
366
    );
367
  }
368
369
  return $prices;
370
}
371
372
373
// TOOLS & UTILITIES ----------------------------------------------------------------------------------------------------------------
374
/**
375
 * Generates random string of $length symbols from $allowed_chars charset
376
 *
377
 * @param int    $length
378
 * @param string $allowed_chars
379
 *
380
 * @return string
381
 */
382
function sys_random_string($length = 16, $allowed_chars = SN_SYS_SEC_CHARS_ALLOWED) {
383
  $allowed_length = strlen($allowed_chars);
384
385
  $random_string = '';
386
  for ($i = 0; $i < $length; $i++) {
387
    $random_string .= $allowed_chars[mt_rand(0, $allowed_length - 1)];
388
  }
389
390
  return $random_string;
391
}
392
393
function array_merge_recursive_numeric($array1, $array2) {
394
  if (!empty($array2) && is_array($array2)) {
395
    foreach ($array2 as $key => $value) {
396
      $array1[$key] = !isset($array1[$key]) || !is_array($array1[$key]) ? $value : array_merge_recursive_numeric($array1[$key], $value);
397
    }
398
  }
399
400
  return $array1;
401
}
402
403
function sn_sys_array_cumulative_sum(&$array) {
404
  $accum = 0;
405
  foreach ($array as &$value) {
406
    $accum += $value;
407
    $value = $accum;
408
  }
409
}
410
411
function print_rr($var, $capture = false) {
412
  $print = '<pre>' . htmlspecialchars(print_r($var, true)) . '</pre>';
0 ignored issues
show
Bug introduced by
It seems like print_r($var, true) can also be of type true; however, parameter $string of htmlspecialchars() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

412
  $print = '<pre>' . htmlspecialchars(/** @scrutinizer ignore-type */ print_r($var, true)) . '</pre>';
Loading history...
413
  if ($capture) {
414
    return $print;
415
  } else {
416
    print($print);
417
  }
418
}
419
420
/**
421
 * Returns unique string ID for total fleets on planet
422
 *
423
 * @param array $planetTemplatized
424
 *
425
 * @return int|string
426
 */
427
function getUniqueFleetId($planetTemplatized) {
428
  return empty($planetTemplatized['id']) ? 0 : sprintf(FLEET_ID_TEMPLATE, $planetTemplatized['id']);
429
}
430
431
/**
432
 * @param array $context
433
 *
434
 * @return array
435
 */
436
function getLocationFromContext($context = []) {
437
  if (!empty($context[LOC_FLEET])) {
438
    return [LOC_FLEET, $context[LOC_FLEET]['fleet_id']];
439
  } elseif (!empty($context[LOC_PLANET])) {
440
    return [LOC_PLANET, $context[LOC_PLANET]['id']];
441
  } elseif (!empty($context[LOC_USER])) {
442
    return [LOC_USER, $context[LOC_USER]['id']];
443
  } else {
444
    return [LOC_SERVER, 0];
445
  }
446
447
}
448
449
450
//
451
452
453
// MAIL ----------------------------------------------------------------------------------------------------------------
454
function mymail($email_unsafe, $title, $body, $from = '', $html = false) {
455
  $from = trim($from ? $from : SN::$config->game_adminEmail);
456
457
  $head = '';
458
  $head .= "Content-Type: text/" . ($html ? 'html' : 'plain') . "; charset=utf-8 \r\n";
459
  $head .= "Date: " . date('r') . " \r\n";
460
  $head .= "Return-Path: " . SN::$config->game_adminEmail . " \r\n";
461
  $head .= "From: {$from} \r\n";
462
  $head .= "Sender: {$from} \r\n";
463
  $head .= "Reply-To: {$from} \r\n";
464
//  $head .= "Organization: {$org} \r\n";
465
  $head .= "X-Sender: {$from} \r\n";
466
  $head .= "X-Priority: 3 \r\n";
467
468
  $body = str_replace("\r\n", "\n", $body);
469
  $body = str_replace("\n", "\r\n", $body);
470
471
  if ($html) {
472
    $body = '<html><head><base href="' . SN_ROOT_VIRTUAL . '"></head><body>' . nl2br($body) . '</body></html>';
473
  }
474
475
  $title = '=?UTF-8?B?' . base64_encode($title) . '?=';
476
477
  return @mail($email_unsafe, $title, $body, $head);
478
}
479
480
481
// VERSION FUNCTIONS ----------------------------------------------------------------------------------------------------------------
482
function sn_version_compare_extra($version) {
483
  static $version_regexp = '#(\d+)([a-f])(\d+)(?:\.(\d+))*#';
484
  preg_match($version_regexp, $version, $version);
485
  unset($version[0]);
486
  $version[2] = ord($version[2]) - ord('a');
487
488
  return implode('.', $version);
489
}
490
491
function sn_version_compare($ver1, $ver2) {
492
  return version_compare(sn_version_compare_extra($ver1), sn_version_compare_extra($ver2));
493
}
494
495
496
// MODULES FUNCTIONS ---------------------------------------------------------------------------------------------------
497
/**
498
 * Return Award module or NULL
499
 *
500
 * For typecasting
501
 *
502
 * @return null|player_award
0 ignored issues
show
Bug introduced by
The type player_award was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
503
 */
504
function moduleAward() {
505
  return SN::$gc->modules->getModule('player_award');
0 ignored issues
show
Bug Best Practice introduced by
The expression return SN::gc->modules->getModule('player_award') also could return the type Modules\sn_module which is incompatible with the documented return type null|player_award.
Loading history...
506
}
507
508
/**
509
 * Return Captain module or NULL
510
 *
511
 * For typecasting
512
 *
513
 * @return null|unit_captain
0 ignored issues
show
Bug introduced by
The type unit_captain was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
514
 */
515
function moduleCaptain() {
516
  return SN::$gc->modules->getModule('unit_captain');
0 ignored issues
show
Bug Best Practice introduced by
The expression return SN::gc->modules->getModule('unit_captain') also could return the type Modules\sn_module which is incompatible with the documented return type null|unit_captain.
Loading history...
517
}
518
519
/**
520
 * Updates users online count
521
 *
522
 * We should move this to separate function due to ambiguency of pass() method
523
 *
524
 * @param $usersOnline
525
 */
526
function dbUpdateUsersOnline($usersOnline) {
527
  SN::$config->pass()->var_online_user_count = $usersOnline;
528
}
529
530
/**
531
 * Updates total user count
532
 *
533
 * We should move this to separate function due to ambiguency of pass() method
534
 *
535
 * @param $userCount
536
 */
537
function dbUpdateUsersCount($userCount) {
538
  SN::$config->pass()->users_amount = $userCount;
539
}
540