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
Pull Request — master (#1038)
by Dan
04:32
created

SmrSector::getGalaxyID()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php declare(strict_types=1);
2
3
// Exception thrown when a sector cannot be found in the database
4
class SectorNotFoundException extends Exception {}
5
6
class SmrSector {
7
	protected static $CACHE_SECTORS = array();
8
	protected static $CACHE_GALAXY_SECTORS = array();
9
	protected static $CACHE_LOCATION_SECTORS = array();
10
11
	protected $db;
12
	protected $SQL;
13
14
	protected $gameID;
15
	protected $sectorID;
16
	protected $battles;
17
	protected $galaxyID;
18
	protected $visited = array();
19
	protected $links;
20
	protected $warp;
21
22
	protected $hasChanged = false;
23
	protected $isNew = false;
24
25
	/**
26
	 * Constructs the sector to determine if it exists.
27
	 * Returns a boolean value.
28
	 */
29
	public static function sectorExists($gameID, $sectorID) {
30
		try {
31
			self::getSector($gameID, $sectorID);
32
			return true;
33
		} catch (SectorNotFoundException $e) {
34
			return false;
35
		}
36
	}
37
38
	public static function getGalaxySectors($gameID, $galaxyID, $forceUpdate = false) {
39
		if ($forceUpdate || !isset(self::$CACHE_GALAXY_SECTORS[$gameID][$galaxyID])) {
40
			$db = Smr\Database::getInstance();
41
			$db->query('SELECT * FROM sector WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND galaxy_id=' . $db->escapeNumber($galaxyID) . ' ORDER BY sector_id ASC');
42
			$sectors = array();
43
			while ($db->nextRecord()) {
44
				$sectorID = $db->getInt('sector_id');
45
				$sectors[$sectorID] = self::getSector($gameID, $sectorID, $forceUpdate, $db);
46
			}
47
			self::$CACHE_GALAXY_SECTORS[$gameID][$galaxyID] = $sectors;
48
		}
49
		return self::$CACHE_GALAXY_SECTORS[$gameID][$galaxyID];
50
	}
51
52
	public static function getLocationSectors($gameID, $locationTypeID, $forceUpdate = false) {
53
		if ($forceUpdate || !isset(self::$CACHE_LOCATION_SECTORS[$gameID][$locationTypeID])) {
54
			$db = Smr\Database::getInstance();
55
			$db->query('SELECT * FROM location JOIN sector USING (game_id, sector_id) WHERE location_type_id = ' . $db->escapeNumber($locationTypeID) . ' AND game_id=' . $db->escapeNumber($gameID) . ' ORDER BY sector_id ASC');
56
			$sectors = array();
57
			while ($db->nextRecord()) {
58
				$sectorID = $db->getInt('sector_id');
59
				$sectors[$sectorID] = self::getSector($gameID, $sectorID, $forceUpdate, $db);
60
			}
61
			self::$CACHE_LOCATION_SECTORS[$gameID][$locationTypeID] = $sectors;
62
		}
63
		return self::$CACHE_LOCATION_SECTORS[$gameID][$locationTypeID];
64
	}
65
66
	public static function getSector($gameID, $sectorID, $forceUpdate = false, $db = null) {
67
		if (!isset(self::$CACHE_SECTORS[$gameID][$sectorID]) || $forceUpdate) {
68
			self::$CACHE_SECTORS[$gameID][$sectorID] = new SmrSector($gameID, $sectorID, false, $db);
69
		}
70
		return self::$CACHE_SECTORS[$gameID][$sectorID];
71
	}
72
73
	public static function clearCache() {
74
		self::$CACHE_LOCATION_SECTORS = array();
75
		self::$CACHE_GALAXY_SECTORS = array();
76
		self::$CACHE_SECTORS = array();
77
	}
78
79
	public static function saveSectors() {
80
		foreach (self::$CACHE_SECTORS as $gameSectors) {
81
			foreach ($gameSectors as $sector) {
82
				$sector->update();
83
			}
84
		}
85
	}
86
87
	public static function createSector($gameID, $sectorID) {
88
		if (!isset(self::$CACHE_SECTORS[$gameID][$sectorID])) {
89
			$s = new SmrSector($gameID, $sectorID, true);
90
			self::$CACHE_SECTORS[$gameID][$sectorID] = $s;
91
		}
92
		return self::$CACHE_SECTORS[$gameID][$sectorID];
93
	}
94
95
	protected function __construct($gameID, $sectorID, $create = false, $db = null) {
96
		$this->db = Smr\Database::getInstance();
97
		$this->SQL = 'game_id = ' . $this->db->escapeNumber($gameID) . ' AND sector_id = ' . $this->db->escapeNumber($sectorID);
98
99
		// Do we already have a database query for this sector?
100
		if (isset($db)) {
101
			$sectorExists = true;
102
		} else {
103
			$db = $this->db;
104
			$db->query('SELECT * FROM sector WHERE ' . $this->SQL . ' LIMIT 1');
105
			$sectorExists = $db->nextRecord();
106
		}
107
108
		$this->gameID = (int)$gameID;
109
		$this->sectorID = (int)$sectorID;
110
111
		if ($sectorExists) {
112
			$this->galaxyID = $db->getInt('galaxy_id');
113
			$this->battles = $db->getInt('battles');
114
115
			$this->links = array();
116
			if ($db->getInt('link_up')) {
117
				$this->links['Up'] = $db->getInt('link_up');
118
			}
119
			if ($db->getInt('link_down')) {
120
				$this->links['Down'] = $db->getInt('link_down');
121
			}
122
			if ($db->getInt('link_left')) {
123
				$this->links['Left'] = $db->getInt('link_left');
124
			}
125
			if ($db->getInt('link_right')) {
126
				$this->links['Right'] = $db->getInt('link_right');
127
			}
128
			$this->warp = $db->getInt('warp');
129
		} elseif ($create) {
130
			$this->battles = 0;
131
			$this->links = array();
132
			$this->warp = 0;
133
			$this->isNew = true;
134
			return;
135
		} else {
136
			throw new SectorNotFoundException('No sector ' . $sectorID . ' in game ' . $gameID);
137
		}
138
	}
139
140
	public function update() {
141
		if ($this->isNew) {
142
			$this->db->query('INSERT INTO sector(sector_id,game_id,galaxy_id,link_up,link_down,link_left,link_right,warp)
143
								values
144
								(' . $this->db->escapeNumber($this->getSectorID()) .
145
								',' . $this->db->escapeNumber($this->getGameID()) .
146
								',' . $this->db->escapeNumber($this->getGalaxyID()) .
147
								',' . $this->db->escapeNumber($this->getLinkUp()) .
148
								',' . $this->db->escapeNumber($this->getLinkDown()) .
149
								',' . $this->db->escapeNumber($this->getLinkLeft()) .
150
								',' . $this->db->escapeNumber($this->getLinkRight()) .
151
								',' . $this->db->escapeNumber($this->getWarp()) .
152
								')');
153
		} elseif ($this->hasChanged) {
154
			$this->db->query('UPDATE sector SET battles = ' . $this->db->escapeNumber($this->getBattles()) .
155
									', galaxy_id=' . $this->db->escapeNumber($this->getGalaxyID()) .
156
									', link_up=' . $this->db->escapeNumber($this->getLinkUp()) .
157
									', link_right=' . $this->db->escapeNumber($this->getLinkRight()) .
158
									', link_down=' . $this->db->escapeNumber($this->getLinkDown()) .
159
									', link_left=' . $this->db->escapeNumber($this->getLinkLeft()) .
160
									', warp=' . $this->db->escapeNumber($this->getWarp()) .
161
								' WHERE ' . $this->SQL . ' LIMIT 1');
162
		}
163
		$this->isNew = false;
164
		$this->hasChanged = false;
165
	}
166
167
	public function markVisited(AbstractSmrPlayer $player) {
168
		if ($this->hasPort()) {
169
			$this->getPort()->addCachePort($player->getAccountID());
170
		}
171
172
		//now delete the entry from visited
173
		if (!$this->isVisited($player)) {
174
			$this->db->query('DELETE FROM player_visited_sector WHERE ' . $this->SQL . '
175
								 AND account_id = ' . $this->db->escapeNumber($player->getAccountID()) . ' LIMIT 1');
176
		}
177
		$this->visited[$player->getAccountID()] = true;
178
	}
179
180
	public function hasWeaponShop() {
181
		foreach ($this->getLocations() as $location) {
182
			if ($location->isWeaponSold()) {
183
				return true;
184
			}
185
		}
186
		return false;
187
	}
188
189
	public function hasHQ() {
190
		foreach ($this->getLocations() as $location) {
191
			if ($location->isHQ()) {
192
				return true;
193
			}
194
		}
195
		return false;
196
	}
197
198
	public function hasUG() {
199
		foreach ($this->getLocations() as $location) {
200
			if ($location->isUG()) {
201
				return true;
202
			}
203
		}
204
		return false;
205
	}
206
207
	public function hasShipShop() {
208
		foreach ($this->getLocations() as $location) {
209
			if ($location->isShipSold()) {
210
				return true;
211
			}
212
		}
213
		return false;
214
	}
215
216
	public function offersFederalProtection() {
217
		foreach ($this->getLocations() as $location) {
218
			if ($location->isFed()) {
219
				return true;
220
			}
221
		}
222
		return false;
223
	}
224
225
	public function getFedRaceIDs() {
226
		$raceIDs = array();
227
		foreach ($this->getLocations() as $location) {
228
			if ($location->isFed()) {
229
				$raceIDs[$location->getRaceID()] = $location->getRaceID();
230
			}
231
		}
232
		return $raceIDs;
233
	}
234
235
	public function hasBar() {
236
		foreach ($this->getLocations() as $location) {
237
			if ($location->isBar()) {
238
				return true;
239
			}
240
		}
241
		return false;
242
	}
243
244
	public function hasHardwareShop() {
245
		foreach ($this->getLocations() as $location) {
246
			if ($location->isHardwareSold()) {
247
				return true;
248
			}
249
		}
250
		return false;
251
	}
252
253
	public function hasBank() {
254
		foreach ($this->getLocations() as $location) {
255
			if ($location->isBank()) {
256
				return true;
257
			}
258
		}
259
		return false;
260
	}
261
262
	public function enteringSector(AbstractSmrPlayer $player, $movementType) {
263
		// send scout messages to user
264
		$message = 'Your forces have spotted ' . $player->getBBLink() . ' ';
265
		$message .= match($movementType) {
266
			MOVEMENT_JUMP => 'jumping into',
267
			MOVEMENT_WARP => 'warping into',
268
			MOVEMENT_WALK => 'entering',
269
		};
270
		$message .= ' sector ' . Globals::getSectorBBLink($this->getSectorID());
271
272
		$forces = $this->getForces();
273
		foreach ($forces as $force) {
274
			$force->ping($message, $player);
275
		}
276
	}
277
278
	public function leavingSector(AbstractSmrPlayer $player, $movementType) {
279
		// send scout messages to user
280
		$message = 'Your forces have spotted ' . $player->getBBLink() . ' ';
281
		$message .= match($movementType) {
282
			MOVEMENT_JUMP => 'jumping from',
283
			MOVEMENT_WARP => 'warping from',
284
			MOVEMENT_WALK => 'leaving',
285
		};
286
		$message .= ' sector ' . Globals::getSectorBBLink($this->getSectorID());
287
288
		// iterate over all scout drones in sector
289
		foreach ($this->getForces() as $force) {
290
			$force->ping($message, $player);
291
		}
292
		$this->db->query('UPDATE sector_has_forces SET refresher = 0 WHERE ' . $this->SQL . '
293
								AND refresher = ' . $this->db->escapeNumber($player->getAccountID()));
294
	}
295
296
	public function diedHere(AbstractSmrPlayer $player) {
297
		// iterate over all scout drones in sector
298
		foreach ($this->getForces() as $force) {
299
			// send scout messages to user
300
			$message = 'Your forces have spotted that ' . $player->getBBLink() . ' has been <span class="red">DESTROYED</span> in sector ' . Globals::getSectorBBLink($this->sectorID);
301
			$force->ping($message, $player);
302
		}
303
	}
304
305
	public function getSQL() {
306
		return $this->SQL;
307
	}
308
309
	public function getGameID() {
310
		return $this->gameID;
311
	}
312
313
	public function getSectorID() {
314
		return $this->sectorID;
315
	}
316
317
	public function getGalaxyID() {
318
		return $this->galaxyID;
319
	}
320
321
	public function setGalaxyID($galaxyID) {
322
		if ($this->galaxyID == $galaxyID) {
323
			return;
324
		}
325
		$this->galaxyID = $galaxyID;
326
		$this->hasChanged = true;
327
	}
328
329
	public function getNumberOfLinks() {
330
		$num = 0;
331
		if (!is_array($this->getLinks())) {
332
			return $num;
333
		}
334
		foreach ($this->getLinks() as $link) {
335
			if ($link !== 0) {
336
				$num++;
337
			}
338
		}
339
		return $num;
340
	}
341
342
	public function getNumberOfConnections() {
343
		$links = $this->getNumberOfLinks();
344
		if ($this->hasWarp()) {
345
			$links++;
346
		}
347
		return $links;
348
	}
349
350
	public function getGalaxy() {
351
		return SmrGalaxy::getGalaxy($this->getGameID(), $this->getGalaxyID());
352
	}
353
354
	public function getNeighbourID($dir) {
355
		if ($this->hasLink($dir)) {
356
			return $this->getLink($dir);
357
		}
358
		$galaxy = $this->getGalaxy();
359
		$neighbour = $this->getSectorID();
360
		switch ($dir) {
361
			case 'Up':
362
				$neighbour -= $galaxy->getWidth();
363
				if ($neighbour < $galaxy->getStartSector()) {
364
					$neighbour += $galaxy->getSize();
365
				}
366
			break;
367
			case 'Down':
368
				$neighbour += $galaxy->getWidth();
369
				if ($neighbour > $galaxy->getEndSector()) {
370
					$neighbour -= $galaxy->getSize();
371
				}
372
			break;
373
			case 'Left':
374
				$neighbour -= 1;
375
				if ((1 + $neighbour - $galaxy->getStartSector()) % $galaxy->getWidth() == 0) {
376
					$neighbour += $galaxy->getWidth();
377
				}
378
			break;
379
			case 'Right':
380
				$neighbour += 1;
381
				if (($neighbour - $galaxy->getStartSector()) % $galaxy->getWidth() == 0) {
382
					$neighbour -= $galaxy->getWidth();
383
				}
384
			break;
385
			default:
386
				throw new Exception($dir . ': is not a valid direction');
387
		}
388
		return $neighbour;
389
	}
390
391
	public function getSectorDirection($sectorID) {
392
		if ($sectorID == $this->getSectorID()) {
393
			return 'Current';
394
		}
395
		$dir = array_search($sectorID, $this->getLinks());
396
		if ($dir !== false) {
397
			return $dir;
398
		}
399
		if ($sectorID == $this->getWarp()) {
400
			return 'Warp';
401
		}
402
		return 'None';
403
	}
404
405
	public function getNeighbourSector($dir) {
406
		return SmrSector::getSector($this->getGameID(), $this->getNeighbourID($dir));
407
	}
408
409
	public function getLinks() {
410
		return $this->links;
411
	}
412
413
	public function isLinked($sectorID) {
414
		return in_array($sectorID, $this->links) || $sectorID == $this->getWarp();
415
	}
416
417
	public function getLink($name) {
418
		return $this->links[$name] ?? 0;
419
	}
420
421
	public function hasLink($name) {
422
		return $this->getLink($name) != 0;
423
	}
424
425
	public function getLinkSector($name) {
426
		if ($this->hasLink($name)) {
427
			return SmrSector::getSector($this->getGameID(), $this->getLink($name));
428
		}
429
		return false;
430
	}
431
432
	/**
433
	 * Cannot be used for Warps
434
	 */
435
	public function setLink($name, $linkID) {
436
		if ($this->getLink($name) == $linkID) {
437
			return;
438
		}
439
		if ($linkID == 0) {
440
			unset($this->links[$name]);
441
		} else {
442
			$this->links[$name] = $linkID;
443
		}
444
		$this->hasChanged = true;
445
	}
446
447
	/**
448
	 * Cannot be used for Warps
449
	 */
450
	public function setLinkSector($dir, SmrSector $linkSector) {
451
		if ($this->getLink($dir) == $linkSector->getSectorID() || $linkSector->equals($this)) {
452
			return;
453
		}
454
		$this->setLink($dir, $linkSector->getSectorID());
455
		$linkSector->setLink(self::oppositeDir($dir), $this->getSectorID());
456
		$this->hasChanged = true;
457
	}
458
	/**
459
	 * Cannot be used for Warps
460
	 */
461
	public function enableLink($dir) {
462
		$this->setLinkSector($dir, $this->getNeighbourSector($dir));
463
	}
464
	/**
465
	 * Cannot be used for Warps
466
	 */
467
	public function disableLink($dir) {
468
		$this->setLink($dir, 0);
469
		$this->getNeighbourSector($dir)->setLink(self::oppositeDir($dir), 0);
470
	}
471
	/**
472
	 * Cannot be used for Warps
473
	 */
474
	public function toggleLink($dir) {
475
		if ($this->hasLink($dir)) {
476
			$this->disableLink($dir);
477
		} else {
478
			$this->enableLink($dir);
479
		}
480
	}
481
482
	protected static function oppositeDir($dir) {
483
		return match($dir) {
484
			'Up' => 'Down',
485
			'Down' => 'Up',
486
			'Left' => 'Right',
487
			'Right' => 'Left',
488
			'Warp' => 'Warp',
489
		};
490
	}
491
492
	public function getLinkUp() {
493
		return $this->getLink('Up');
494
	}
495
496
	public function setLinkUp($linkID) {
497
		$this->setLink('Up', $linkID);
498
	}
499
500
	public function hasLinkUp() {
501
		return $this->hasLink('Up');
502
	}
503
504
	public function getLinkDown() {
505
		return $this->getLink('Down');
506
	}
507
508
	public function setLinkDown($linkID) {
509
		$this->setLink('Down', $linkID);
510
	}
511
512
	public function hasLinkDown() {
513
		return $this->hasLink('Down');
514
	}
515
516
	public function getLinkLeft() {
517
		return $this->getLink('Left');
518
	}
519
520
	public function hasLinkLeft() {
521
		return $this->hasLink('Left');
522
	}
523
524
	public function setLinkLeft($linkID) {
525
		$this->setLink('Left', $linkID);
526
	}
527
528
	public function getLinkRight() {
529
		return $this->getLink('Right');
530
	}
531
532
	public function hasLinkRight() {
533
		return $this->hasLink('Right');
534
	}
535
536
	public function setLinkRight($linkID) {
537
		$this->setLink('Right', $linkID);
538
	}
539
540
	/**
541
	 * Returns the warp sector if the sector has a warp; returns 0 otherwise.
542
	 */
543
	public function getWarp() {
544
		return $this->warp;
545
	}
546
547
	public function getWarpSector() {
548
		return SmrSector::getSector($this->getGameID(), $this->getWarp());
549
	}
550
551
	public function hasWarp() {
552
		return $this->getWarp() != 0;
553
	}
554
555
	/**
556
	 * Set the warp sector for both $this and $warp to ensure
557
	 * a consistent 2-way warp.
558
	 */
559
	public function setWarp(SmrSector $warp) {
560
		if ($this->getWarp() == $warp->getSectorID() &&
561
		    $warp->getWarp() == $this->getSectorID()) {
562
			// Warps are already set correctly!
563
			return;
564
		}
565
566
		if ($this->equals($warp)) {
567
			throw new Exception('Sector must not warp to itself!');
568
		}
569
570
		// Can only have 1 warp per sector
571
		foreach ([[$warp, $this], [$this, $warp]] as $sectors) {
572
			$A = $sectors[0];
573
			$B = $sectors[1];
574
			if ($A->hasWarp() && $A->getWarp() != $B->getSectorID()) {
575
				throw new Exception('Sector ' . $A->getSectorID() . ' already has a warp (to ' . $A->getWarp() . ')!');
576
			}
577
		}
578
579
		$this->warp = $warp->getSectorID();
580
		$this->hasChanged = true;
581
582
		if ($warp->getWarp() != $this->getSectorID()) {
583
			// Set the other side if needed
584
			$warp->setWarp($this);
585
		}
586
	}
587
588
	/**
589
	 * Remove the warp sector for both sides of the warp.
590
	 */
591
	public function removeWarp() {
592
		if (!$this->hasWarp()) {
593
			return;
594
		}
595
596
		$warp = $this->getWarpSector();
597
		if ($warp->hasWarp() && $warp->getWarp() != $this->getSectorID()) {
598
			throw new Exception('Warp sectors do not match');
599
		}
600
601
		$this->warp = 0;
602
		$this->hasChanged = true;
603
604
		if ($warp->hasWarp()) {
605
			$warp->removeWarp();
606
		}
607
	}
608
609
	public function hasPort() {
610
		return $this->getPort()->exists();
611
	}
612
613
	public function getPort() {
614
		return SmrPort::getPort($this->getGameID(), $this->getSectorID());
615
	}
616
617
	public function createPort() {
618
		return SmrPort::createPort($this->getGameID(), $this->getSectorID());
619
	}
620
621
	public function removePort() {
622
		SmrPort::removePort($this->getGameID(), $this->getSectorID());
623
	}
624
625
	public function hasCachedPort(AbstractSmrPlayer $player = null) {
626
		return $this->getCachedPort($player) !== false;
627
	}
628
629
	public function getCachedPort(AbstractSmrPlayer $player = null) {
630
		if ($player == null) {
631
			$return = false;
632
			return $return;
633
		}
634
		return SmrPort::getCachedPort($this->getGameID(), $this->getSectorID(), $player->getAccountID());
635
	}
636
637
	public function hasAnyLocationsWithAction() {
638
		$locations = SmrLocation::getSectorLocations($this->getGameID(), $this->getSectorID());
639
		$hasAction = false;
640
		foreach ($locations as $location) {
641
			if ($location->hasAction()) {
642
				$hasAction = true;
643
			}
644
		}
645
		return $hasAction;
646
	}
647
648
	public function hasLocation($locationTypeID = false) {
649
		$locations = $this->getLocations();
650
		if (count($locations) == 0) {
651
			return false;
652
		}
653
		if ($locationTypeID == false) {
654
			return true;
655
		}
656
		foreach ($locations as $location) {
657
			if ($location->getTypeID() == $locationTypeID) {
658
				return true;
659
			}
660
		}
661
		return false;
662
	}
663
664
	public function getLocations() {
665
		return SmrLocation::getSectorLocations($this->getGameID(), $this->getSectorID());
666
	}
667
668
	public function addLocation(SmrLocation $location) {
669
		SmrLocation::addSectorLocation($this->getGameID(), $this->getSectorID(), $location);
670
	}
671
672
	public function removeAllLocations() {
673
		SmrLocation::removeSectorLocations($this->getGameID(), $this->getSectorID());
674
	}
675
676
	public function hasPlanet() {
677
		return $this->getPlanet()->exists();
678
	}
679
680
	public function getPlanet() {
681
		return SmrPlanet::getPlanet($this->getGameID(), $this->getSectorID());
682
	}
683
684
	public function createPlanet($type = 1) {
685
		return SmrPlanet::createPlanet($this->getGameID(), $this->getSectorID(), $type);
686
	}
687
688
	public function removePlanet() {
689
		SmrPlanet::removePlanet($this->getGameID(), $this->getSectorID());
690
	}
691
692
	/**
693
	 * Removes ports, planets, locations, and warps from this sector.
694
	 * NOTE: This should only be used by the universe generator!
695
	 */
696
	public function removeAllFixtures() {
697
		if ($this->hasPort()) {
698
			$this->removePort();
699
		}
700
		if ($this->hasPlanet()) {
701
			$this->removePlanet();
702
		}
703
		if ($this->hasLocation()) {
704
			$this->removeAllLocations();
705
		}
706
		if ($this->hasWarp()) {
707
			$this->removeWarp();
708
		}
709
	}
710
711
	public function hasForces() {
712
		return count($this->getForces()) > 0;
713
	}
714
715
	public function hasEnemyForces(AbstractSmrPlayer $player = null) {
716
		if ($player == null || !$this->hasForces()) {
717
			return false;
718
		}
719
		foreach ($this->getForces() as $force) {
720
			if (!$player->forceNAPAlliance($force->getOwner())) {
721
				return true;
722
			}
723
		}
724
		return false;
725
	}
726
727
	public function getEnemyForces(AbstractSmrPlayer $player) {
728
		$enemyForces = array();
729
		foreach ($this->getForces() as $force) {
730
			if (!$player->forceNAPAlliance($force->getOwner())) {
731
				$enemyForces[] = $force;
732
			}
733
		}
734
		return $enemyForces;
735
	}
736
737
	/**
738
	 * Returns true if any forces in this sector belong to $player.
739
	 */
740
	public function hasPlayerForces(AbstractSmrPlayer $player) {
741
		foreach ($this->getForces() as $force) {
742
			if ($player->getAccountID() == $force->getOwnerID()) {
743
				return true;
744
			}
745
		}
746
		return false;
747
	}
748
749
	public function hasFriendlyForces(AbstractSmrPlayer $player = null) {
750
		if ($player == null || !$this->hasForces()) {
751
			return false;
752
		}
753
		foreach ($this->getForces() as $force) {
754
			if ($player->forceNAPAlliance($force->getOwner())) {
755
				return true;
756
			}
757
		}
758
		return false;
759
	}
760
761
	public function getFriendlyForces(AbstractSmrPlayer $player) {
762
		$friendlyForces = array();
763
		foreach ($this->getForces() as $force) {
764
			if ($player->forceNAPAlliance($force->getOwner())) {
765
				$friendlyForces[] = $force;
766
			}
767
		}
768
		return $friendlyForces;
769
	}
770
771
	public function getForces() {
772
		return SmrForce::getSectorForces($this->getGameID(), $this->getSectorID());
773
	}
774
775
	public function getPlayers() {
776
		return SmrPlayer::getSectorPlayers($this->getGameID(), $this->getSectorID());
777
	}
778
779
	public function hasPlayers() {
780
		return count($this->getPlayers()) > 0;
781
	}
782
783
	public function getOtherTraders(AbstractSmrPlayer $player) {
784
		$players = SmrPlayer::getSectorPlayers($this->getGameID(), $this->getSectorID()); //Do not use & because we unset something and only want that in what we return
785
		unset($players[$player->getAccountID()]);
786
		return $players;
787
	}
788
789
	public function hasOtherTraders(AbstractSmrPlayer $player) {
790
		return count($this->getOtherTraders($player)) > 0;
791
	}
792
793
	public function hasEnemyTraders(AbstractSmrPlayer $player = null) {
794
		if ($player == null || !$this->hasOtherTraders($player)) {
795
			return false;
796
		}
797
		$otherPlayers = $this->getOtherTraders($player);
798
		foreach ($otherPlayers as $otherPlayer) {
799
			if (!$player->traderNAPAlliance($otherPlayer)
800
				&& !$otherPlayer->hasNewbieTurns()
801
				&& !$otherPlayer->hasFederalProtection()) {
802
				return true;
803
			}
804
		}
805
		return false;
806
	}
807
808
	public function hasFriendlyTraders(AbstractSmrPlayer $player = null) {
809
		if ($player == null || !$this->hasOtherTraders($player)) {
810
			return false;
811
		}
812
		$otherPlayers = $this->getOtherTraders($player);
813
		foreach ($otherPlayers as $otherPlayer) {
814
			if ($player->traderNAPAlliance($otherPlayer)) {
815
				return true;
816
			}
817
		}
818
		return false;
819
	}
820
821
	/**
822
	 * Is the $player's alliance flagship in this sector?
823
	 */
824
	public function hasAllianceFlagship(AbstractSmrPlayer $player = null) {
825
		if (is_null($player) || !$player->hasAlliance() || !$player->getAlliance()->hasFlagship()) {
826
			return false;
827
		}
828
		$flagshipID = $player->getAlliance()->getFlagshipID();
829
		foreach ($this->getPlayers() as $sectorPlayer) {
830
			if ($sectorPlayer->getAccountID() == $flagshipID) {
831
				return true;
832
			}
833
		}
834
		return false;
835
	}
836
837
	public function hasProtectedTraders(AbstractSmrPlayer $player = null) {
838
		if ($player == null || !$this->hasOtherTraders($player)) {
839
			return false;
840
		}
841
		$otherPlayers = $this->getOtherTraders($player);
842
		foreach ($otherPlayers as $otherPlayer) {
843
			if (!$player->traderNAPAlliance($otherPlayer)
844
				&& ($otherPlayer->hasNewbieTurns() || $otherPlayer->hasFederalProtection())) {
845
				return true;
846
			}
847
		}
848
		return false;
849
	}
850
851
	public function getFightingTradersAgainstForces(AbstractSmrPlayer $attackingPlayer, $bump) {
0 ignored issues
show
Unused Code introduced by
The parameter $bump 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

851
	public function getFightingTradersAgainstForces(AbstractSmrPlayer $attackingPlayer, /** @scrutinizer ignore-unused */ $bump) {

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...
852
		// Whether bumping or attacking, only the current player fires at forces
853
		return array($attackingPlayer);
854
	}
855
856
	public function getFightingTradersAgainstPort(AbstractSmrPlayer $attackingPlayer, SmrPort $defendingPort) {
0 ignored issues
show
Unused Code introduced by
The parameter $defendingPort 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

856
	public function getFightingTradersAgainstPort(AbstractSmrPlayer $attackingPlayer, /** @scrutinizer ignore-unused */ SmrPort $defendingPort) {

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...
857
		$fightingPlayers = array();
858
		$alliancePlayers = SmrPlayer::getSectorPlayersByAlliances($this->getGameID(), $this->getSectorID(), array($attackingPlayer->getAllianceID()));
859
		foreach ($alliancePlayers as $accountID => $player) {
860
			if ($player->canFight()) {
861
				if ($attackingPlayer->traderAttackPortAlliance($player)) {
862
					$fightingPlayers[$accountID] = $alliancePlayers[$accountID];
863
				}
864
			}
865
		}
866
		return self::limitFightingTraders($fightingPlayers, $attackingPlayer, MAXIMUM_PORT_FLEET_SIZE);
867
	}
868
869
	public function getFightingTradersAgainstPlanet(AbstractSmrPlayer $attackingPlayer, SmrPlanet $defendingPlanet) {
870
		$fightingPlayers = array();
871
		$alliancePlayers = SmrPlayer::getSectorPlayersByAlliances($this->getGameID(), $this->getSectorID(), array($attackingPlayer->getAllianceID()));
872
		if (count($alliancePlayers) > 0) {
873
			$planetOwner = $defendingPlanet->getOwner();
874
			foreach ($alliancePlayers as $accountID => $player) {
875
				if ($player->canFight()) {
876
					if ($attackingPlayer->traderAttackPlanetAlliance($player) && !$planetOwner->planetNAPAlliance($player)) {
877
						$fightingPlayers[$accountID] = $alliancePlayers[$accountID];
878
					}
879
				}
880
			}
881
		}
882
		return self::limitFightingTraders($fightingPlayers, $attackingPlayer, min($defendingPlanet->getMaxAttackers(), MAXIMUM_PLANET_FLEET_SIZE));
883
	}
884
885
	public function getFightingTraders(AbstractSmrPlayer $attackingPlayer, AbstractSmrPlayer $defendingPlayer, $checkForCloak = false) {
886
		if ($attackingPlayer->traderNAPAlliance($defendingPlayer)) {
887
			throw new Exception('These traders are NAPed.');
888
		}
889
		$fightingPlayers = array('Attackers' => array(), 'Defenders' => array());
890
		$alliancePlayers = SmrPlayer::getSectorPlayersByAlliances($this->getGameID(), $this->getSectorID(), array($attackingPlayer->getAllianceID(), $defendingPlayer->getAllianceID()));
891
		$attackers = array();
892
		$defenders = array();
893
		foreach ($alliancePlayers as $accountID => $player) {
894
			if ($player->canFight()) {
895
				if ($attackingPlayer->traderAttackTraderAlliance($player) && !$defendingPlayer->traderDefendTraderAlliance($player) && !$defendingPlayer->traderNAPAlliance($player)) {
896
					$attackers[] = $alliancePlayers[$accountID];
897
				} elseif ($defendingPlayer->traderDefendTraderAlliance($player) && !$attackingPlayer->traderAttackTraderAlliance($player) && !$attackingPlayer->traderNAPAlliance($player) && ($checkForCloak === false || $attackingPlayer->canSee($player))) {
898
					$defenders[] = $alliancePlayers[$accountID];
899
				}
900
			}
901
		}
902
		$attackers = self::limitFightingTraders($attackers, $attackingPlayer, MAXIMUM_PVP_FLEET_SIZE);
903
		shuffle($attackers);
904
		foreach ($attackers as $attacker) {
905
			$fightingPlayers['Attackers'][$attacker->getAccountID()] = $attacker;
906
		}
907
		$defenders = self::limitFightingTraders($defenders, $defendingPlayer, MAXIMUM_PVP_FLEET_SIZE);
908
		shuffle($defenders);
909
		foreach ($defenders as $defender) {
910
			$fightingPlayers['Defenders'][$defender->getAccountID()] = $defender;
911
		}
912
		return $fightingPlayers;
913
	}
914
915
	public static function limitFightingTraders(array &$fightingPlayers, AbstractSmrPlayer $keepPlayer, $maximumFleetSize) {
916
		// Cap fleets to the required size
917
		$fleet_size = count($fightingPlayers);
918
		if ($fleet_size > $maximumFleetSize) {
919
			// We use random key to stop the same people being capped all the time
920
			for ($j = 0; $j < $fleet_size - $maximumFleetSize; ++$j) {
921
				do {
922
					$key = array_rand($fightingPlayers);
923
				} while ($keepPlayer->equals($fightingPlayers[$key]));
924
				unset($fightingPlayers[$key]);
925
			}
926
		}
927
		return $fightingPlayers;
928
	}
929
930
	public function getPotentialFightingTraders(AbstractSmrPlayer $attackingPlayer) {
931
		$fightingPlayers = array();
932
		$alliancePlayers = SmrPlayer::getSectorPlayersByAlliances($this->getGameID(), $this->getSectorID(), array($attackingPlayer->getAllianceID()));
933
		foreach ($alliancePlayers as $accountID => $player) {
934
			if ($player->canFight()) {
935
				if ($attackingPlayer->traderAttackTraderAlliance($player)) {
936
					$fightingPlayers['Attackers'][$accountID] = $player;
937
				}
938
			}
939
		}
940
		return $fightingPlayers;
941
	}
942
943
	public function getBattles() {
944
		return $this->battles;
945
	}
946
947
	public function setBattles($amount) {
948
		if ($this->battles == $amount) {
949
			return;
950
		}
951
		$this->battles = $amount;
952
		$this->hasChanged = true;
953
	}
954
955
	public function decreaseBattles($amount) {
956
		$this->setBattles($this->battles - $amount);
957
	}
958
959
	public function increaseBattles($amount) {
960
		$this->setBattles($this->battles + $amount);
961
	}
962
963
	public function equals(SmrSector $otherSector) {
964
		return $otherSector->getSectorID() == $this->getSectorID() && $otherSector->getGameID() == $this->getGameID();
965
	}
966
967
	public function isLinkedSector(SmrSector $otherSector) {
968
		return $otherSector->getGameID() == $this->getGameID() && $this->isLinked($otherSector->getSectorID());
969
	}
970
971
	public function isVisited(AbstractSmrPlayer $player = null) {
972
		if ($player === null) {
973
			return true;
974
		}
975
		if (!isset($this->visited[$player->getAccountID()])) {
976
			$this->db->query('SELECT sector_id FROM player_visited_sector WHERE ' . $this->SQL . ' AND account_id=' . $this->db->escapeNumber($player->getAccountID()) . ' LIMIT 1');
977
			$this->visited[$player->getAccountID()] = !$this->db->nextRecord();
978
		}
979
		return $this->visited[$player->getAccountID()];
980
	}
981
982
	public function getLocalMapMoveHREF(AbstractSmrPlayer $player) : string {
983
		return Globals::getSectorMoveHREF($player, $this->getSectorID(), 'map_local.php');
984
	}
985
986
	public function getCurrentSectorMoveHREF(AbstractSmrPlayer $player) : string {
987
		return Globals::getCurrentSectorMoveHREF($player, $this->getSectorID());
988
	}
989
990
	public function getGalaxyMapHREF() {
991
		return '?sector_id=' . $this->getSectorID();
992
	}
993
994
	public function getSectorScanHREF(AbstractSmrPlayer $player) : string {
995
		return Globals::getSectorScanHREF($player, $this->getSectorID());
996
	}
997
998
	public function hasX(/*Object*/ $x, AbstractSmrPlayer $player = null) {
999
		if ($x instanceof SmrSector) {
1000
			return $this->equals($x);
1001
		}
1002
		if ($x == 'Port') {
1003
			return $this->hasPort();
1004
		}
1005
		if ($x == 'Location') {
1006
			return $this->hasLocation();
1007
		}
1008
		if ($x instanceof SmrLocation) {
1009
			return $this->hasLocation($x->getTypeID());
1010
		}
1011
		if ($x instanceof SmrGalaxy) {
1012
			return $x->contains($this);
1013
		}
1014
1015
		if (is_array($x) && $x['Type'] == 'Good') { //Check if it's possible for port to have X, hacky but nice performance gains
1016
			if ($this->hasPort() && $this->getPort()->hasX($x)) {
1017
				return true;
1018
			}
1019
		}
1020
1021
		//Check if it's possible for location to have X, hacky but nice performance gains
1022
		if ($x instanceof SmrWeaponType || (is_array($x) && ($x['Type'] == 'Ship' || $x['Type'] == 'Hardware')) || (is_string($x) && ($x == 'Bank' || $x == 'Bar' || $x == 'Fed' || $x == 'SafeFed' || $x == 'HQ' || $x == 'UG' || $x == 'Hardware' || $x == 'Ship' || $x == 'Weapon'))) {
1023
			foreach ($this->getLocations() as $loc) {
1024
				if ($loc->hasX($x, $player)) {
1025
					return true;
1026
				}
1027
			}
1028
		}
1029
		return false;
1030
	}
1031
}
1032