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

Failed Conditions
Push — main ( d9cfb9...10f5c7 )
by Dan
32s queued 21s
created

src/bootstrap.php (1 issue)

Labels
Severity
1
<?php declare(strict_types=1);
2
3
use Smr\Container\DiContainer;
4
use Smr\Exceptions\UserError;
5
use Smr\SectorLock;
6
use Smr\Session;
7
8
function logException(Throwable $e): void {
9
	$message = '';
10
	$delim = "\n\n-----------\n\n";
11
12
	$message .= 'Error Message: ' . $e . $delim;
13
14
	if (DiContainer::initialized(Session::class)) {
15
		$session = Session::getInstance();
16
17
		if ($session->hasAccount()) {
18
			$account = $session->getAccount();
19
			$message .= 'Login: ' . $account->getLogin() . "\n" .
20
				'E-Mail: ' . $account->getEmail() . "\n" .
21
				'Account ID: ' . $account->getAccountID();
22
			if ($session->hasGame()) {
23
				$message .= "\n" .
24
					'Game ID: ' . $session->getGameID() . "\n" .
25
					'Sector ID: ' . $session->getPlayer()->getSectorID();
26
			}
27
			$message .= $delim;
28
		}
29
30
		$message .= 'ajax: ' . var_export($session->ajax, true) . "\n";
31
32
		$var = $session->hasCurrentVar() ? $session->getCurrentVar() : null;
33
		$message .= '$var: ' . print_r($var, true) . $delim;
34
	}
35
36
	// Don't display passwords input by users in the log message!
37
	if (isset($_REQUEST['password'])) {
38
		$_REQUEST['password'] = '*****';
39
	}
40
	$message .= '$_REQUEST: ' . var_export($_REQUEST, true);
41
	$message .= $delim;
42
43
	$message .=
44
		'User IP: ' . getIpAddress() . "\n" .
45
		'User Agent: ' . ($_SERVER['HTTP_USER_AGENT'] ?? 'undefined') . "\n" .
46
		'URL: ' . (defined('URL') ? URL : 'undefined');
47
48
	// Try to release lock so they can carry on normally
49
	if (DiContainer::initialized(SectorLock::class)) {
50
		try {
51
			SectorLock::getInstance()->release();
52
		} catch (Throwable $ee) {
53
			$message .= $delim .
54
					'Releasing Lock Failed' . "\n" .
55
					'Message: ' . $ee . "\n";
56
		}
57
	}
58
59
	if (defined('SCRIPT_ID')) {
60
		$message = 'Script: ' . SCRIPT_ID . $delim . $message . "\n\n";
61
	}
62
63
	// Unconditionally send error message to the log
64
	error_log($message);
65
66
	if (ENABLE_DEBUG) {
67
		// Display error message on the page (redundant with error_log for CLI)
68
		if (PHP_SAPI !== 'cli') {
69
			echo '<pre>' . $message . '</pre>';
70
		}
71
		// Skip remaining log methods (too disruptive during development)
72
		return;
73
	}
74
75
	// Send error message to the in-game auto bugs mailbox
76
	if (isset($session) && $session->hasGame()) {
77
		$session->getPlayer()->sendMessageToBox(BOX_BUGS_AUTO, $message);
78
	} elseif (isset($session) && $session->hasAccount()) {
79
		// Will be logged without a game_id
80
		$session->getAccount()->sendMessageToBox(BOX_BUGS_AUTO, $message);
81
	} else {
82
		// Will be logged without a game_id or sender_id
83
		SmrAccount::doMessageSendingToBox(0, BOX_BUGS_AUTO, $message, 0);
84
	}
85
86
	// Send error message to e-mail so that we have a permanent record
87
	if (!empty(BUG_REPORT_TO_ADDRESSES)) {
88
		$mail = setupMailer();
89
		$mail->Subject = (defined('PAGE_PREFIX') ? PAGE_PREFIX : '??? ') .
90
		                 'Automatic Bug Report';
91
		$mail->setFrom('[email protected]');
92
		$mail->Body = $message;
93
		foreach (BUG_REPORT_TO_ADDRESSES as $toAddress) {
94
			$mail->addAddress($toAddress);
95
		}
96
		$mail->send();
97
	}
98
}
99
100
/**
101
 * Handles all user-facing exceptions.
102
 *
103
 * If the error is fatal, the exception is logged and the player is redirected
104
 * to an appropriate error page.
105
 *
106
 * If the error is just informational (e.g. the user input an invalid value),
107
 * then the message is displayed on the page without being logged.
108
 */
109
function handleException(Throwable $e): void {
110
	// The real error message may display sensitive information, so we
111
	// need to catch any exceptions that are thrown while logging the error.
112
	try {
113
		if ($e instanceof UserError) {
114
			handleUserError($e->getMessage());
115
		}
116
		logException($e);
117
		$errorType = 'Unexpected Error!';
118
	} catch (Throwable $e2) {
119
		error_log('Original exception: ' . $e);
120
		error_log('Exception during logException: ' . $e2);
121
		$errorType = 'This error cannot be automatically reported. Please notify an admin!';
122
	}
123
124
	// If this is an ajax update, we don't really have a way to redirect
125
	// to an error page at this time.
126
	if (!ENABLE_DEBUG) {
127
		header('location: /error.php?msg=' . urlencode($errorType));
128
	}
129
}
130
131
/**
132
 * Can be used to convert any type of notice into an exception.
133
 */
134
function exception_error_handler(int $errno, string $errstr, string $errfile, int $errline): bool {
135
	if (!(error_reporting() & $errno)) {
136
		return false; // error is suppressed
137
	}
138
	throw new ErrorException($errstr, $errno, E_ERROR, $errfile, $errline);
139
}
140
141
function setupMailer(): \PHPMailer\PHPMailer\PHPMailer {
142
	$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
143
	if (!empty(SMTP_HOSTNAME)) {
144
		$mail->isSMTP();
145
		$mail->Host = SMTP_HOSTNAME;
146
	}
147
	return $mail;
148
}
149
150
function getIpAddress(): string {
151
	foreach (['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR'] as $key) {
152
		if (array_key_exists($key, $_SERVER) === true) {
153
			foreach (explode(',', $_SERVER[$key]) as $ip) {
154
				if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
155
					return $ip;
156
				}
157
			}
158
		}
159
	}
160
	return 'unknown';
161
}
162
163
/**
164
 * Wrapper around the floor() builtin for returning an integer type.
165
 */
166
function IFloor(float $val): int {
167
	return (int)floor($val);
168
}
169
170
/**
171
 * Wrapper around the ceil() builtin for returning an integer type.
172
 */
173
function ICeil(float $val): int {
174
	return (int)ceil($val);
175
}
176
177
/**
178
 * Wrapper around the round() builtin for returning an integer type.
179
 */
180
function IRound(float $val): int {
181
	return (int)round($val);
182
}
183
184
/**
185
 * Convert a numeric string to an int with input validation.
186
 */
187
function str2int(string $val): int {
188
	$result = filter_var($val, FILTER_VALIDATE_INT);
189
	if ($result === false) {
190
		throw new Exception('Input value is not an integer: ' . $val);
191
	}
192
	return $result;
193
}
194
195
/**
196
 * Generate a cryptographically strong random hexadecimal string.
197
 * The requested length must be a multiple of 2.
198
 */
199
function random_string(int $length): string {
200
	if ($length % 2 != 0) {
201
		throw new Exception('Length must be a multiple of 2!');
202
	}
203
	return bin2hex(random_bytes($length / 2));
204
}
205
206
/**
207
 * Generate a (non-cryptographic) random alphabetic string.
208
 * This is slower for longer strings.
209
 */
210
function random_alphabetic_string(int $length): string {
211
	$result = '';
212
	for ($i = 0; $i < $length; ++$i) {
213
		$result .= chr(rand(ord('a'), ord('z')));
214
	}
215
	return $result;
216
}
217
218
/**
219
 * Return the value of a random key from an array.
220
 *
221
 * @template T
222
 * @param array<T> $arr
223
 * @return T
224
 */
225
function array_rand_value(array $arr): mixed {
226
	if (empty($arr)) {
227
		throw new Exception('Cannot pick random value from empty array!');
228
	}
229
	return $arr[array_rand($arr)];
230
}
231
232
// Defines all constants
233
require_once('config.php');
234
235
// Set up vendor and class autoloaders
236
require_once(ROOT . 'vendor/autoload.php');
237
require_once(LIB . 'autoload.inc.php');
238
spl_autoload_register(get_class_loc(...));
0 ignored issues
show
A parse error occurred: Syntax error, unexpected ')' on line 238 at column 39
Loading history...
239
240
// Load common functions
241
require_once(LIB . 'Default/smr.inc.php');
242
243
// Set up dependency injection container
244
DiContainer::initialize(getenv('DISABLE_PHPDI_COMPILATION') !== 'true');
245