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 (#871)
by Dan
03:40
created

SmrGame::getTotalPlayers()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php declare(strict_types=1);
2
3
// Exception thrown when a game cannot be found in the database
4
class GameNotFoundException extends Exception {}
5
6
class SmrGame {
7
	protected static $CACHE_GAMES = array();
8
9
	protected SmrMySqlDatabase $db;
10
11
	protected int $gameID;
12
	protected string $name;
13
	protected string $description;
14
	protected int $joinTime;
15
	protected int $startTime;
16
	protected int $endTime;
17
	protected int $maxPlayers;
18
	protected int $maxTurns;
19
	protected int $startTurnHours;
20
	protected int $gameTypeID;
21
	protected int $creditsNeeded;
22
	protected float $gameSpeed;
23
	protected bool $enabled;
24
	protected bool $ignoreStats;
25
	protected int $allianceMaxPlayers;
26
	protected int $allianceMaxVets;
27
	protected int $startingCredits;
28
29
	protected int $totalPlayers;
30
	protected array $playableRaceIDs;
31
32
	protected bool $hasChanged = false;
33
	protected bool $isNew = false;
34
35
	const GAME_TYPE_DEFAULT = 0;
36
	const GAME_TYPE_HUNTER_WARS = 3;
37
	const GAME_TYPE_SEMI_WARS = 4;
38
	const GAME_TYPE_DRAFT = 5;
39
	const GAME_TYPE_FFA = 6;
40
	const GAME_TYPE_NEWBIE = 7;
41
	const GAME_TYPES = [
42
		self::GAME_TYPE_DEFAULT => 'Default',
43
		self::GAME_TYPE_HUNTER_WARS => 'Hunter Wars',
44
		self::GAME_TYPE_SEMI_WARS => 'Semi Wars',
45
		self::GAME_TYPE_DRAFT => 'Draft',
46
		self::GAME_TYPE_FFA => 'FFA',
47
		self::GAME_TYPE_NEWBIE => 'Newbie',
48
	];
49
50
	public static function getGame(int $gameID, bool $forceUpdate = false) : SmrGame {
51
		if ($forceUpdate || !isset(self::$CACHE_GAMES[$gameID])) {
52
			$g = new SmrGame($gameID);
53
			self::$CACHE_GAMES[$gameID] = $g;
54
		}
55
		return self::$CACHE_GAMES[$gameID];
56
	}
57
58
	public static function saveGames() : void {
59
		foreach (self::$CACHE_GAMES as $game) {
60
			$game->save();
61
		}
62
	}
63
64
	public static function createGame(int $gameID) : SmrGame {
65
		if (!isset(self::$CACHE_GAMES[$gameID])) {
66
			$g = new SmrGame($gameID, true);
67
			self::$CACHE_GAMES[$gameID] = $g;
68
		}
69
		return self::$CACHE_GAMES[$gameID];
70
	}
71
72
	protected function __construct(int $gameID, bool $create = false) {
73
		$this->db = new SmrMySqlDatabase();
74
75
		$this->db->query('SELECT * FROM game WHERE game_id = ' . $this->db->escapeNumber($gameID) . ' LIMIT 1');
76
		if ($this->db->nextRecord()) {
77
			$this->gameID = $this->db->getInt('game_id');
78
			$this->name = $this->db->getField('game_name');
79
			$this->description = $this->db->getField('game_description');
80
			$this->joinTime = $this->db->getInt('join_time');
81
			$this->startTime = $this->db->getInt('start_time');
82
			$this->endTime = $this->db->getInt('end_time');
83
			$this->maxPlayers = $this->db->getInt('max_players');
84
			$this->maxTurns = $this->db->getInt('max_turns');
85
			$this->startTurnHours = $this->db->getInt('start_turns');
86
			$this->gameTypeID = $this->db->getInt('game_type');
87
			$this->creditsNeeded = $this->db->getInt('credits_needed');
88
			$this->gameSpeed = $this->db->getFloat('game_speed');
89
			$this->enabled = $this->db->getBoolean('enabled');
90
			$this->ignoreStats = $this->db->getBoolean('ignore_stats');
91
			$this->allianceMaxPlayers = $this->db->getInt('alliance_max_players');
92
			$this->allianceMaxVets = $this->db->getInt('alliance_max_vets');
93
			$this->startingCredits = $this->db->getInt('starting_credits');
94
		} elseif ($create === true) {
95
			$this->gameID = $gameID;
96
			$this->isNew = true;
97
			return;
98
		} else {
99
			throw new GameNotFoundException('No such game: ' . $gameID);
100
		}
101
	}
102
103
	public function save() : void {
104
		if ($this->isNew) {
105
			$this->db->query('INSERT INTO game (game_id,game_name,game_description,join_time,start_time,end_time,max_players,max_turns,start_turns,game_type,credits_needed,game_speed,enabled,ignore_stats,alliance_max_players,alliance_max_vets,starting_credits)
106
									VALUES
107
									(' . $this->db->escapeNumber($this->getGameID()) .
108
										',' . $this->db->escapeString($this->getName()) .
109
										',' . $this->db->escapeString($this->getDescription()) .
110
										',' . $this->db->escapeNumber($this->getJoinTime()) .
111
										',' . $this->db->escapeNumber($this->getStartTime()) .
112
										',' . $this->db->escapeNumber($this->getEndTime()) .
113
										',' . $this->db->escapeNumber($this->getMaxPlayers()) .
114
										',' . $this->db->escapeNumber($this->getMaxTurns()) .
115
										',' . $this->db->escapeNumber($this->getStartTurnHours()) .
116
										',' . $this->db->escapeNumber($this->gameTypeID) .
117
										',' . $this->db->escapeNumber($this->getCreditsNeeded()) .
118
										',' . $this->db->escapeNumber($this->getGameSpeed()) .
119
										',' . $this->db->escapeBoolean($this->isEnabled()) .
120
										',' . $this->db->escapeBoolean($this->isIgnoreStats()) .
121
										',' . $this->db->escapeNumber($this->getAllianceMaxPlayers()) .
122
										',' . $this->db->escapeNumber($this->getAllianceMaxVets()) .
123
										',' . $this->db->escapeNumber($this->getStartingCredits()) . ')');
124
		} elseif ($this->hasChanged) {
125
			$this->db->query('UPDATE game SET game_name = ' . $this->db->escapeString($this->getName()) .
126
										', game_description = ' . $this->db->escapeString($this->getDescription()) .
127
										', join_time = ' . $this->db->escapeNumber($this->getJoinTime()) .
128
										', start_time = ' . $this->db->escapeNumber($this->getStartTime()) .
129
										', end_time = ' . $this->db->escapeNumber($this->getEndTime()) .
130
										', max_players = ' . $this->db->escapeNumber($this->getMaxPlayers()) .
131
										', max_turns = ' . $this->db->escapeNumber($this->getMaxTurns()) .
132
										', start_turns = ' . $this->db->escapeNumber($this->getStartTurnHours()) .
133
										', game_type = ' . $this->db->escapeNumber($this->gameTypeID) .
134
										', credits_needed = ' . $this->db->escapeNumber($this->getCreditsNeeded()) .
135
										', game_speed = ' . $this->db->escapeNumber($this->getGameSpeed()) .
136
										', enabled = ' . $this->db->escapeBoolean($this->isEnabled()) .
137
										', ignore_stats = ' . $this->db->escapeBoolean($this->isIgnoreStats()) .
138
										', alliance_max_players = ' . $this->db->escapeNumber($this->getAllianceMaxPlayers()) .
139
										', alliance_max_vets = ' . $this->db->escapeNumber($this->getAllianceMaxVets()) .
140
										', starting_credits = ' . $this->db->escapeNumber($this->getStartingCredits()) .
141
									' WHERE game_id = ' . $this->db->escapeNumber($this->getGameID()) . ' LIMIT 1');
142
		}
143
		$this->isNew = false;
144
		$this->hasChanged = false;
145
	}
146
147
	public function getGameID() : int {
148
		return $this->gameID;
149
	}
150
151
	public function getName() : string {
152
		return $this->name;
153
	}
154
155
	public function setName(string $name) : void {
156
		if (!$this->isNew && $this->name === $name) {
157
			return;
158
		}
159
		$this->name = $name;
160
		$this->hasChanged = true;
161
	}
162
163
	public function getDescription() : string {
164
		return $this->description;
165
	}
166
167
	public function setDescription(string $description) : void {
168
		if (!$this->isNew && $this->description === $description) {
169
			return;
170
		}
171
		$this->description = $description;
172
		$this->hasChanged = true;
173
	}
174
175
	public function hasStarted() : bool {
176
		return TIME >= $this->getStartTime();
177
	}
178
179
	/**
180
	 * Returns the epoch time when the game starts,
181
	 * i.e. when players can move, turns are gained, etc.
182
	 */
183
	public function getStartTime() : int {
184
		return $this->startTime;
185
	}
186
187
	public function setStartTime(int $startTime) : void {
188
		if (!$this->isNew && $this->startTime === $startTime) {
189
			return;
190
		}
191
		$this->startTime = $startTime;
192
		$this->hasChanged = true;
193
	}
194
195
	/**
196
	 * Returns the epoch time when players can begin to join the game.
197
	 */
198
	public function getJoinTime() : int {
199
		return $this->joinTime;
200
	}
201
202
	public function setJoinTime(int $joinTime) : void {
203
		if (!$this->isNew && $this->joinTime === $joinTime) {
204
			return;
205
		}
206
		$this->joinTime = $joinTime;
207
		$this->hasChanged = true;
208
	}
209
210
	public function hasEnded() : bool {
211
		return $this->getEndTime() < TIME;
212
	}
213
214
	/**
215
	 * Returns the epoch time when the game ends.
216
	 */
217
	public function getEndTime() : int {
218
		return $this->endTime;
219
	}
220
221
	public function setEndTime(int $endTime) : void {
222
		if (!$this->isNew && $this->endTime === $endTime) {
223
			return;
224
		}
225
		$this->endTime = $endTime;
226
		$this->hasChanged = true;
227
	}
228
229
	public function getMaxPlayers() : int {
230
		return $this->maxPlayers;
231
	}
232
233
	public function setMaxPlayers(int $maxPlayers) : void {
234
		if (!$this->isNew && $this->maxPlayers === $maxPlayers) {
235
			return;
236
		}
237
		$this->maxPlayers = $maxPlayers;
238
		$this->hasChanged = true;
239
	}
240
241
	public function getMaxTurns() : int {
242
		return $this->maxTurns;
243
	}
244
245
	public function setMaxTurns(int $int) : void {
246
		if (!$this->isNew && $this->maxTurns === $int) {
247
			return;
248
		}
249
		$this->maxTurns = $int;
250
		$this->hasChanged = true;
251
	}
252
253
	public function getStartTurnHours() : int {
254
		return $this->startTurnHours;
255
	}
256
257
	public function setStartTurnHours(int $int) : void {
258
		if (!$this->isNew && $this->startTurnHours === $int) {
259
			return;
260
		}
261
		$this->startTurnHours = $int;
262
		$this->hasChanged = true;
263
	}
264
265
	public function getGameType() : string {
266
		return self::GAME_TYPES[$this->gameTypeID];
267
	}
268
269
	public function setGameTypeID(int $gameTypeID) : void {
270
		if (!$this->isNew && $this->gameTypeID === $gameTypeID) {
271
			return;
272
		}
273
		$this->gameTypeID = $gameTypeID;
274
		$this->hasChanged = true;
275
	}
276
277
	public function getCreditsNeeded() : int {
278
		return $this->creditsNeeded;
279
	}
280
281
	public function setCreditsNeeded(int $creditsNeeded) : void {
282
		if (!$this->isNew && $this->creditsNeeded === $creditsNeeded) {
283
			return;
284
		}
285
		$this->creditsNeeded = $creditsNeeded;
286
		$this->hasChanged = true;
287
	}
288
289
	public function getGameSpeed() : float {
290
		return $this->gameSpeed;
291
	}
292
293
	public function setGameSpeed(float $gameSpeed) : void {
294
		if (!$this->isNew && $this->gameSpeed === $gameSpeed) {
295
			return;
296
		}
297
		$this->gameSpeed = $gameSpeed;
298
		$this->hasChanged = true;
299
	}
300
301
	public function isEnabled() : bool {
302
		return $this->enabled;
303
	}
304
305
	public function setEnabled(bool $bool) : void {
306
		if (!$this->isNew && $this->enabled === $bool) {
307
			return;
308
		}
309
		$this->enabled = $bool;
310
		$this->hasChanged = true;
311
	}
312
313
	public function isIgnoreStats() : bool {
314
		return $this->ignoreStats;
315
	}
316
317
	public function setIgnoreStats(bool $bool) : void {
318
		if (!$this->isNew && $this->ignoreStats === $bool) {
319
			return;
320
		}
321
		$this->ignoreStats = $bool;
322
		$this->hasChanged = true;
323
	}
324
325
	public function getAllianceMaxPlayers() : int {
326
		return $this->allianceMaxPlayers;
327
	}
328
329
	public function setAllianceMaxPlayers(int $int) : void {
330
		if (!$this->isNew && $this->allianceMaxPlayers === $int) {
331
			return;
332
		}
333
		$this->allianceMaxPlayers = $int;
334
		$this->hasChanged = true;
335
	}
336
337
	public function getAllianceMaxVets() : int {
338
		return $this->allianceMaxVets;
339
	}
340
341
	public function setAllianceMaxVets(int $int) : void {
342
		if (!$this->isNew && $this->allianceMaxVets === $int) {
343
			return;
344
		}
345
		$this->allianceMaxVets = $int;
346
		$this->hasChanged = true;
347
	}
348
349
	public function getStartingCredits() : int {
350
		return $this->startingCredits;
351
	}
352
353
	public function setStartingCredits(int $int) : void {
354
		if (!$this->isNew && $this->startingCredits === $int) {
355
			return;
356
		}
357
		$this->startingCredits = $int;
358
		$this->hasChanged = true;
359
	}
360
361
	public function getTotalPlayers() : int {
362
		if (!isset($this->totalPlayers)) {
363
			$this->db->query('SELECT count(*) FROM player WHERE game_id = ' . $this->db->escapeNumber($this->getGameID()));
364
			$this->db->nextRecord();
365
			$this->totalPlayers = $this->db->getInt('count(*)');
366
		}
367
		return $this->totalPlayers;
368
	}
369
370
	public function getNumberOfGalaxies() : int {
371
		return count(SmrGalaxy::getGameGalaxies($this->getGameID()));
372
	}
373
374
	public function equals(SmrGame $otherGame) : bool {
375
		return $otherGame->getGameID() == $this->getGameID();
376
	}
377
378
	// Convenience function for printing the game name with id
379
	public function getDisplayName() : string {
380
		return $this->getName() . " (" . $this->getGameID() . ")";
381
	}
382
383
	/**
384
	 * Set the starting political relations between races.
385
	 */
386
	public function setStartingRelations(int $relations) : void {
387
		if ($relations < MIN_GLOBAL_RELATIONS || $relations > MAX_GLOBAL_RELATIONS) {
388
			throw new Exception('Invalid relations: ' . $relations);
389
		}
390
		foreach (Globals::getRaces() as $race1) {
391
			foreach (Globals::getRaces() as $race2) {
392
				if ($race1['Race ID'] == $race2['Race ID']) {
393
					// Max relations for a race with itself
394
					$amount = MAX_GLOBAL_RELATIONS;
395
				} elseif ($race1['Race ID'] == RACE_NEUTRAL || $race2['Race ID'] == RACE_NEUTRAL) {
396
					$amount = 0; //0 relations with neutral
397
				} else {
398
					$amount = $relations;
399
				}
400
				$this->db->query('REPLACE INTO race_has_relation (game_id, race_id_1, race_id_2, relation)
401
				                  VALUES (' . $this->db->escapeNumber($this->getGameID()) . ',' . $this->db->escapeNumber($race1['Race ID']) . ',' . $this->db->escapeNumber($race2['Race ID']) . ',' . $this->db->escapeNumber($amount) . ')');
402
			}
403
		}
404
	}
405
406
	/**
407
	 * Get the list of playable Race IDs based on which Racial HQ's
408
	 * are locations in this game.
409
	 */
410
	public function getPlayableRaceIDs() : array {
411
		if (!isset($this->playableRaceIDs)) {
412
			// Get a unique set of HQ's available in game
413
			$this->db->query('SELECT DISTINCT location_type_id
414
				FROM location
415
				WHERE location_type_id > ' . $this->db->escapeNumber(UNDERGROUND) . '
416
					AND location_type_id < ' . $this->db->escapeNumber(FED) . '
417
					AND game_id = ' . $this->db->escapeNumber($this->getGameID()) . '
418
				ORDER BY location_type_id');
419
			$this->playableRaceIDs = array();
420
			while ($this->db->nextRecord()) {
421
				$this->playableRaceIDs[] = $this->db->getInt('location_type_id') - 101;
422
			}
423
		}
424
		return $this->playableRaceIDs;
425
	}
426
427
}
428