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
Pull Request — master (#1031)
by Dan
05:27
created

resetContainer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 10
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A create_submit_link() 0 2 1
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 = Page::create('combat_log_viewer_verify.php');
19
	$container['log_id'] = $logID;
20
	return '<a href="' . $container->href() . '"><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 = Page::create('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 = Page::create('alliance_invite_accept_processing.php');
130
				$container['alliance_id'] = $alliance->getAllianceID();
131
				return '<div class="buttonA"><a class="buttonA" href="' . $container->href() . '">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 = Page::create('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 = $container->href();
204
			// json_encode the HREF as a safety precaution
205
			$template->addJavascriptForAjax('EVAL', 'location.href = ' . json_encode($errorHREF));
206
		}
207
	}
208
	$container->go();
209
}
210
211
function create_link(Page|string $container, $text, $class = null) {
212
	return '<a' . ($class == null ? '' : ' class="' . $class . '"') . ' href="' . (is_string($container) ? $container : $container->href()) . '">' . $text . '</a>';
213
}
214
215
function create_submit_link(Page $container, $text) {
216
	return '<a href="' . $container->href() . '" class="submitStyle">' . $text . '</a>';
217
}
218
219
function get_colored_text_range($value, $maxValue, $text = null, $minValue = 0, $type = 'Game', $return_type = 'Normal') {
220
	if ($text == null) {
221
		$text = number_format($value);
222
	}
223
	if ($maxValue - $minValue == 0) {
224
		return $text;
225
	} else {
226
		$normalisedValue = IRound(510 * max(0, min($maxValue, $value) - $minValue) / ($maxValue - $minValue)) - 255;
227
	}
228
	if ($type == 'Game') {
229
		if ($normalisedValue < 0) {
230
			$r_component = 'ff';
231
			$g_component = dechex(255 + $normalisedValue);
232
			if (strlen($g_component) == 1) {
233
				$g_component = '0' . $g_component;
234
			}
235
		} else if ($normalisedValue > 0) {
236
			$g_component = 'ff';
237
			$r_component = dechex(255 - $normalisedValue);
238
			if (strlen($r_component) == 1) {
239
				$r_component = '0' . $r_component;
240
			}
241
		} else {
242
			$r_component = 'ff';
243
			$g_component = 'ff';
244
		}
245
		$colour = $r_component . $g_component . '00';
246
		if ($return_type == 'Colour') {
247
			return $colour;
248
		}
249
		return '<span style="color:#' . $colour . '">' . $text . '</span>';
250
	} elseif ($type == 'IRC') {
251
		//IRC color codes
252
		if ($normalisedValue == 255) {
253
			$colour = '[k03]';
254
		} elseif ($normalisedValue == -255) {
255
			$colour = '[k04]';
256
		} else {
257
			$colour = '[k08]';
258
		}
259
		if ($return_type == 'Colour') {
260
			return $colour;
261
		}
262
		return $colour . $text;
263
	}
264
}
265
266
function get_colored_text($value, $text = null, $type = 'Game', $return_type = 'Normal') {
267
	return get_colored_text_range($value, 300, $text, -300, $type, $return_type);
268
}
269
270
function word_filter($string) {
271
	static $words;
272
273
	if (!is_array($words)) {
274
		$db = MySqlDatabase::getInstance();
275
		$db->query('SELECT word_value, word_replacement FROM word_filter');
276
		$words = array();
277
		while ($db->nextRecord()) {
278
			$row = $db->getRow();
279
			$words[] = array('word_value' => '/' . str_replace('/', '\/', $row['word_value']) . '/i', 'word_replacement'=> $row['word_replacement']);
280
		}
281
	}
282
283
	foreach ($words as $word) {
284
		$string = preg_replace($word['word_value'], $word['word_replacement'], $string);
285
	}
286
287
	return $string;
288
}
289
290
// choose correct pluralization based on amount
291
function pluralise($word, $count = 0) {
292
	if ($count == 1) {
293
		return $word;
294
	}
295
	if (strtolower($word) == 'is') {
296
		return 'are';
297
	}
298
	return $word . 's';
299
}
300
301
/**
302
 * This function is a hack around the old style http forward mechanism.
303
 * It is also responsible for setting most of the global variables
304
 * (see loader.php for the initialization of the globals).
305
 */
306
function do_voodoo() {
307
	global $lock, $var, $player, $ship, $sector, $account, $db, $template;
308
309
	if (!defined('AJAX_CONTAINER')) {
310
		define('AJAX_CONTAINER', isset($var['AJAX']) && $var['AJAX'] === true);
311
	}
312
	if (!AJAX_CONTAINER && USING_AJAX && SmrSession::hasChangedSN()) {
313
		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...
314
	}
315
//	ob_clean();
316
317
	// create account object
318
	$account = SmrSession::getAccount();
319
320
	if (!defined('DATE_DATE_SHORT')) {
321
		define('DATE_DATE_SHORT', $account->getShortDateFormat());
322
	}
323
	if (!defined('DATE_TIME_SHORT')) {
324
		define('DATE_TIME_SHORT', $account->getShortTimeFormat());
325
	}
326
	if (!defined('DATE_FULL_SHORT')) {
327
		define('DATE_FULL_SHORT', DATE_DATE_SHORT . ' ' . DATE_TIME_SHORT);
328
	}
329
	if (!defined('DATE_FULL_SHORT_SPLIT')) {
330
		define('DATE_FULL_SHORT_SPLIT', DATE_DATE_SHORT . '\<b\r /\>' . DATE_TIME_SHORT);
331
	}
332
333
	// initialize objects we usually need, like player, ship
334
	if (SmrSession::hasGame()) {
335
		if (SmrGame::getGame(SmrSession::getGameID())->hasEnded()) {
336
			Page::create('game_leave_processing.php', 'game_play.php', array('errorMsg' => 'The game has ended.'))->go();
337
		}
338
		// We need to acquire locks BEFORE getting the player information
339
		// Otherwise we could be working on stale information
340
		$db->query('SELECT sector_id FROM player WHERE account_id=' . $db->escapeNumber($account->getAccountID()) . ' AND game_id=' . $db->escapeNumber(SmrSession::getGameID()) . ' LIMIT 1');
341
		$db->requireRecord();
342
		$sector_id = $db->getInt('sector_id');
343
344
		global $locksFailed;
345
		if (!USING_AJAX //AJAX should never do anything that requires a lock.
346
//			&& !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.
347
			) {
348
			if (!$lock && !isset($locksFailed[$sector_id])) {
349
				if (!acquire_lock($sector_id)) {
350
					create_error('Failed to acquire sector lock');
351
				}
352
				//Refetch var info in case it changed between grabbing lock.
353
				SmrSession::fetchVarInfo();
354
				if (!($var = SmrSession::retrieveVar())) {
355
					if (ENABLE_DEBUG) {
356
						$db->query('INSERT INTO debug VALUES (\'SPAM\',' . $db->escapeNumber($account->getAccountID()) . ',0,0)');
357
					}
358
					create_error('Please do not spam click!');
359
				}
360
			}
361
		}
362
363
		// Now that they've acquire a lock we can move on
364
		$player = SmrPlayer::getPlayer($account->getAccountID(), SmrSession::getGameID());
365
366
		if ($player->isDead() && $var['url'] != 'death_processing.php' && !isset($var['override_death'])) {
367
			Page::create('death_processing.php')->go();
368
		}
369
370
		$ship = $player->getShip();
371
		$sector = $player->getSector();
372
373
		// update turns on that player
374
		$player->updateTurns();
375
376
		if (!$player->isDead() && $player->getNewbieTurns() <= NEWBIE_TURNS_WARNING_LIMIT &&
377
			$player->getNewbieWarning() &&
378
			$var['url'] != 'newbie_warning_processing.php')
379
			Page::create('newbie_warning_processing.php')->go();
380
	}
381
382
	// Initialize the template
383
	$template = new Template();
384
385
	if ($var['url'] != 'skeleton.php') {
386
		require(get_file_loc($var['url']));
387
	}
388
	if ($var['body']) {
389
		if ($var['body'] == 'error.php') { // infinite includes for error pages
390
			require(get_file_loc($var['body']));
391
		} else {
392
			require_once(get_file_loc($var['body']));
393
		}
394
	}
395
396
	if (SmrSession::hasGame()) {
397
		$template->assign('UnderAttack', $player->removeUnderAttack());
398
	}
399
400
	if ($lock) { //Only save if we have the lock.
401
		SmrSector::saveSectors();
402
		SmrShip::saveShips();
403
		SmrPlayer::savePlayers();
404
		SmrForce::saveForces();
405
		SmrPort::savePorts();
406
		SmrPlanet::savePlanets();
407
		if (class_exists('WeightedRandom', false)) {
408
			WeightedRandom::saveWeightedRandoms();
409
		}
410
		//Update session here to make sure current page $var is up to date before releasing lock.
411
		SmrSession::update();
412
		release_lock();
413
	}
414
415
	//Nothing below this point should require the lock.
416
417
	$template->assign('TemplateBody', $var['body']);
418
	if (SmrSession::hasGame()) {
419
		$template->assign('ThisSector', $sector);
420
		$template->assign('ThisPlayer', $player);
421
		$template->assign('ThisShip', $ship);
422
	}
423
	$template->assign('ThisAccount', $account);
424
	if ($account->getCssLink() != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $account->getCssLink() of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
425
		$template->assign('ExtraCSSLink', $account->getCssLink());
426
	}
427
	doSkeletonAssigns($template, $player, $ship, $sector, $db, $account, $var);
428
429
	// Set ajax refresh time
430
	$ajaxRefresh = $var['AllowAjax'] ?? true; // hack for bar_gambling_processing.php
431
	if (!$account->isUseAJAX()) {
432
		$ajaxRefresh = false;
433
	}
434
	if ($ajaxRefresh) {
435
		// If we can refresh, specify the refresh interval in millisecs
436
		if (SmrSession::hasGame() && $player->canFight()) {
437
			$ajaxRefresh = AJAX_UNPROTECTED_REFRESH_TIME;
438
		} else {
439
			$ajaxRefresh = AJAX_DEFAULT_REFRESH_TIME;
440
		}
441
	}
442
	$template->assign('AJAX_ENABLE_REFRESH', $ajaxRefresh);
443
444
	$template->display($var['url'], USING_AJAX || AJAX_CONTAINER);
445
446
	SmrSession::update();
447
448
	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...
449
}
450
451
//xdebug_dump_function_profile(2);
452
453
// This is hackish, but without row level locking it's the best we can do
454
function acquire_lock($sector) {
455
	global $db, $lock, $locksFailed;
456
457
	if ($lock) {
458
		return true;
459
	}
460
461
	// Insert ourselves into the queue.
462
	$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(SmrSession::getTime()) . ')');
463
	$lock = $db->getInsertID();
464
465
	for ($i = 0; $i < 250; ++$i) {
466
		if (time() - SmrSession::getTime() >= LOCK_DURATION - LOCK_BUFFER) {
467
			break;
468
		}
469
		// If there is someone else before us in the queue we sleep for a while
470
		$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(SmrSession::getTime() - LOCK_DURATION));
471
		$locksInQueue = -1;
0 ignored issues
show
Unused Code introduced by
The assignment to $locksInQueue is dead and can be removed.
Loading history...
472
		if ($db->nextRecord() && ($locksInQueue = $db->getInt('COUNT(*)')) > 0) {
473
			//usleep(100000 + mt_rand(0,50000));
474
475
			// We can only have one lock in the queue, anything more means someone is screwing around
476
			$db->query('SELECT COUNT(*) FROM locks_queue WHERE account_id=' . $db->escapeNumber(SmrSession::getAccountID()) . ' AND sector_id=' . $db->escapeNumber($sector) . ' AND timestamp > ' . $db->escapeNumber(SmrSession::getTime() - LOCK_DURATION));
477
			if ($db->nextRecord() && $db->getInt('COUNT(*)') > 1) {
478
				release_lock();
479
				$locksFailed[$sector] = true;
480
				create_error('Multiple actions cannot be performed at the same time!');
481
			}
482
483
			usleep(25000 * $locksInQueue);
484
			continue;
485
		} else {
486
			return true;
487
		}
488
	}
489
490
	release_lock();
491
	$locksFailed[$sector] = true;
492
	return false;
493
}
494
495
function release_lock() {
496
	global $db, $lock;
497
	if ($lock) {
498
		$db->query('DELETE from locks_queue WHERE lock_id=' . $db->escapeNumber($lock) . ' OR timestamp<' . $db->escapeNumber(SmrSession::getTime() - LOCK_DURATION));
499
	}
500
501
	$lock = false;
502
}
503
504
function doTickerAssigns($template, $player, $db) {
505
	//any ticker news?
506
	if ($player->hasTickers()) {
507
		$ticker = array();
508
		$max = SmrSession::getTime() - 60;
509
		if ($player->hasTicker('NEWS')) {
510
			//get recent news (5 mins)
511
			$db->query('SELECT time,news_message FROM news WHERE game_id = ' . $db->escapeNumber($player->getGameID()) . ' AND time >= ' . $max . ' ORDER BY time DESC LIMIT 4');
512
			while ($db->nextRecord()) {
513
				$ticker[] = array('Time' => date(DATE_FULL_SHORT, $db->getInt('time')),
514
								'Message'=>$db->getField('news_message'));
515
			}
516
		}
517
		if ($player->hasTicker('SCOUT')) {
518
			$db->query('SELECT message_text,send_time FROM message
519
						WHERE account_id=' . $db->escapeNumber($player->getAccountID()) . '
520
						AND game_id=' . $db->escapeNumber($player->getGameID()) . '
521
						AND message_type_id=' . $db->escapeNumber(MSG_SCOUT) . '
522
						AND send_time>=' . $db->escapeNumber($max) . '
523
						AND sender_id NOT IN (SELECT account_id FROM player_has_ticker WHERE type='.$db->escapeString('BLOCK') . ' AND expires > ' . $db->escapeNumber(SmrSession::getTime()) . ' AND game_id = ' . $db->escapeNumber($player->getGameID()) . ') AND receiver_delete = \'FALSE\'
524
						ORDER BY send_time DESC
525
						LIMIT 4');
526
			while ($db->nextRecord()) {
527
				$ticker[] = array('Time' => date(DATE_FULL_SHORT, $db->getInt('send_time')),
528
								'Message'=>$db->getField('message_text'));
529
			}
530
		}
531
		$template->assign('Ticker', $ticker);
532
	}
533
}
534
535
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

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

860
	$rand = rand(1, /** @scrutinizer ignore-type */ array_sum($choices));
Loading history...
861
862
	// Subtract weights from the random number until it is negative,
863
	// then return the key associated with that weight.
864
	foreach ($choices as $key => $weight) {
865
		$rand -= $weight;
866
		if ($rand <= 0) {
867
			return $key;
868
		}
869
	}
870
	throw new Exception('Internal error computing weights');
871
}
872