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 — main (#1494)
by Dan
08:06 queued 03:15
created

SectorsFile   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 121
dl 0
loc 183
rs 9.1199
c 1
b 0
f 0
wmc 41

1 Method

Rating   Name   Duplication   Size   Complexity  
F create() 0 181 41

How to fix   Complexity   

Complex Class

Complex classes like SectorsFile often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SectorsFile, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
namespace Smr;
4
5
use AbstractSmrPlayer;
6
use Globals;
7
use SmrForce;
8
use SmrGame;
9
use SmrLocation;
10
use SmrPlanet;
11
use SmrPort;
12
use SmrSector;
13
use SmrShipType;
14
use SmrWeaponType;
15
16
class SectorsFile {
17
18
	public static function create(int $gameID, ?AbstractSmrPlayer $player, bool $adminCreate = false): never {
19
		// NOTE: If the format of this file is changed in an incompatible way,
20
		// make sure to update the SMR_FILE_VERSION!
21
22
		$file = ';SMR1.6 Sectors File v' . SMR_FILE_VERSION . '
23
		; Created on ' . date(DEFAULT_DATE_TIME_FORMAT) . '
24
		[Races]
25
		; Name = ID' . EOL;
26
		foreach (Race::getAllNames() as $raceID => $raceName) {
27
			$file .= inify($raceName) . '=' . $raceID . EOL;
28
		}
29
30
		$file .= '[Goods]
31
		; ID = Name, BasePrice' . EOL;
32
		foreach (Globals::getGoods() as $good) {
33
			$file .= $good['ID'] . '=' . inify($good['Name']) . ',' . $good['BasePrice'] . EOL;
34
		}
35
36
		$file .= '[Weapons]
37
		; Weapon = Race,Cost,Shield,Armour,Accuracy,Power level,Restriction
38
		; Restriction: 0=none, 1=good, 2=evil, 3=newbie, 4=port, 5=planet' . EOL;
39
		foreach (SmrWeaponType::getAllWeaponTypes() as $weapon) {
40
			$file .= inify($weapon->getName()) . '=' . inify($weapon->getRaceName()) . ',' . $weapon->getCost() . ',' . $weapon->getShieldDamage() . ',' . $weapon->getArmourDamage() . ',' . $weapon->getAccuracy() . ',' . $weapon->getPowerLevel() . ',' . $weapon->getBuyerRestriction()->value . EOL;
41
		}
42
43
		$file .= '[ShipEquipment]
44
		; Name = Cost' . EOL;
45
		$hardwares = Globals::getHardwareTypes();
46
		foreach ($hardwares as $hardware) {
47
			$file .= inify($hardware['Name']) . '=' . $hardware['Cost'] . EOL;
48
		}
49
50
		$file .= '[Ships]
51
		; Name = Race,Cost,TPH,Hardpoints,Power,Class,+Equipment (Optional),+Restrictions(Optional)
52
		; Restrictions:Align(Integer)' . EOL;
53
		foreach (SmrShipType::getAll() as $ship) {
54
			$file .= inify($ship->getName()) . '=' . inify($ship->getRaceName()) . ',' . $ship->getCost() . ',' . $ship->getSpeed() . ',' . $ship->getHardpoints() . ',' . $ship->getMaxPower() . ',' . $ship->getClass()->name;
55
			$shipEquip = [];
56
			foreach ($ship->getAllMaxHardware() as $hardwareID => $maxHardware) {
57
				$shipEquip[] = $hardwares[$hardwareID]['Name'] . '=' . $maxHardware;
58
			}
59
			if (!empty($shipEquip)) {
60
				$file .= ',ShipEquipment=' . implode(';', $shipEquip);
61
			}
62
			$file .= ',Restrictions=' . $ship->getRestriction()->value;
63
			$file .= EOL;
64
		}
65
66
		$file .= '[Locations]
67
		; Name = +Sells' . EOL;
68
		foreach (SmrLocation::getAllLocations($gameID) as $location) {
69
			$file .= inify($location->getName()) . '=';
70
			$locSells = '';
71
			if ($location->isWeaponSold()) {
72
				$locSells .= 'Weapons=';
73
				foreach ($location->getWeaponsSold() as $locWeapon) {
74
					$locSells .= $locWeapon->getName() . ';';
75
				}
76
				$locSells = substr($locSells, 0, -1) . ',';
77
			}
78
			if ($location->isHardwareSold()) {
79
				$locSells .= 'ShipEquipment=';
80
				foreach ($location->getHardwareSold() as $locHardware) {
81
					$locSells .= $locHardware['Name'] . ';';
82
				}
83
				$locSells = substr($locSells, 0, -1) . ',';
84
			}
85
			if ($location->isShipSold()) {
86
				$locSells .= 'Ships=';
87
				foreach ($location->getShipsSold() as $locShip) {
88
					$locSells .= $locShip->getName() . ';';
89
				}
90
				$locSells = substr($locSells, 0, -1) . ',';
91
			}
92
			if ($location->isBank()) {
93
				$locSells .= 'Bank=,';
94
			}
95
			if ($location->isBar()) {
96
				$locSells .= 'Bar=,';
97
			}
98
			if ($location->isHQ()) {
99
				$locSells .= 'HQ=,';
100
			}
101
			if ($location->isUG()) {
102
				$locSells .= 'UG=,';
103
			}
104
			if ($location->isFed()) {
105
				$locSells .= 'Fed=,';
106
			}
107
			if ($locSells != '') {
108
				$file .= substr($locSells, 0, -1);
109
			}
110
			$file .= EOL;
111
		}
112
113
		// Everything below here must be valid INI syntax (safe to parse)
114
		$game = SmrGame::getGame($gameID);
115
		$file .= '[Metadata]
116
		FileVersion=' . SMR_FILE_VERSION . '
117
		[Game]
118
		Name=' . inify($game->getName()) . '
119
		[Galaxies]
120
		';
121
		$galaxies = $game->getGalaxies();
122
		foreach ($galaxies as $galaxy) {
123
			$file .= $galaxy->getGalaxyID() . '=' . $galaxy->getWidth() . ',' . $galaxy->getHeight() . ',' . $galaxy->getGalaxyType() . ',' . inify($galaxy->getName()) . ',' . $galaxy->getMaxForceTime() . EOL;
124
		}
125
126
		foreach ($galaxies as $galaxy) {
127
			// Efficiently construct the caches before proceeding
128
			$galaxy->getLocations();
129
			$galaxy->getPlanets();
130
			$galaxy->getForces();
131
132
			foreach ($galaxy->getSectors() as $sector) {
133
				$file .= '[Sector=' . $sector->getSectorID() . ']' . EOL;
134
135
				if (!$sector->isVisited($player) && $adminCreate === false) {
136
					continue;
137
				}
138
139
				foreach ($sector->getLinks() as $linkName => $link) {
140
					$file .= $linkName . '=' . $link . EOL;
141
				}
142
				if ($sector->hasWarp()) {
143
					$file .= 'Warp=' . $sector->getWarp() . EOL;
144
				}
145
				if (($adminCreate !== false && $sector->hasPort()) || is_object($player) && $sector->hasCachedPort($player)) {
146
					if ($adminCreate !== false) {
147
						$port = $sector->getPort();
148
					} else {
149
						$port = $sector->getCachedPort($player);
150
					}
151
					$file .= 'Port Level=' . $port->getLevel() . EOL;
152
					$file .= 'Port Race=' . $port->getRaceID() . EOL;
153
					if (!empty($port->getSellGoodIDs())) {
154
						$file .= 'Buys=' . implode(',', $port->getSellGoodIDs()) . EOL;
155
					}
156
					if (!empty($port->getBuyGoodIDs())) {
157
						$file .= 'Sells=' . implode(',', $port->getBuyGoodIDs()) . EOL;
158
					}
159
				}
160
				if ($sector->hasPlanet()) {
161
					$planetType = $sector->getPlanet()->getTypeID();
162
					$file .= 'Planet=' . $planetType . EOL;
163
				}
164
				if ($sector->hasLocation()) {
165
					$locationsString = 'Locations=';
166
					foreach ($sector->getLocations() as $location) {
167
						$locationsString .= inify($location->getName()) . ',';
168
					}
169
					$file .= substr($locationsString, 0, -1) . EOL;
170
				}
171
				if ($adminCreate === false && $sector->hasFriendlyForces($player)) {
172
					$forcesString = 'FriendlyForces=';
173
					foreach ($sector->getFriendlyForces($player) as $forces) {
174
						$forcesString .= inify($forces->getOwner()->getPlayerName()) . '=' . inify(Globals::getHardwareName(HARDWARE_MINE)) . '=' . $forces->getMines() . ';' . inify(Globals::getHardwareName(HARDWARE_COMBAT)) . '=' . $forces->getCDs() . ';' . inify(Globals::getHardwareName(HARDWARE_SCOUT)) . '=' . $forces->getSDs() . ',';
175
					}
176
					$file .= substr($forcesString, 0, -1) . EOL;
177
				}
178
			}
179
			SmrPort::clearCache();
180
			SmrForce::clearCache();
181
			SmrPlanet::clearCache();
182
			SmrSector::clearCache();
183
		}
184
185
		$size = strlen($file);
186
187
		header('Pragma: public');
188
		header('Expires: 0');
189
		header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
190
		header('Cache-Control: private', false);
191
		header('Content-Type: application/force-download');
192
		header('Content-Disposition: attachment; filename="' . $game->getName() . '.smr"');
193
		header('Content-Transfer-Encoding: binary');
194
		header('Content-Length: ' . $size);
195
196
		echo $file;
197
198
		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...
199
	}
200
201
}
202