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 ( 5797ad...3faf69 )
by Dan
29s queued 24s
created

UploadSmrFileProcessor::build()   F

Complexity

Conditions 22
Paths 3904

Size

Total Lines 117
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 22
eloc 62
nc 3904
nop 1
dl 0
loc 117
rs 0
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Smr\Pages\Admin\UniGen;
4
5
use Smr\Page\AccountPageProcessor;
6
use Smr\TransactionType;
7
use SmrAccount;
8
use SmrGalaxy;
9
use SmrLocation;
10
use SmrPort;
11
use SmrSector;
12
13
class UploadSmrFileProcessor extends AccountPageProcessor {
14
15
	public function __construct(
16
		private readonly int $gameID
17
	) {}
18
19
	public function build(SmrAccount $account): never {
20
		if ($_FILES['smr_file']['error'] !== UPLOAD_ERR_OK) {
21
			create_error('Failed to upload SMR file!');
22
		}
23
24
		$ini_str = file_get_contents($_FILES['smr_file']['tmp_name']);
25
26
		// We only care about the sections after [Metadata], and the earlier
27
		// sections have invalid INI key characters (e.g. Creonti "Big Daddy", Salvene
28
		// Supply & Plunder). For this reason, we simply remove the offending sections
29
		// instead of trying to encode all the special characters: ?{}|&~![()^"
30
		//
31
		// NOTE: these special characters are allowed in the ini-values, but only if
32
		// we use the "raw" scanner. We need this because of the "Location=" values.
33
		$ini_substr = strstr($ini_str, '[Metadata]');
34
		if ($ini_substr === false) {
35
			create_error('Could not find [Metadata] section in SMR file');
36
		}
37
		$data = parse_ini_string($ini_substr, true, INI_SCANNER_RAW);
38
39
		$version = $data['Metadata']['FileVersion'];
40
		if ($version !== SMR_FILE_VERSION) {
41
			create_error('Uploaded v' . $version . ' is incompatible with server expecting v' . SMR_FILE_VERSION);
42
		}
43
44
		// Create the galaxies
45
		foreach ($data['Galaxies'] as $galID => $details) {
46
			[$width, $height, $type, $name, $maxForceTime] = explode(',', $details);
47
			$galaxy = SmrGalaxy::createGalaxy($this->gameID, $galID);
48
			$galaxy->setWidth(str2int($width));
0 ignored issues
show
Bug introduced by
The function str2int was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

48
			$galaxy->setWidth(/** @scrutinizer ignore-call */ str2int($width));
Loading history...
49
			$galaxy->setHeight(str2int($height));
50
			$galaxy->setGalaxyType($type);
51
			$galaxy->setName($name);
52
			$galaxy->setMaxForceTime(str2int($maxForceTime));
53
		}
54
		// Workaround for SmrGalaxy::getStartSector depending on all other galaxies
55
		SmrGalaxy::saveGalaxies();
56
		foreach (SmrGalaxy::getGameGalaxies($this->gameID, true) as $galaxy) {
57
			$galaxy->generateSectors();
58
		}
59
60
		// Populate the sectors
61
		foreach ($data as $key => $vals) {
62
			if (!preg_match('/^Sector=(\d+)$/', $key, $matches)) {
63
				continue;
64
			}
65
66
			$sectorID = str2int($matches[1]);
67
			$editSector = SmrSector::getSector($this->gameID, $sectorID);
68
69
			// Sector connections (we assume link sectors are correct)
70
			foreach (['Up', 'Down', 'Left', 'Right'] as $dir) {
71
				if (isset($vals[$dir])) {
72
					$editSector->enableLink($dir);
73
				} else {
74
					$editSector->disableLink($dir);
75
				}
76
			}
77
78
			// Ports
79
			if (isset($vals['Port Level'])) {
80
				$port = $editSector->createPort();
81
				$port->setRaceID(str2int($vals['Port Race']));
82
				$port->setLevel(str2int($vals['Port Level']));
83
				$port->setCreditsToDefault();
84
				// SMR file indicates the port action Buys/Sells,
85
				// but SmrPort::addPortGood uses the player action.
86
				if (isset($vals['Buys'])) {
87
					foreach (explode(',', $vals['Buys']) as $goodID) {
88
						$port->addPortGood(str2int($goodID), TransactionType::Sell);
89
					}
90
				}
91
				if (isset($vals['Sells'])) {
92
					foreach (explode(',', $vals['Sells']) as $goodID) {
93
						$port->addPortGood(str2int($goodID), TransactionType::Buy);
94
					}
95
				}
96
			}
97
98
			// Locations
99
			$allLocs = SmrLocation::getAllLocations($this->gameID);
100
			if (isset($vals['Locations'])) {
101
				$locNames = explode(',', $vals['Locations']);
102
				foreach ($locNames as $locName) {
103
					// Since we only know the location name, we must search for it
104
					$found = false;
105
					foreach ($allLocs as $loc) {
106
						if ($locName == inify($loc->getName())) {
107
							$editSector->addLocation($loc);
108
							$found = true;
109
							break;
110
						}
111
					}
112
					if (!$found) {
113
						create_error('Could not find location named: ' . $locName);
114
					}
115
				}
116
			}
117
118
			// Warps
119
			if (isset($vals['Warp'])) {
120
				$editSector->setWarp(SmrSector::getSector($this->gameID, str2int($vals['Warp'])));
121
			}
122
123
			// Planets
124
			if (isset($vals['Planet'])) {
125
				$editSector->createPlanet(str2int($vals['Planet']));
126
			}
127
		}
128
129
		// Save so that sector links and ports persist
130
		// (otherwise they are overwritten somewhere while forwarding)
131
		SmrSector::saveSectors();
132
		SmrPort::savePorts();
133
134
		$container = new EditGalaxy($this->gameID);
135
		$container->go();
136
	}
137
138
}
139