I think uploading packs is more or less working. I nutted out a few bugs in a lot...
[rock.divinelegy.git] / Services / SimfileParser.php
1 <?php
2
3 namespace Services;
4
5 use Services\ISimfileParser;
6 use Exception;
7
8 class SimfileParser implements ISimfileParser
9 {
10
11 // 'light' => 'Novice',
12 // 'beginner' => 'Novice',
13 // 'easy' => 'Easy',
14 // 'medium' => 'Medium',
15 // 'hard' => 'Hard',
16 // 'challenge' => 'Expert',
17 // 'edit' => 'Edit'
18
19 private $_smFileLines;
20
21 public function parse($simfileData)
22 {
23 $this->_smFileLines = explode(";", $simfileData);
24 }
25
26 public function banner()
27 {
28 return $this->extractKey('BANNER') ?: null;
29 }
30
31 public function title()
32 {
33 $title = $this->extractKey('TITLE');
34 if(!$title) throw new Exception ('Invalid SM file. TITLE missing');
35
36 return $title;
37 }
38
39 public function artist()
40 {
41 $artist = $this->extractKey('ARTIST');
42 if(!$artist) throw new Exception ('Invalid SM file. ARTIST missing');
43
44 return new \Domain\VOs\StepMania\Artist($artist);
45 }
46
47 public function stops()
48 {
49 $stops = $this->extractKey('STOPS') ? 'Yes' : 'No';
50 if(!$stops) throw new Exception ('Invalid SM file. STOPS missing');
51
52 return $stops;
53 }
54
55 public function fgChanges()
56 {
57 $fgChanges = $this->extractKey('FGCHANGES') ? 'Yes' : 'No';
58 if(!$fgChanges) throw new Exception ('Invalid SM file. FGCHANGES missing');
59
60 return $fgChanges;
61 }
62
63 public function bpm()
64 {
65 $displayBpm = $this->extractKey('DISPLAYBPM');
66
67 if($displayBpm)
68 {
69 $bpmRange = explode(":",$displayBpm);
70 } else {
71 $bpms = $this->extractKey('BPMS');
72 $bpmRange = $this->parseBpms($bpms);
73 }
74
75 //I have nfi why I made the BPM VO high-low instead of low-high in the constructor but yolo
76 return new \Domain\VOs\StepMania\BPM($bpmRange[1], $bpmRange[0]);
77 }
78
79 public function bgChanges()
80 {
81 $bgChanges = $this->extractKey('BGCHANGES') ? 'Yes' : 'No';
82 if(!$bgChanges) throw new Exception ('Invalid SM file. BGCHANGES missing');
83
84 return $bgChanges;
85 }
86
87 public function bpmChanges()
88 {
89 $bpmChanges = $this->extractKey('BPMS') ? 'Yes' : 'No';
90 if(!$bpmChanges) throw new Exception ('Invalid SM file. BPMS missing');
91
92 return $bpmChanges;
93 }
94
95 public function subtitle()
96 {
97 $subtitle = $this->extractKey('SUBTITLE');
98 if(!$subtitle) throw new Exception ('Invalid SM file. SUBTITLE missing');
99
100 return $subtitle;
101 }
102
103 function steps()
104 {
105 if(empty($this->_smFileLines)) throw new Exception('SM file data not set.');
106 $allSteps = array();
107
108 foreach ($this->_smFileLines as $line)
109 {
110 $pos = strpos($line, '#NOTES:');
111 if ($pos !== false)
112 {
113 $noteData = trim(substr($line, $pos + 9));
114 $allSteps[] = $this->stepchartFromNoteData($noteData);
115 }
116 }
117
118 if(empty($allSteps)) throw new Exception('Invalid Sm file. NOTES missing');
119 return $allSteps;
120 }
121
122 private function stepchartFromNoteData($noteData)
123 {
124 $stepData = array_map('trim', explode(':', $noteData));
125 return new \Domain\VOs\StepMania\StepChart(
126 new \Domain\VOs\StepMania\DanceMode($stepData[0]),
127 new \Domain\VOs\StepMania\Difficulty($stepData[2]),
128 empty($stepData[1]) ? null : new \Domain\VOs\StepMania\StepArtist($stepData[1]),
129 $stepData[3]
130 );
131 }
132
133 private function extractKey($key)
134 {
135 if(empty($this->_smFileLines)) throw new Exception('SM file data not set.');
136
137 foreach ($this->_smFileLines as $line)
138 {
139 $pos = strpos($line, '#' . $key . ':');
140 if ($pos !== false) return trim(substr($line, $pos + strlen($key) + 2));
141 }
142 }
143
144 private function parseBpms($bpms)
145 {
146 $bpms = explode(",", $bpms);
147 $bpmRange = array('high' => null, 'low' => null);
148
149 foreach($bpms as $bpm)
150 {
151 $bpmMeasure = explode('=', $bpm);
152 $bpmValue = floatval($bpmMeasure[1]);
153
154 if(empty($bpmRange['low'])) $bpmRange['low'] = $bpmRange['high'] = $bpmValue;
155
156 $bpmRange['high'] = ($bpmValue > $bpmRange['high']) ? $bpmValue : $bpmRange['high'];
157 $bpmRange['low'] = ($bpmValue < $bpmRange['low']) ? $bpmValue : $bpmRange['low'];
158 }
159
160 return array($bpmRange['low'], $bpmRange['high']);
161 }
162 }