|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace eXpansion\Bundle\Maps\Plugins; |
|
4
|
|
|
|
|
5
|
|
|
use eXpansion\Bundle\Maps\Model\Map; |
|
6
|
|
|
use eXpansion\Bundle\Maps\Model\MapQuery; |
|
7
|
|
|
use eXpansion\Bundle\Maps\Model\Mxmap; |
|
8
|
|
|
use eXpansion\Bundle\Maps\Model\MxmapQuery; |
|
9
|
|
|
use eXpansion\Bundle\Maps\Services\JukeboxService; |
|
10
|
|
|
use eXpansion\Bundle\Maps\Structure\MxInfo; |
|
11
|
|
|
use eXpansion\Framework\AdminGroups\Helpers\AdminGroups; |
|
12
|
|
|
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpApplication; |
|
13
|
|
|
use eXpansion\Framework\Core\Helpers\ChatNotification; |
|
14
|
|
|
use eXpansion\Framework\Core\Helpers\Http; |
|
15
|
|
|
use eXpansion\Framework\Core\Helpers\Structures\HttpResult; |
|
16
|
|
|
use eXpansion\Framework\Core\Helpers\TMString; |
|
17
|
|
|
use eXpansion\Framework\Core\Services\Console; |
|
18
|
|
|
use eXpansion\Framework\Core\Storage\GameDataStorage; |
|
19
|
|
|
use Maniaplanet\DedicatedServer\Connection; |
|
20
|
|
|
use Maniaplanet\DedicatedServer\Structures\Map as DedicatedMap; |
|
21
|
|
|
use Propel\Runtime\Map\TableMap; |
|
22
|
|
|
|
|
23
|
|
|
class ManiaExchange implements ListenerInterfaceExpApplication |
|
24
|
|
|
{ |
|
25
|
|
|
|
|
26
|
|
|
const SITE_TM = "TM"; |
|
27
|
|
|
const SITE_SM = "SM"; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* @var Connection |
|
31
|
|
|
*/ |
|
32
|
|
|
private $connection; |
|
33
|
|
|
/** |
|
34
|
|
|
* @var ChatNotification |
|
35
|
|
|
*/ |
|
36
|
|
|
private $chatNotification; |
|
37
|
|
|
/** |
|
38
|
|
|
* @var Http |
|
39
|
|
|
*/ |
|
40
|
|
|
private $http; |
|
41
|
|
|
/** |
|
42
|
|
|
* @var AdminGroups |
|
43
|
|
|
*/ |
|
44
|
|
|
private $adminGroups; |
|
45
|
|
|
/** |
|
46
|
|
|
* @var GameDataStorage |
|
47
|
|
|
*/ |
|
48
|
|
|
private $gameDataStorage; |
|
49
|
|
|
/** |
|
50
|
|
|
* @var Console |
|
51
|
|
|
*/ |
|
52
|
|
|
private $console; |
|
53
|
|
|
/** |
|
54
|
|
|
* @var JukeboxService |
|
55
|
|
|
*/ |
|
56
|
|
|
private $jukebox; |
|
57
|
|
|
|
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* ManiaExchange constructor. |
|
61
|
|
|
* @param Connection $connection |
|
62
|
|
|
* @param ChatNotification $chatNotification |
|
63
|
|
|
* @param Http $http |
|
64
|
|
|
* @param AdminGroups $adminGroups |
|
65
|
|
|
* @param GameDataStorage $gameDataStorage |
|
66
|
|
|
* @param Console $console |
|
67
|
|
|
* @param JukeboxService $jukebox |
|
68
|
|
|
*/ |
|
69
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
|
|
70
|
|
|
Connection $connection, |
|
71
|
|
|
ChatNotification $chatNotification, |
|
72
|
|
|
Http $http, |
|
73
|
|
|
AdminGroups $adminGroups, |
|
74
|
|
|
GameDataStorage $gameDataStorage, |
|
75
|
|
|
Console $console, |
|
76
|
|
|
JukeboxService $jukebox |
|
77
|
|
|
) { |
|
78
|
|
|
$this->connection = $connection; |
|
79
|
|
|
$this->chatNotification = $chatNotification; |
|
80
|
|
|
$this->http = $http; |
|
81
|
|
|
$this->adminGroups = $adminGroups; |
|
82
|
|
|
$this->gameDataStorage = $gameDataStorage; |
|
83
|
|
|
$this->console = $console; |
|
84
|
|
|
$this->jukebox = $jukebox; |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
/** |
|
88
|
|
|
* @param string $login |
|
89
|
|
|
* @param integer $id |
|
90
|
|
|
* @param string $mxsite "TM" or "SM" |
|
91
|
|
|
*/ |
|
92
|
|
|
public function addMap($login, $id, $mxsite) |
|
93
|
|
|
{ |
|
94
|
|
|
|
|
95
|
|
|
if (!$this->adminGroups->hasPermission($login, "maps.add")) { |
|
96
|
|
|
$this->chatNotification->sendMessage('expansion_mx.chat.nopermission', $login); |
|
97
|
|
|
|
|
98
|
|
|
return; |
|
99
|
|
|
} |
|
100
|
|
|
$options = [ |
|
101
|
|
|
CURLOPT_HTTPHEADER => [ |
|
102
|
|
|
"Content-Type" => "application/json", |
|
103
|
|
|
"X-ManiaPlanet-ServerLogin" => $this->gameDataStorage->getSystemInfo()->serverLogin, |
|
104
|
|
|
], |
|
105
|
|
|
]; |
|
106
|
|
|
|
|
107
|
|
|
if (!$mxsite) { |
|
108
|
|
|
$mxsite = "TM"; |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
$group = $this->adminGroups->getLoginUserGroups($login); |
|
112
|
|
|
|
|
113
|
|
|
$this->chatNotification->sendMessage( |
|
114
|
|
|
'expansion_mx.chat.start', |
|
115
|
|
|
$group, |
|
116
|
|
|
["%id%" => $id, "%site%" => $mxsite] |
|
117
|
|
|
); |
|
118
|
|
|
|
|
119
|
|
|
$this->http->get("https://api.mania-exchange.com/".strtolower($mxsite)."/maps?ids=".$id, |
|
120
|
|
|
[$this, 'callbackAddMap1'], |
|
121
|
|
|
['login' => $login, 'site' => $mxsite, 'mxId' => $id], $options); |
|
122
|
|
|
|
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
|
|
126
|
|
|
public function callbackAddMap1(HttpResult $result) |
|
127
|
|
|
{ |
|
128
|
|
|
$additionalData = $result->getAdditionalData(); |
|
129
|
|
|
$group = $this->adminGroups->getLoginUserGroups($additionalData['login']); |
|
130
|
|
|
|
|
131
|
|
|
$json = json_decode($result->getResponse(), true); |
|
132
|
|
|
|
|
133
|
|
|
if (isset($json['StatusCode'])) { |
|
134
|
|
|
$this->chatNotification->sendMessage( |
|
135
|
|
|
'expansion_mx.chat.apierror', |
|
136
|
|
|
$group, |
|
137
|
|
|
["%status%" => $json['StatusCode'], "%message%" => $json['Message']] |
|
138
|
|
|
); |
|
139
|
|
|
|
|
140
|
|
|
return; |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
$mxInfo = new MxInfo($json[0]); |
|
144
|
|
|
$additionalData['mxInfo'] = $mxInfo; |
|
145
|
|
|
|
|
146
|
|
|
if (!$result->hasError()) { |
|
147
|
|
|
$options = [ |
|
148
|
|
|
CURLOPT_FOLLOWLOCATION => false, |
|
149
|
|
|
CURLOPT_HTTPHEADER => [ |
|
150
|
|
|
"Content-Type" => "application/json", |
|
151
|
|
|
"X-ManiaPlanet-ServerLogin" => $this->gameDataStorage->getSystemInfo()->serverLogin, |
|
152
|
|
|
] |
|
153
|
|
|
]; |
|
154
|
|
|
|
|
155
|
|
|
$this->http->get("https://".strtolower($additionalData['site']). |
|
156
|
|
|
".mania-exchange.com/tracks/download/".$additionalData['mxId'], |
|
157
|
|
|
[$this, 'callbackAddMap2'], |
|
158
|
|
|
$additionalData, $options); |
|
159
|
|
|
} else { |
|
160
|
|
|
$this->chatNotification->sendMessage( |
|
161
|
|
|
'expansion_mx.chat.httperror', |
|
162
|
|
|
$group, |
|
163
|
|
|
["%status%" => $result->getHttpCode(), "%message%" => $result->getError()] |
|
164
|
|
|
); |
|
165
|
|
|
} |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
public function callbackAddMap2(HttpResult $result) |
|
169
|
|
|
{ |
|
170
|
|
|
$data = $result->getAdditionalData(); |
|
171
|
|
|
$group = $this->adminGroups->getLoginUserGroups($data['login']); |
|
172
|
|
|
|
|
173
|
|
|
if ($result->hasError()) { |
|
174
|
|
|
|
|
175
|
|
|
if ($result->getHttpCode() == 302) { |
|
176
|
|
|
$this->chatNotification->sendMessage( |
|
177
|
|
|
'expansion_mx.chat.decline', |
|
178
|
|
|
$group, |
|
179
|
|
|
[] |
|
180
|
|
|
); |
|
181
|
|
|
return; |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
$this->chatNotification->sendMessage( |
|
185
|
|
|
'expansion_mx.chat.httperror', |
|
186
|
|
|
$group, |
|
187
|
|
|
["%status%" => $result->getHttpCode(), "%message%" => $result->getError()] |
|
188
|
|
|
); |
|
189
|
|
|
|
|
190
|
|
|
return; |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
/** @var MxInfo $info */ |
|
194
|
|
|
$info = $data['mxInfo']; |
|
195
|
|
|
|
|
196
|
|
|
$authorName = $this->cleanString($info->username); |
|
197
|
|
|
$mapName = $this->cleanString( |
|
198
|
|
|
trim( |
|
199
|
|
|
mb_convert_encoding( |
|
200
|
|
|
substr(TMString::trimStyles($info->gbxMapName), 0, 20), |
|
201
|
|
|
"7bit", |
|
202
|
|
|
"UTF-8" |
|
203
|
|
|
) |
|
204
|
|
|
) |
|
205
|
|
|
); |
|
206
|
|
|
|
|
207
|
|
|
$filename = $data['mxId']."-".$authorName."-".$mapName.".Map.Gbx"; |
|
208
|
|
|
|
|
209
|
|
|
try { |
|
210
|
|
|
// @todo add file abstaction layer, when it gets finished |
|
211
|
|
|
$folder = $this->gameDataStorage->getMapFolder(); |
|
212
|
|
|
|
|
213
|
|
|
if (!is_dir($folder.DIRECTORY_SEPARATOR.$info->titlePack)) { |
|
214
|
|
|
try { |
|
215
|
|
|
mkdir($folder.DIRECTORY_SEPARATOR.$info->titlePack); |
|
216
|
|
|
} catch (\Exception $ex) { |
|
217
|
|
|
$this->chatNotification->sendMessage( |
|
218
|
|
|
'expansion_mx.chat.exception', |
|
219
|
|
|
$group, ["%message%" => $ex->getMessage()] |
|
220
|
|
|
); |
|
221
|
|
|
$this->console->writeln('$f00Error while adding map'.$ex->getMessage()); |
|
222
|
|
|
} |
|
223
|
|
|
} |
|
224
|
|
|
$file = ($folder.DIRECTORY_SEPARATOR.$info->titlePack.DIRECTORY_SEPARATOR.$filename); |
|
225
|
|
|
file_put_contents($file, $result->getResponse()); |
|
226
|
|
|
|
|
227
|
|
|
// $this->connection->writeFile($filename, $result->getResponse()); |
|
|
|
|
|
|
228
|
|
|
|
|
229
|
|
|
if (!$this->connection->checkMapForCurrentServerParams($info->titlePack.DIRECTORY_SEPARATOR.$filename)) { |
|
230
|
|
|
$this->chatNotification->sendMessage("expansion_mx.chat.fail"); |
|
231
|
|
|
|
|
232
|
|
|
return; |
|
233
|
|
|
} |
|
234
|
|
|
|
|
235
|
|
|
$map = $this->connection->getMapInfo($info->titlePack.DIRECTORY_SEPARATOR.$filename); |
|
236
|
|
|
$this->connection->addMap($map->fileName); |
|
237
|
|
|
|
|
238
|
|
|
$this->jukebox->addMap($map, $data['login']); |
|
239
|
|
|
$this->chatNotification->sendMessage( |
|
240
|
|
|
'expansion_mx.chat.success', |
|
241
|
|
|
null, |
|
242
|
|
|
[ |
|
243
|
|
|
"%mxid%" => $data['mxId'], |
|
244
|
|
|
"%mapauthor%" => $map->author, |
|
245
|
|
|
"%mapname%" => TMString::trimControls($map->name), |
|
246
|
|
|
] |
|
247
|
|
|
); |
|
248
|
|
|
|
|
249
|
|
|
$this->persistMapData($map, $info); |
|
250
|
|
|
|
|
251
|
|
|
} catch (\Exception $e) { |
|
252
|
|
|
$this->chatNotification->sendMessage( |
|
253
|
|
|
'expansion_mx.chat.dedicatedexception', |
|
254
|
|
|
$group, ["%message%" => $e->getMessage()] |
|
255
|
|
|
); |
|
256
|
|
|
} |
|
257
|
|
|
} |
|
258
|
|
|
|
|
259
|
|
|
/** |
|
260
|
|
|
* @param DedicatedMap $map |
|
261
|
|
|
* @param MxInfo $mxInfo |
|
262
|
|
|
* @throws \Propel\Runtime\Exception\PropelException |
|
263
|
|
|
*/ |
|
264
|
|
|
protected function persistMapData($map, $mxInfo) |
|
265
|
|
|
{ |
|
266
|
|
|
|
|
267
|
|
|
$mapquery = new MapQuery(); |
|
268
|
|
|
$dbMap = $mapquery->findOneByMapuid($map->uId); |
|
269
|
|
|
|
|
270
|
|
|
if ($dbMap) { |
|
271
|
|
|
$dbMap->fromArray($this->convertMap($map), TableMap::TYPE_FIELDNAME); |
|
272
|
|
|
} else { |
|
273
|
|
|
$dbMap = new Map(); |
|
274
|
|
|
$dbMap->fromArray($this->convertMap($map), TableMap::TYPE_FIELDNAME); |
|
275
|
|
|
} |
|
276
|
|
|
|
|
277
|
|
|
$mxquery = new MxmapQuery(); |
|
278
|
|
|
$mxMap = $mxquery->findOneByTrackuid($map->uId); |
|
279
|
|
|
|
|
280
|
|
|
print_r($mxInfo->toArray()); |
|
281
|
|
|
|
|
282
|
|
|
if ($mxMap) { |
|
283
|
|
|
$mxMap->fromArray($mxInfo->toArray(), TableMap::TYPE_FIELDNAME); |
|
284
|
|
|
} else { |
|
285
|
|
|
$mxMap = new Mxmap(); |
|
286
|
|
|
$mxMap->fromArray($mxInfo->toArray(), TableMap::TYPE_FIELDNAME); |
|
287
|
|
|
} |
|
288
|
|
|
$dbMap->addMxmap($mxMap); |
|
289
|
|
|
$dbMap->save(); |
|
290
|
|
|
$mxMap->save(); |
|
291
|
|
|
} |
|
292
|
|
|
|
|
293
|
|
|
/** |
|
294
|
|
|
* @param DedicatedMap $map |
|
295
|
|
|
* @return array |
|
296
|
|
|
*/ |
|
297
|
|
|
private function convertMap($map) |
|
298
|
|
|
{ |
|
299
|
|
|
$outMap = (array)$map; |
|
300
|
|
|
$outMap["mapUid"] = $map->uId; |
|
301
|
|
|
|
|
302
|
|
|
return $outMap; |
|
303
|
|
|
|
|
304
|
|
|
} |
|
305
|
|
|
|
|
306
|
|
|
/** |
|
307
|
|
|
* Remove special characters from map name |
|
308
|
|
|
* |
|
309
|
|
|
* @param $string |
|
310
|
|
|
* @return mixed |
|
311
|
|
|
*/ |
|
312
|
|
|
protected function cleanString($string) |
|
313
|
|
|
{ |
|
314
|
|
|
return str_replace(array("/", "\\", ":", ".", "?", "*", '"', "|", "<", ">", "'"), "", $string); |
|
315
|
|
|
} |
|
316
|
|
|
|
|
317
|
|
|
|
|
318
|
|
|
/** |
|
319
|
|
|
* called at eXpansion init |
|
320
|
|
|
* |
|
321
|
|
|
* @return void |
|
322
|
|
|
*/ |
|
323
|
|
|
public function onApplicationInit() |
|
324
|
|
|
{ |
|
325
|
|
|
// TODO: Implement onApplicationInit() method. |
|
326
|
|
|
} |
|
327
|
|
|
|
|
328
|
|
|
/** |
|
329
|
|
|
* called when init is done and callbacks are enabled |
|
330
|
|
|
* |
|
331
|
|
|
* @return void |
|
332
|
|
|
*/ |
|
333
|
|
|
public function onApplicationReady() |
|
334
|
|
|
{ |
|
335
|
|
|
|
|
336
|
|
|
} |
|
337
|
|
|
|
|
338
|
|
|
/** |
|
339
|
|
|
* called when requesting application stop |
|
340
|
|
|
* |
|
341
|
|
|
* @return void |
|
342
|
|
|
*/ |
|
343
|
|
|
public function onApplicationStop() |
|
344
|
|
|
{ |
|
345
|
|
|
// TODO: Implement onApplicationStop() method. |
|
346
|
|
|
} |
|
347
|
|
|
} |
|
348
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.