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   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 63
dl 0
loc 123
rs 10
c 1
b 0
f 0
wmc 23

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
F build() 0 117 22
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