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

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