Got old Windows datapack and monsters do not load on Linux? [on Linux
Downloaded map with
Find all bugged names and fixes for them.
Code suggests existing file path with same lowercase file path as in
Online version: OTS.ME - Monsters & Spawn files checker (https://ots.me/monsters-fixer/)
It generates reports like this:
Sorry for ugly variables and 20
PHP code:
achad.xml
!= Achad.xml
]Downloaded map with
spawns.xml
, but some monster are not in your datapack?Find all bugged names and fixes for them.
Code suggests existing file path with same lowercase file path as in
monsters.xml
. If there is none, it searches in all folders for file with same lowercase name.Online version: OTS.ME - Monsters & Spawn files checker (https://ots.me/monsters-fixer/)
It generates reports like this:
Sorry for ugly variables and 20
for
/if
. I made it few years ago to fix one datapack. I did not plan to release it, but there are still people that try to mix datapacks and get million errors on server startup.PHP code:
PHP:
<?php
function colorChanges($orginalString, $changedString)
{
$original = str_split($orginalString);
$changed = str_split($changedString);
$offset = 1;
$ret = '';
while($offset <= count($original) && $offset <= count($changed)) {
$o = $original[count($original)-$offset];
$c = $changed[count($changed)-$offset];
if($o == $c)
$ret = $o . $ret;
else
$ret = '<span class="diff">' . $c . '</span>' . $ret;
$offset++;
}
if (count($original) < count($changed)) {
while($offset <= count($changed)) {
$c = $changed[count($changed)-$offset];
$ret = '<span class="diff">' . $c . '</span>' . $ret;
$offset++;
}
}
return $ret;
}
$monstersErrorsList = array();
$spawnsErrorsList = array();
if(isset($_FILES['monsters_file']['tmp_name']))
{
try {
$monstersPaths = array();
$monstersZIP = new ZipArchive();
if($monstersZIP->open($_FILES['monsters_file']['tmp_name']))
{
// create list of .xml file paths in .zip
for($i = 0; $i < $monstersZIP->numFiles; $i++) {
$monsterFilePath = $monstersZIP->getNameIndex($i);
if(substr($monsterFilePath, -4, 4) == '.xml'){
$monstersPaths[$monsterFilePath] = $monsterFilePath;
}
}
// remove 'monster/' from file paths
$removeMonsterDir = true;
foreach($monstersPaths as $monsterPath)
{
if(substr($monsterPath, 0, 8) != 'monster/') {
$removeMonsterDir = false;
break;
}
}
if($removeMonsterDir)
{
$monstersFilePath = 'monster/monsters.xml';
foreach($monstersPaths as $monsterPath)
{
unset($monstersPaths[$monsterPath]);
$newMonsterPath = substr($monsterPath, 8, strlen($monsterPath) -8);
$monstersPaths[$newMonsterPath] = $newMonsterPath;
}
} else {
$monstersFilePath = 'monsters.xml';
}
ksort($monstersPaths);
$monstersPathsLowercase = [];
$monstersFilesLowercase = [];
foreach($monstersPaths as $value) {
$lowercasePath = strtolower($value);
$lowercaseFileName = array_reverse(explode('/', str_replace('\\', '/', strtolower($value))))[0];
$monstersPathsLowercase[$lowercasePath] = [
'path' => $value,
'lowercasePath' => $lowercasePath,
'lowercaseFileName' => $lowercaseFileName,
];
$monstersFilesLowercase[$lowercaseFileName] = [
'path' => $value,
'lowercasePath' => $lowercasePath,
'lowercaseFileName' => $lowercaseFileName,
];
}
}
else {
throw new RuntimeException('Failed to open monsters .zip file');
}
$monstersXMLfileContent = $monstersZIP->getFromName($monstersFilePath);
$monstersXML = new DOMDocument();
$monstersXML->loadXML($monstersXMLfileContent);
$monstersList = array();
$monstersElements = $monstersXML->getElementsByTagName('monster');
for($m = 0; $m < $monstersElements->length; $m++)
{
if($monstersElements->item($m)->hasAttributes() && $monstersElements->item($m)->attributes->getNamedItem('name') && $monstersElements->item($m)->attributes->getNamedItem('file'))
$monstersList[$monstersElements->item($m)->attributes->getNamedItem('name')->nodeValue] = $monstersElements->item($m)->attributes->getNamedItem('file')->nodeValue;
}
$i = 0;
$monsterPathId = array_values($monstersPaths);
foreach($monstersList as $name => $file)
{
if(!isset($monstersPaths[$file]))
{
$fileName = array_reverse(explode('/', str_replace('\\', '/', strtolower($file))))[0];
if(isset($monstersPathsLowercase[strtolower($file)])) { // same lowercase path
$result = [
'name' => $name,
'now' => colorChanges($monstersPathsLowercase[strtolower($file)]['path'], $file),
'proposition' => colorChanges($file, $monstersPathsLowercase[strtolower($file)]['path'])
];
} elseif(isset($monstersFilesLowercase[$fileName])) { // same lowercase file name
$result = [
'name' => $name,
'now' => colorChanges($monstersFilesLowercase[$fileName]['path'], $file),
'proposition' => colorChanges($file, $monstersFilesLowercase[$fileName]['path'])
];
} else {
$result = [
'name' => $name,
'now' => $file,
'proposition' => 'NONE :('
];
}
$monstersErrorsList[] = $result;
}
$i++;
}
if(!empty($_FILES['spawns_file']['tmp_name']))
{
$spawnsXML = new DOMDocument();
$spawnsXML->load($_FILES['spawns_file']['tmp_name']);
$spawnMonstersList = array();
$spawnsMonsters = $spawnsXML->getElementsByTagName('monster');
for($s = 0; $s < $spawnsMonsters->length; $s++) {
if($spawnsMonsters->item($s)->hasAttributes() && $spawnsMonsters->item($s)->attributes->getNamedItem('name')) {
$monsterName = $spawnsMonsters->item($s)->attributes->getNamedItem('name')->nodeValue;
$spawnMonstersList[] = $monsterName;
}
}
foreach($spawnMonstersList as $spawnMonsterName)
if(!isset($monstersList[$spawnMonsterName])) {
$result = [
'name' => $name,
'now' => $name,
'proposition' => 'NONE :('
];
// try to find monster in monster.xml with same lowercase name
foreach($monstersList as $name => $file) {
if (strtolower($name) == strtolower($spawnMonsterName)) {
$result = [
'name' => $name,
'now' => colorChanges($spawnMonsterName, $name),
'proposition' => colorChanges($name, $spawnMonsterName)
];
break;
}
}
$spawnsErrorsList[] = $result;
}
}
} catch(Exception $e) {
echo '<div style="font-size: 20px;color: red">Errors while loading files: ' . $e->getMessage() . '</div>';
} catch(ValueError $e) {
echo '<div style="font-size: 20px;color: red">Errors while loading ZIP archive. Probably you uploaded wrong file.</div>';
}
}
echo '<html><head><title>OTS.ME - Monsters & Spawn files checker</title></head><body>';
echo '<style>
table {
text-align: left;
border-collapse: collapse;
}
table td, table th {
border: 1px solid #AAAAAA;
padding: 5px 4px;
font-size: 16px;
}
.diff {
font-size: 18px;
color: blue;
}
</style>';
echo '<h3>ZIP your <i>data/monster</i> directory and upload to check <i>monster.xml</i> and file names compatibility</h3>';
echo '<h3>You can also upload your <i>data/world/spawns.xml</i> to check, if all monsters from map are in <i>monster.xml</i></h3>';
echo '<form action="index.php" method="post" enctype="multipart/form-data">
Monsters ZIP file: <input type="file" name="monsters_file" /> [monster.zip]<br />
Spawns file: <input type="file" name="spawns_file" /> [..-spawn.xml]<br />
<input type="submit" value="Send & verify" />
</form>';
echo '<div style="font-size: 20px;color: red">Wrong paths to monsters in monsters.xml:</div>';
echo '<table style="font-size:16px"><tr><th>Name</th><th>Now</th><th>Proposition</th></tr>';
foreach($monstersErrorsList as $errorData) {
echo '<tr><td>' . $errorData['name'] . '</td><td>' . $errorData['now'] . '</td><td>' . $errorData['proposition'] . '</td></tr>';
}
echo '</table>';
echo '<div style="font-size: 20px;color: red">Monsters from spawns file that can\'t be loaded:</div>';
echo '<table><tr><th>Name</th><th>Now</th><th>Proposition</th></tr>';
foreach($spawnsErrorsList as $errorData) {
echo '<tr><td>' . $errorData['name'] . '</td><td>' . $errorData['now'] . '</td><td>' . $errorData['proposition'] . '</td></tr>';
echo '</table>';
}[/php]