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

SectorsFile   A
last analyzed

Complexity

Total Complexity 40

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 120
dl 0
loc 182
rs 9.2
c 1
b 0
f 0
wmc 40

1 Method

Rating   Name   Duplication   Size   Complexity  
F create() 0 180 40

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