Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Push — master ( 2b39bd...8870e8 )
by Dan
12:21
created

xmlify()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php declare(strict_types=1);
2
3
function htmliseMessage($message) {
4
	$message = htmlentities($message, ENT_COMPAT, 'utf-8');
5
	$message = str_replace('&lt;br /&gt;', '<br />', $message);
6
	return $message;
7
}
8
9
function parseBoolean($check) {
10
	// Only negative strings are not implicitly converted to the correct bool
11
	if (is_string($check) && (strcasecmp($check, 'NO') == 0 || strcasecmp($check, 'FALSE') == 0)) {
12
		return false;
13
	}
14
	return (bool)$check;
15
}
16
17
function linkCombatLog($logID) {
18
	$container = create_container('combat_log_viewer_verify.php');
19
	$container['log_id'] = $logID;
20
	return '<a href="' . SmrSession::getNewHREF($container) . '"><img src="images/notify.gif" width="14" height="11" border="0" title="View the combat log" /></a>';
21
}
22
23
/**
24
 * Converts a BBCode tag into some other text depending on the tag and value.
25
 * This is called in two stages: first with action BBCODE_CHECK (where the
26
 * returned value must be a boolean) and second, if the first check passes,
27
 * with action BBCODE_OUTPUT.
28
 */
29
function smrBBCode($bbParser, $action, $tagName, $default, $tagParams, $tagContent) {
0 ignored issues
show
Unused Code introduced by
The parameter $bbParser is not used and could be removed. ( Ignorable by Annotation )

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

29
function smrBBCode(/** @scrutinizer ignore-unused */ $bbParser, $action, $tagName, $default, $tagParams, $tagContent) {

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

Loading history...
30
	global $overrideGameID, $disableBBLinks, $player, $account, $var;
31
	try {
32
		switch ($tagName) {
33
			case 'combatlog':
34
				if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
35
					return is_numeric($default);
36
				}
37
				$logID = (int)$default;
38
				return linkCombatLog($logID);
39
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
40
			case 'player':
41
				if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
42
					return is_numeric($default);
43
				}
44
				$playerID = (int)$default;
45
				$bbPlayer = SmrPlayer::getPlayerByPlayerID($playerID, $overrideGameID);
46
				$showAlliance = isset($tagParams['showalliance']) ? parseBoolean($tagParams['showalliance']) : false;
47
				if ($disableBBLinks === false && $overrideGameID == SmrSession::getGameID()) {
48
					return $bbPlayer->getLinkedDisplayName($showAlliance);
49
				}
50
				return $bbPlayer->getDisplayName($showAlliance);
51
			break;
52
			case 'alliance':
53
				if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
54
					return is_numeric($default);
55
				}
56
				$allianceID = (int)$default;
57
				$alliance = SmrAlliance::getAlliance($allianceID, $overrideGameID);
58
				if ($disableBBLinks === false && $overrideGameID == SmrSession::getGameID()) {
59
					$container = create_container('skeleton.php');
60
					$container['alliance_id'] = $alliance->getAllianceID();
61
					if (is_object($player) && $alliance->getAllianceID() == $player->getAllianceID()) {
62
						$container['body'] = 'alliance_mod.php';
63
					} else {
64
						$container['body'] = 'alliance_roster.php';
65
					}
66
					return create_link($container, $alliance->getAllianceDisplayName());
67
				}
68
				return $alliance->getAllianceDisplayName();
69
			break;
70
			case 'race':
71
				$raceNameID = $default;
72
				foreach (Globals::getRaces() as $raceID => $raceInfo) {
73
					if ((is_numeric($raceNameID) && $raceNameID == $raceID)
74
						|| $raceNameID == $raceInfo['Race Name']) {
75
						if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
76
							return true;
77
						}
78
						$linked = $disableBBLinks === false && $overrideGameID == SmrSession::getGameID();
79
						return AbstractSmrPlayer::getColouredRaceNameOrDefault($raceID, $player, $linked);
80
					}
81
				}
82
			break;
83
			case 'servertimetouser':
84
				if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
85
					return true;
86
				}
87
				$timeString = $default;
88
				if ($timeString != '' && ($time = strtotime($timeString)) !== false) {
89
					if (is_object($account)) {
90
						$time += $account->getOffset() * 3600;
91
					}
92
					return date(DATE_FULL_SHORT, $time);
93
				}
94
			break;
95
			case 'chess':
96
				if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
97
					return is_numeric($default);
98
				}
99
				$chessGameID = (int)$default;
100
				$chessGame = ChessGame::getChessGame($chessGameID);
101
				return '<a href="' . $chessGame->getPlayGameHREF() . '">chess game (' . $chessGame->getChessGameID() . ')</a>';
102
			break;
103
104
			case 'sector':
105
				if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
106
					return is_numeric($default);
107
				}
108
109
				$sectorID = (int)$default;
110
				$sectorTag = '<span class="sectorColour">#' . $sectorID . '</span>';
111
112
				// The use of $var here is for a corner case where an admin can check reported messages whilst being in-game.
113
				// Ugly but working, probably want a better mechanism to check if more BBCode tags get added
114
				if ($disableBBLinks === false
115
					&& SmrSession::hasGame()
116
					&& SmrSession::getGameID() == $overrideGameID
117
					&& SmrSector::sectorExists($overrideGameID, $sectorID)) {
118
					return '<a href="' . Globals::getPlotCourseHREF($player->getSectorID(), $sectorID) . '">' . $sectorTag . '</a>';
119
				}
120
121
				return $sectorTag;
122
			break;
123
			case 'join_alliance':
124
				if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
125
					return is_numeric($default);
126
				}
127
				$allianceID = (int)$default;
128
				$alliance = SmrAlliance::getAlliance($allianceID, $overrideGameID);
129
				$container = create_container('alliance_invite_accept_processing.php');
130
				$container['alliance_id'] = $alliance->getAllianceID();
131
				return '<div class="buttonA"><a class="buttonA" href="' . SmrSession::getNewHREF($container) . '">Join ' . $alliance->getAllianceDisplayName() . '</a></div>';
132
			break;
133
		}
134
	} catch (Throwable $e) {
135
		// If there's an error, we will silently display the original text
136
	}
137
	if ($action == \Nbbc\BBCode::BBCODE_CHECK) {
138
		return false;
139
	}
140
	return htmlspecialchars($tagParams['_tag']) . $tagContent . htmlspecialchars($tagParams['_endtag']);
141
}
142
143
function xmlify($str) {
144
	$xml = htmlspecialchars($str, ENT_XML1, 'utf-8');
145
	return $xml;
146
}
147
148
function inify($text) {
149
	return str_replace(',', '', html_entity_decode($text));
150
}
151
152
function bbifyMessage($message, $noLinks = false) {
153
	static $bbParser;
154
	if (!isset($bbParser)) {
155
		$bbParser = new \Nbbc\BBCode();
156
		$bbParser->SetEnableSmileys(false);
157
		$bbParser->RemoveRule('wiki');
158
		$bbParser->RemoveRule('img');
159
		$bbParser->SetURLTarget('_blank');
160
		$bbParser->SetURLTargetable('override');
161
		$bbParser->setEscapeContent(false); // don't escape HTML, needed for News etc.
162
		$smrRule = array(
163
				'mode' => \Nbbc\BBCode::BBCODE_MODE_CALLBACK,
164
				'method' => 'smrBBCode',
165
				'class' => 'link',
166
				'allow_in' => Array('listitem', 'block', 'columns', 'inline'),
167
				'end_tag' => \Nbbc\BBCode::BBCODE_PROHIBIT,
168
				'content' => \Nbbc\BBCode::BBCODE_PROHIBIT,
169
			);
170
		$bbParser->AddRule('combatlog', $smrRule);
171
		$bbParser->AddRule('player', $smrRule);
172
		$bbParser->AddRule('alliance', $smrRule);
173
		$bbParser->AddRule('race', $smrRule);
174
		$bbParser->AddRule('servertimetouser', $smrRule);
175
		$bbParser->AddRule('chess', $smrRule);
176
		$bbParser->AddRule('sector', $smrRule);
177
		$bbParser->addRule('join_alliance', $smrRule);
178
	}
179
	global $disableBBLinks;
180
	if ($noLinks === true) {
181
		$disableBBLinks = true;
182
	} else {
183
		$disableBBLinks = false;
184
	}
185
	if (strpos($message, '[') !== false) { //We have BBCode so let's do a full parse.
186
		$message = $bbParser->parse($message);
187
		$message = str_replace('&lt;br /&gt;', '<br />', $message);
188
	} else { //Otherwise just convert newlines
189
		$message = nl2br($message, true);
190
	}
191
	return $message;
192
}
193
194
function create_error($message) {
195
	$container = create_container('skeleton.php', 'error.php');
196
	$container['message'] = $message;
197
	if (USING_AJAX) {
198
		// To avoid the page just not refreshing when an error is encountered
199
		// during ajax updates, use javascript to auto-redirect to the
200
		// appropriate error page.
201
		global $template;
202
		if (is_object($template) && method_exists($template, 'addJavascriptForAjax')) {
203
			$errorHREF = SmrSession::getNewHREF($container);
204
			// json_encode the HREF as a safety precaution
205
			$template->addJavascriptForAjax('EVAL', 'location.href = ' . json_encode($errorHREF));
206
		}
207
	}
208
	forward($container);
209
}
210
211
function resetContainer($new_container, $sn = null) {
212
	global $container, $var;
213
214
	// this sn identifies our container later
215
	if (!is_null($sn)) {
216
		SmrSession::resetLink($new_container, $sn);
217
	}
218
219
	$var = $new_container;
220
	$container = $new_container;
221
}
222
223
function forward($new_container) {
224
	global $sn;
225
	if (defined('OVERRIDE_FORWARD') && OVERRIDE_FORWARD === true) {
226
		return overrideForward($new_container);
227
	}
228
	resetContainer($new_container, $sn);
229
	do_voodoo();
230
}
231
232
function forwardURL($new_container) {
233
	resetContainer($new_container);
234
	global $var;
235
	require_once(get_file_loc($var['url']));
236
}
237
238
function transfer($what) {
239
	global $var, $container;
240
241
	// transfer this value to next container
242
	if (isset($var[$what])) {
243
		$container[$what] = $var[$what];
244
	}
245
}
246
247
function create_container($file, $body = '', array $extra = array(), $remainingPageLoads = null) {
248
	$container = $extra;
249
	$container['url'] = $file;
250
	$container['body'] = $body;
251
	if ($remainingPageLoads) {
252
		$container['RemainingPageLoads'] = $remainingPageLoads;
253
	}
254
	return $container;
255
}
256
257
function create_link($container, $text, $class = null) {
258
	return '<a' . ($class == null ? '' : ' class="' . $class . '"') . ' href="' . (is_array($container) ?SmrSession::getNewHREF($container) : $container) . '">' . $text . '</a>';
259
}
260
261
function create_submit_link($container, $text) {
262
	return '<a href="' . SmrSession::getNewHREF($container) . '" class="submitStyle">' . $text . '</a>';
263
}
264
265
function get_colored_text_range($value, $maxValue, $text = null, $minValue = 0, $type = 'Game', $return_type = 'Normal') {
266
	if ($text == null) {
267
		$text = number_format($value);
268
	}
269
	if ($maxValue - $minValue == 0) {
270
		return $text;
271
	} else {
272
		$normalisedValue = IRound(510 * max(0, min($maxValue, $value) - $minValue) / ($maxValue - $minValue)) - 255;
273
	}
274
	if ($type == 'Game') {
275
		if ($normalisedValue < 0) {
276
			$r_component = 'ff';
277
			$g_component = dechex(255 + $normalisedValue);
278
			if (strlen($g_component) == 1) {
279
				$g_component = '0' . $g_component;
280
			}
281
		} else if ($normalisedValue > 0) {
282
			$g_component = 'ff';
283
			$r_component = dechex(255 - $normalisedValue);
284
			if (strlen($r_component) == 1) {
285
				$r_component = '0' . $r_component;
286
			}
287
		} else {
288
			$r_component = 'ff';
289
			$g_component = 'ff';
290
		}
291
		$colour = $r_component . $g_component . '00';
292
		if ($return_type == 'Colour') {
293
			return $colour;
294
		}
295
		return '<span style="color:#' . $colour . '">' . $text . '</span>';
296
	} elseif ($type == 'IRC') {
297
		//IRC color codes
298
		if ($normalisedValue == 255) {
299
			$colour = '[k03]';
300
		} elseif ($normalisedValue == -255) {
301
			$colour = '[k04]';
302
		} else {
303
			$colour = '[k08]';
304
		}
305
		if ($return_type == 'Colour') {
306
			return $colour;
307
		}
308
		return $colour . $text;
309
	}
310
}
311
312
function get_colored_text($value, $text = null, $type = 'Game', $return_type = 'Normal') {
313
	return get_colored_text_range($value, 300, $text, -300, $type, $return_type);
314
}
315
316
function word_filter($string) {
317
	static $words;
318
319
	if (!is_array($words)) {
320
		$db = new SmrMySqlDatabase();
321
		$db->query('SELECT word_value, word_replacement FROM word_filter');
322
		$words = array();
323
		while ($db->nextRecord()) {
324
			$row = $db->getRow();
325
			$words[] = array('word_value' => '/' . str_replace('/', '\/', $row['word_value']) . '/i', 'word_replacement'=> $row['word_replacement']);
326
		}
327
	}
328
329
	foreach ($words as $word) {
330
		$string = preg_replace($word['word_value'], $word['word_replacement'], $string);
331
	}
332
333
	return $string;
334
}
335
336
// choose correct pluralization based on amount
337
function pluralise($word, $count = 0) {
338
	if ($count == 1) {
339
		return $word;
340
	}
341
	if (strtolower($word) == 'is') {
342
		return 'are';
343
	}
344
	return $word . 's';
345
}
346
347
/**
348
 * This function is a hack around the old style http forward mechanism.
349
 * It is also responsible for setting most of the global variables
350
 * (see loader.php for the initialization of the globals).
351
 */
352
function do_voodoo() {
353
	global $lock, $var, $container, $player, $ship, $sector, $account, $db, $template;
354
355
	if (!defined('AJAX_CONTAINER')) {
356
		define('AJAX_CONTAINER', isset($var['AJAX']) && $var['AJAX'] === true);
357
	}
358
	if (!AJAX_CONTAINER && USING_AJAX && SmrSession::hasChangedSN()) {
359
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
360
	}
361
//	ob_clean();
362
363
	// create account object
364
	$account = SmrSession::getAccount();
365
366
	if (!defined('DATE_DATE_SHORT')) {
367
		define('DATE_DATE_SHORT', $account->getShortDateFormat());
368
	}
369
	if (!defined('DATE_TIME_SHORT')) {
370
		define('DATE_TIME_SHORT', $account->getShortTimeFormat());
371
	}
372
	if (!defined('DATE_FULL_SHORT')) {
373
		define('DATE_FULL_SHORT', DATE_DATE_SHORT . ' ' . DATE_TIME_SHORT);
374
	}
375
	if (!defined('DATE_FULL_SHORT_SPLIT')) {
376
		define('DATE_FULL_SHORT_SPLIT', DATE_DATE_SHORT . '\<b\r /\>' . DATE_TIME_SHORT);
377
	}
378
379
	// initialize objects we usually need, like player, ship
380
	if (SmrSession::hasGame()) {
381
		if (SmrGame::getGame(SmrSession::getGameID())->hasEnded()) {
382
			forward(create_container('game_leave_processing.php', 'game_play.php', array('errorMsg' => 'The game has ended.')));
383
		}
384
		// We need to acquire locks BEFORE getting the player information
385
		// Otherwise we could be working on stale information
386
		$db->query('SELECT sector_id FROM player WHERE account_id=' . $db->escapeNumber($account->getAccountID()) . ' AND game_id=' . $db->escapeNumber(SmrSession::getGameID()) . ' LIMIT 1');
387
		$db->requireRecord();
388
		$sector_id = $db->getInt('sector_id');
389
390
		global $locksFailed;
391
		if (!USING_AJAX //AJAX should never do anything that requires a lock.
392
//			&& !isset($var['url']) && ($var['body'] == 'current_sector.php' || $var['body'] == 'map_local.php') //Neither should CS or LM and they gets loaded a lot so should reduce lag issues with big groups.
393
			) {
394
			if (!$lock && !isset($locksFailed[$sector_id])) {
395
				if (!acquire_lock($sector_id)) {
396
					create_error('Failed to acquire sector lock');
397
				}
398
				//Refetch var info in case it changed between grabbing lock.
399
				SmrSession::fetchVarInfo();
400
				if (!($var = SmrSession::retrieveVar())) {
401
					if (ENABLE_DEBUG) {
402
						$db->query('INSERT INTO debug VALUES (\'SPAM\',' . $db->escapeNumber($account->getAccountID()) . ',0,0)');
403
					}
404
					create_error('Please do not spam click!');
405
				}
406
			}
407
		}
408
409
		// Now that they've acquire a lock we can move on
410
		$player = SmrPlayer::getPlayer($account->getAccountID(), SmrSession::getGameID());
411
412
		if ($player->isDead() && $var['url'] != 'death_processing.php' && !isset($var['override_death'])) {
413
			forward(create_container('death_processing.php'));
414
		}
415
416
		$ship = $player->getShip();
417
		$sector = $player->getSector();
418
419
		// update turns on that player
420
		$player->updateTurns();
421
422
		if (!$player->isDead() && $player->getNewbieTurns() <= NEWBIE_TURNS_WARNING_LIMIT &&
423
			$player->getNewbieWarning() &&
424
			$var['url'] != 'newbie_warning_processing.php')
425
			forward(create_container('newbie_warning_processing.php'));
426
	}
427
428
	// Initialize the template
429
	$template = new Template();
430
431
	if ($var['url'] != 'skeleton.php') {
432
		require(get_file_loc($var['url']));
433
	}
434
	if ($var['body']) {
435
		if ($var['body'] == 'error.php') { // infinite includes for error pages
436
			require(get_file_loc($var['body']));
437
		} else {
438
			require_once(get_file_loc($var['body']));
439
		}
440
	}
441
442
	if (SmrSession::hasGame()) {
443
		$template->assign('UnderAttack', $ship->removeUnderAttack());
444
	}
445
446
	if ($lock) { //Only save if we have the lock.
447
		SmrSector::saveSectors();
448
		SmrShip::saveShips();
449
		SmrPlayer::savePlayers();
450
		SmrForce::saveForces();
451
		SmrPort::savePorts();
452
		SmrPlanet::savePlanets();
453
		if (class_exists('WeightedRandom', false)) {
454
			WeightedRandom::saveWeightedRandoms();
455
		}
456
		//Update session here to make sure current page $var is up to date before releasing lock.
457
		SmrSession::update();
458
		release_lock();
459
	}
460
461
	//Nothing below this point should require the lock.
462
463
	$template->assign('TemplateBody', $var['body']);
464
	if (SmrSession::hasGame()) {
465
		$template->assign('ThisSector', $sector);
466
		$template->assign('ThisPlayer', $player);
467
		$template->assign('ThisShip', $ship);
468
	}
469
	$template->assign('ThisAccount', $account);
470
	if ($account->getCssLink() != null) {
471
		$template->assign('ExtraCSSLink', $account->getCssLink());
472
	}
473
	doSkeletonAssigns($template, $player, $ship, $sector, $db, $account, $var);
474
475
	// Set ajax refresh time
476
	$ajaxRefresh = $var['AllowAjax'] ?? true; // hack for bar_gambling_processing.php
477
	if (!$account->isUseAJAX()) {
478
		$ajaxRefresh = false;
479
	}
480
	if ($ajaxRefresh) {
481
		// If we can refresh, specify the refresh interval in millisecs
482
		if (SmrSession::hasGame() && $player->canFight()) {
483
			$ajaxRefresh = AJAX_UNPROTECTED_REFRESH_TIME;
484
		} else {
485
			$ajaxRefresh = AJAX_DEFAULT_REFRESH_TIME;
486
		}
487
	}
488
	$template->assign('AJAX_ENABLE_REFRESH', $ajaxRefresh);
489
490
	$template->display($var['url'], USING_AJAX || AJAX_CONTAINER);
491
492
	SmrSession::update();
493
494
	exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
495
}
496
497
//xdebug_dump_function_profile(2);
498
499
// This is hackish, but without row level locking it's the best we can do
500
function acquire_lock($sector) {
501
	global $db, $lock, $locksFailed;
502
503
	if ($lock) {
504
		return true;
505
	}
506
507
	// Insert ourselves into the queue.
508
	$db->query('INSERT INTO locks_queue (game_id,account_id,sector_id,timestamp) VALUES(' . $db->escapeNumber(SmrSession::getGameID()) . ',' . $db->escapeNumber(SmrSession::getAccountID()) . ',' . $db->escapeNumber($sector) . ',' . $db->escapeNumber(TIME) . ')');
509
	$lock = $db->getInsertID();
510
511
	for ($i = 0; $i < 250; ++$i) {
512
		if (time() - TIME >= LOCK_DURATION - LOCK_BUFFER) {
513
			break;
514
		}
515
		// If there is someone else before us in the queue we sleep for a while
516
		$db->query('SELECT COUNT(*) FROM locks_queue WHERE lock_id<' . $db->escapeNumber($lock) . ' AND sector_id=' . $db->escapeNumber($sector) . ' AND game_id=' . $db->escapeNumber(SmrSession::getGameID()) . ' AND timestamp > ' . $db->escapeNumber(TIME - LOCK_DURATION));
517
		$locksInQueue = -1;
0 ignored issues
show
Unused Code introduced by
The assignment to $locksInQueue is dead and can be removed.
Loading history...
518
		if ($db->nextRecord() && ($locksInQueue = $db->getInt('COUNT(*)')) > 0) {
519
			//usleep(100000 + mt_rand(0,50000));
520
521
			// We can only have one lock in the queue, anything more means someone is screwing around
522
			$db->query('SELECT COUNT(*) FROM locks_queue WHERE account_id=' . $db->escapeNumber(SmrSession::getAccountID()) . ' AND sector_id=' . $db->escapeNumber($sector) . ' AND timestamp > ' . $db->escapeNumber(TIME - LOCK_DURATION));
523
			if ($db->nextRecord() && $db->getInt('COUNT(*)') > 1) {
524
				release_lock();
525
				$locksFailed[$sector] = true;
526
				create_error('Multiple actions cannot be performed at the same time!');
527
			}
528
529
			usleep(25000 * $locksInQueue);
530
			continue;
531
		} else {
532
			return true;
533
		}
534
	}
535
536
	release_lock();
537
	$locksFailed[$sector] = true;
538
	return false;
539
}
540
541
function release_lock() {
542
	global $db, $lock;
543
	if ($lock) {
544
		$db->query('DELETE from locks_queue WHERE lock_id=' . $db->escapeNumber($lock) . ' OR timestamp<' . $db->escapeNumber(TIME - LOCK_DURATION));
545
	}
546
547
	$lock = false;
548
}
549
550
function doTickerAssigns($template, $player, $db) {
551
	//any ticker news?
552
	if ($player->hasTickers()) {
553
		$ticker = array();
554
		$max = TIME - 60;
555
		if ($player->hasTicker('NEWS')) {
556
			//get recent news (5 mins)
557
			$db->query('SELECT time,news_message FROM news WHERE game_id = ' . $db->escapeNumber($player->getGameID()) . ' AND time >= ' . $max . ' ORDER BY time DESC LIMIT 4');
558
			while ($db->nextRecord()) {
559
				$ticker[] = array('Time' => date(DATE_FULL_SHORT, $db->getInt('time')),
560
								'Message'=>$db->getField('news_message'));
561
			}
562
		}
563
		if ($player->hasTicker('SCOUT')) {
564
			$db->query('SELECT message_text,send_time FROM message
565
						WHERE account_id=' . $db->escapeNumber($player->getAccountID()) . '
566
						AND game_id=' . $db->escapeNumber($player->getGameID()) . '
567
						AND message_type_id=' . $db->escapeNumber(MSG_SCOUT) . '
568
						AND send_time>=' . $db->escapeNumber($max) . '
569
						AND sender_id NOT IN (SELECT account_id FROM player_has_ticker WHERE type='.$db->escapeString('BLOCK') . ' AND expires > ' . $db->escapeNumber(TIME) . ' AND game_id = ' . $db->escapeNumber($player->getGameID()) . ') AND receiver_delete = \'FALSE\'
570
						ORDER BY send_time DESC
571
						LIMIT 4');
572
			while ($db->nextRecord()) {
573
				$ticker[] = array('Time' => date(DATE_FULL_SHORT, $db->getInt('send_time')),
574
								'Message'=>$db->getField('message_text'));
575
			}
576
		}
577
		$template->assign('Ticker', $ticker);
578
	}
579
}
580
581
function doSkeletonAssigns($template, $player, $ship, $sector, $db, $account, $var) {
0 ignored issues
show
Unused Code introduced by
The parameter $sector is not used and could be removed. ( Ignorable by Annotation )

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

581
function doSkeletonAssigns($template, $player, $ship, /** @scrutinizer ignore-unused */ $sector, $db, $account, $var) {

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

Loading history...
582
	$template->assign('CSSLink', $account->getCssUrl());
583
	$template->assign('CSSColourLink', $account->getCssColourUrl());
584
585
	$template->assign('FontSize', $account->getFontSize() - 20);
586
	$template->assign('timeDisplay', date(DATE_FULL_SHORT_SPLIT, TIME));
587
588
	$container = create_container('skeleton.php');
589
590
591
	if (SmrSession::hasGame()) {
592
		$template->assign('GameName', SmrGame::getGame(SmrSession::getGameID())->getName());
593
		$template->assign('GameID', SmrSession::getGameID());
594
595
		$template->assign('PlotCourseLink', Globals::getPlotCourseHREF());
596
597
		$template->assign('TraderLink', Globals::getTraderStatusHREF());
598
599
		$template->assign('PoliticsLink', Globals::getPoliticsHREF());
600
601
		$container['body'] = 'combat_log_list.php';
602
		$template->assign('CombatLogsLink', SmrSession::getNewHREF($container));
603
604
		$template->assign('PlanetLink', Globals::getPlanetListHREF($player->getAllianceID()));
605
606
		$container['body'] = 'forces_list.php';
607
		$template->assign('ForcesLink', SmrSession::getNewHREF($container));
608
609
		$template->assign('MessagesLink', Globals::getViewMessageBoxesHREF());
610
611
		$container['body'] = 'news_read_current.php';
612
		$template->assign('ReadNewsLink', SmrSession::getNewHREF($container));
613
614
		$container['body'] = 'galactic_post_current.php';
615
		$template->assign('GalacticPostLink', SmrSession::getNewHREF($container));
616
617
		$container['body'] = 'trader_search.php';
618
		$template->assign('SearchForTraderLink', SmrSession::getNewHREF($container));
619
620
		$container['body'] = 'rankings_player_experience.php';
621
		$template->assign('RankingsLink', SmrSession::getNewHREF($container));
622
623
		$container['body'] = 'hall_of_fame_new.php';
624
		$container['game_id'] = $player->getGameID();
625
		$template->assign('CurrentHallOfFameLink', SmrSession::getNewHREF($container));
626
	}
627
628
	if (SmrSession::hasAccount()) {
629
		$container = create_container('skeleton.php', 'hall_of_fame_new.php');
630
		$template->assign('HallOfFameLink', SmrSession::getNewHREF($container));
631
632
		$template->assign('AccountID', SmrSession::getAccountID());
633
		$template->assign('PlayGameLink', SmrSession::getNewHREF(create_container('game_leave_processing.php', 'game_play.php')));
634
635
		$template->assign('LogoutLink', SmrSession::getNewHREF(create_container('logoff.php')));
636
	}
637
638
	$container = create_container('game_leave_processing.php', 'admin_tools.php');
639
	$template->assign('AdminToolsLink', SmrSession::getNewHREF($container));
640
641
	$container = create_container('skeleton.php', 'preferences.php');
642
	$template->assign('PreferencesLink', SmrSession::getNewHREF($container));
643
644
	$container['body'] = 'album_edit.php';
645
	$template->assign('EditPhotoLink', SmrSession::getNewHREF($container));
646
647
	$container['body'] = 'bug_report.php';
648
	$template->assign('ReportABugLink', SmrSession::getNewHREF($container));
649
650
	$container['body'] = 'contact.php';
651
	$template->assign('ContactFormLink', SmrSession::getNewHREF($container));
652
653
	$container['body'] = 'chat_rules.php';
654
	$template->assign('IRCLink', SmrSession::getNewHREF($container));
655
656
	$container['body'] = 'donation.php';
657
	$template->assign('DonateLink', SmrSession::getNewHREF($container));
658
659
660
661
	if (SmrSession::hasGame()) {
662
		$db->query('SELECT message_type_id,COUNT(*) FROM player_has_unread_messages WHERE account_id=' . $db->escapeNumber($player->getAccountID()) . ' AND game_id=' . $db->escapeNumber($player->getGameID()) . ' GROUP BY message_type_id');
663
664
		if ($db->getNumRows()) {
665
			$messages = array();
666
			while ($db->nextRecord()) {
667
				$messages[$db->getInt('message_type_id')] = $db->getInt('COUNT(*)');
668
			}
669
670
			$container = create_container('skeleton.php', 'message_view.php');
671
672
			if (isset($messages[MSG_GLOBAL])) {
673
				$container['folder_id'] = MSG_GLOBAL;
674
				$template->assign('MessageGlobalLink', SmrSession::getNewHREF($container));
675
				$template->assign('MessageGlobalNum', $messages[MSG_GLOBAL]);
676
			}
677
678
			if (isset($messages[MSG_PLAYER])) {
679
				$container['folder_id'] = MSG_PLAYER;
680
				$template->assign('MessagePersonalLink', SmrSession::getNewHREF($container));
681
				$template->assign('MessagePersonalNum', $messages[MSG_PLAYER]);
682
			}
683
684
			if (isset($messages[MSG_SCOUT])) {
685
				$container['folder_id'] = MSG_SCOUT;
686
				$template->assign('MessageScoutLink', SmrSession::getNewHREF($container));
687
				$template->assign('MessageScoutNum', $messages[MSG_SCOUT]);
688
			}
689
690
			if (isset($messages[MSG_POLITICAL])) {
691
				$container['folder_id'] = MSG_POLITICAL;
692
				$template->assign('MessagePoliticalLink', SmrSession::getNewHREF($container));
693
				$template->assign('MessagePoliticalNum', $messages[MSG_POLITICAL]);
694
			}
695
696
			if (isset($messages[MSG_ALLIANCE])) {
697
				$container['folder_id'] = MSG_ALLIANCE;
698
				$template->assign('MessageAllianceLink', SmrSession::getNewHREF($container));
699
				$template->assign('MessageAllianceNum', $messages[MSG_ALLIANCE]);
700
			}
701
702
			if (isset($messages[MSG_ADMIN])) {
703
				$container['folder_id'] = MSG_ADMIN;
704
				$template->assign('MessageAdminLink', SmrSession::getNewHREF($container));
705
				$template->assign('MessageAdminNum', $messages[MSG_ADMIN]);
706
			}
707
708
			if (isset($messages[MSG_CASINO])) {
709
				$container['folder_id'] = MSG_CASINO;
710
				$template->assign('MessageCasinoLink', SmrSession::getNewHREF($container));
711
				$template->assign('MessageCasinoNum', $messages[MSG_CASINO]);
712
			}
713
714
			if (isset($messages[MSG_PLANET])) {
715
				$container = create_container('planet_msg_processing.php');
716
				$template->assign('MessagePlanetLink', SmrSession::getNewHREF($container));
717
				$template->assign('MessagePlanetNum', $messages[MSG_PLANET]);
718
			}
719
		}
720
721
		$container = create_container('skeleton.php', 'trader_search_result.php');
722
		$container['player_id'] = $player->getPlayerID();
723
		$template->assign('PlayerNameLink', SmrSession::getNewHREF($container));
724
725
		if (is_array(Globals::getHiddenPlayers()) && in_array($player->getAccountID(), Globals::getHiddenPlayers())) {
726
			$template->assign('PlayerInvisible', true);
727
		}
728
729
		// ******* Hardware *******
730
		$container = create_container('skeleton.php', 'configure_hardware.php');
731
732
		$template->assign('HardwareLink', SmrSession::getNewHREF($container));
733
734
		// ******* Forces *******
735
		$template->assign('ForceDropLink', SmrSession::getNewHREF(create_container('skeleton.php', 'forces_drop.php')));
736
737
		if ($ship->hasMines()) {
738
			$container = create_container('forces_drop_processing.php');
739
			$container['owner_id'] = $player->getAccountID();
740
			$container['drop_mines'] = 1;
741
			$container['referrer'] = $var['body'];
742
			$template->assign('DropMineLink', SmrSession::getNewHREF($container));
743
		}
744
		if ($ship->hasCDs()) {
745
			$container = create_container('forces_drop_processing.php');
746
			$container['owner_id'] = $player->getAccountID();
747
			$container['drop_combat_drones'] = 1;
748
			$container['referrer'] = $var['body'];
749
			$template->assign('DropCDLink', SmrSession::getNewHREF($container));
750
		}
751
752
		if ($ship->hasSDs()) {
753
			$container = create_container('forces_drop_processing.php');
754
			$container['owner_id'] = $player->getAccountID();
755
			$container['drop_scout_drones'] = 1;
756
			$container['referrer'] = $var['body'];
757
			$template->assign('DropSDLink', SmrSession::getNewHREF($container));
758
		}
759
760
		$template->assign('CargoJettisonLink', SmrSession::getNewHREF(create_container('skeleton.php', 'cargo_dump.php')));
761
762
		$template->assign('WeaponReorderLink', SmrSession::getNewHREF(create_container('skeleton.php', 'weapon_reorder.php')));
763
764
	}
765
766
	// ------- VOTING --------
767
	$voteSites = array();
768
	foreach (VoteSite::getAllSites() as $site) {
769
		$voteSites[] = array(
770
			'img' => $site->getLinkImg($account->getAccountID(), SmrSession::getGameID()),
771
			'url' => $site->getLinkUrl($account->getAccountID(), SmrSession::getGameID()),
772
			'sn' => $site->getSN($account->getAccountID(), SmrSession::getGameID()),
773
		);
774
	}
775
	$template->assign('VoteSites', $voteSites);
776
777
	// Determine the minimum time until the next vote across all sites
778
	$minVoteWait = VoteSite::getMinTimeUntilFreeTurns($account->getAccountID());
779
	if ($minVoteWait <= 0) {
780
		$template->assign('TimeToNextVote', 'now');
781
	} else {
782
		$template->assign('TimeToNextVote', 'in ' . format_time($minVoteWait, true));
783
	}
784
785
	// ------- VERSION --------
786
	$db->query('SELECT * FROM version ORDER BY went_live DESC LIMIT 1');
787
	$version = '';
788
	if ($db->nextRecord()) {
789
		$container = create_container('skeleton.php', 'changelog_view.php');
790
		$version = create_link($container, 'v' . $db->getField('major_version') . '.' . $db->getField('minor_version') . '.' . $db->getField('patch_level'));
791
	}
792
793
	$template->assign('Version', $version);
794
	$template->assign('CurrentYear', date('Y', TIME));
795
}
796
797
/**
798
 * Convert an integer number of seconds into a human-readable time.
799
 * Use short=true to use 1-letter units (e.g. "1h, 3m, and 20s").
800
 * If seconds is negative, will append "ago" to the result.
801
 */
802
function format_time($seconds, $short = false) {
803
	if ($seconds == 0) {
804
		return $short ? '0s' : '0 seconds';
805
	}
806
807
	if ($seconds < 0) {
808
		$past = true;
809
		$seconds = abs($seconds);
810
	} else {
811
		$past = false;
812
	}
813
814
	$minutes = 0;
815
	$hours = 0;
816
	$days = 0;
817
	$weeks = 0;
818
	if ($seconds >= 60) {
819
		$minutes = floor($seconds / 60);
820
		$seconds = $seconds % 60;
821
	}
822
	if ($minutes >= 60) {
823
		$hours = floor($minutes / 60);
824
		$minutes = $minutes % 60;
825
	}
826
	if ($hours >= 24) {
827
		$days = floor($hours / 24);
828
		$hours = $hours % 24;
829
	}
830
	if ($days >= 7) {
831
		$weeks = floor($days / 7);
832
		$days = $days % 7;
833
	}
834
	$times = [
835
		'week' => $weeks,
836
		'day' => $days,
837
		'hour' => $hours,
838
		'minute' => $minutes,
839
		'second' => $seconds,
840
	];
841
	$parts = [];
842
	foreach ($times as $unit => $amount) {
843
		if ($amount > 0) {
844
			if ($short) {
845
				$parts[] = $amount . $unit[0];
846
			} else {
847
				$parts[] = $amount . ' ' . pluralise($unit, $amount);
848
			}
849
		}
850
	}
851
852
	if (count($parts) == 1) {
853
		$result = $parts[0];
854
	} else {
855
		// e.g. 5h, 10m and 30s
856
		$result = join(', ', array_slice($parts, 0, -1)) . ' and ' . end($parts);
857
	}
858
859
	if ($past) {
860
		$result .= ' ago';
861
	}
862
	return $result;
863
}
864
865
function number_colour_format($number, $justSign = false) {
866
	$formatted = '<span';
867
	if ($number > 0) {
868
		$formatted .= ' class="green">+';
869
	} else if ($number < 0) {
870
		$formatted .= ' class="red">-';
871
	} else {
872
		$formatted .= '>';
873
	}
874
	if ($justSign === false) {
875
		$decimalPlaces = 0;
876
		if (($pos = strpos((string)$number, '.')) !== false) {
877
			$decimalPlaces = strlen(substr((string)$number, $pos + 1));
878
		}
879
		$formatted .= number_format(abs($number), $decimalPlaces);
880
	}
881
	$formatted .= '</span>';
882
	return $formatted;
883
}
884
885
886
/**
887
 * Randomly choose an array key weighted by the array values.
888
 * Probabilities are relative to the total weight. For example:
889
 *
890
 * array(
891
 *    'A' => 1, // 10% chance
892
 *    'B' => 3, // 30% chance
893
 *    'C' => 6, // 60% chance
894
 * );
895
 */
896
function getWeightedRandom($choices) {
897
	// Normalize the weights so that their sum is much larger than 1.
898
	$maxWeight = max($choices);
899
	foreach ($choices as $key => &$weight) {
900
		$weight = IRound($weight * 1000 / $maxWeight);
901
	} unset($weight);
902
903
	// Generate a random number that is lower than the sum of the weights.
904
	$rand = rand(1, array_sum($choices));
0 ignored issues
show
Bug introduced by
It seems like array_sum($choices) can also be of type double; however, parameter $max of rand() does only seem to accept integer, 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

904
	$rand = rand(1, /** @scrutinizer ignore-type */ array_sum($choices));
Loading history...
905
906
	// Subtract weights from the random number until it is negative,
907
	// then return the key associated with that weight.
908
	foreach ($choices as $key => $weight) {
909
		$rand -= $weight;
910
		if ($rand <= 0) {
911
			return $key;
912
		}
913
	}
914
}
915