Esempio n. 1
0
function simpleImg()
{
    // prefer manually converted PNG files (as the imagecreatefromblp-script has issues with some formats)
    // see: https://github.com/Kanma/BLPConverter
    $loadImageFile = function ($path) {
        $result = null;
        if (in_array(mb_substr($path, -4, 4), ['.png', '.blp', '.BLP', '.PNG'])) {
            $path = mb_substr($path, 0, mb_strlen($path) - 4);
        }
        $file = $path . '.png';
        if (CLISetup::fileExists($file)) {
            CLISetup::log('manually converted png file present for ' . $path . '.', CLISetup::LOG_INFO);
            $result = imagecreatefrompng($file);
        }
        if (!$result) {
            $file = $path . '.blp';
            if (CLISetup::fileExists($file)) {
                $result = imagecreatefromblp($file);
            }
        }
        return $result;
    };
    if (isset(FileGen::$cliOpts['help'])) {
        echo "\n";
        echo "available options for subScript 'simpleImg':\n";
        echo " --icons          (generates square icons that are used for basicly everything)\n";
        echo " --glyphs         (decorative tidbit displayed on Infobox for Glyph Spells)\n";
        echo " --pagetexts      (imagery contained in PageTexts on readable GameObjects or Items)\n";
        echo " --loadingscreens (loading screens (not used, skipped by default))\n";
        return true;
    }
    $locStr = null;
    $groups = [];
    $dbcPath = CLISetup::$srcDir . '%sDBFilesClient/';
    $imgPath = CLISetup::$srcDir . '%sInterface/';
    $destDir = 'static/images/wow/';
    $success = true;
    $iconDirs = array(['icons/large/', 'jpg', 0, 56, 4], ['icons/medium/', 'jpg', 0, 36, 4], ['icons/small/', 'jpg', 0, 18, 4], ['icons/tiny/', 'gif', 0, 15, 4]);
    $calendarDirs = array(['icons/large/', 'jpg', 90, 56, 4], ['icons/medium/', 'jpg', 90, 36, 4], ['icons/small/', 'jpg', 90, 18, 4], ['icons/tiny/', 'gif', 90, 15, 4]);
    $loadScreenDirs = array(['loadingscreens/large/', 'jpg', 0, 1024, 0], ['loadingscreens/medium/', 'jpg', 0, 488, 0], ['loadingscreens/original/', 'png', 0, 0, 0], ['loadingscreens/small/', 'jpg', 0, 244, 0]);
    $paths = array(0 => ['Icons/', $iconDirs, '/*.[bB][lL][pP]', true, 0], 1 => ['Spellbook/', [['Interface/Spellbook/', 'png', 0, 0, 0]], '/UI-Glyph-Rune*.blp', true, 0], 2 => ['PaperDoll/', array_slice($iconDirs, 0, 3), '/UI-{Backpack,PaperDoll}-*.blp', true, 0], 3 => ['GLUES/CHARACTERCREATE/UI-CharacterCreate-Races.blp', $iconDirs, '', true, 64], 4 => ['GLUES/CHARACTERCREATE/UI-CharacterCreate-CLASSES.blp', $iconDirs, '', true, 64], 5 => ['GLUES/CHARACTERCREATE/UI-CharacterCreate-Factions.blp', $iconDirs, '', true, 64], 7 => ['FlavorImages/', [['Interface/FlavorImages/', 'png', 0, 0, 0]], '/*.[bB][lL][pP]', false, 0], 8 => ['Pictures/', [['Interface/Pictures/', 'png', 0, 0, 0]], '/*.[bB][lL][pP]', false, 0], 9 => ['PvPRankBadges/', [['Interface/PvPRankBadges/', 'png', 0, 0, 0]], '/*.[bB][lL][pP]', false, 0], 10 => ['Calendar/Holidays/', $calendarDirs, '/*{rt,a,y,h,s}.[bB][lL][pP]', true, 0], 11 => ['GLUES/LOADINGSCREENS/', $loadScreenDirs, '/[lL][oO]*.[bB][lL][pP]', false, 0]);
    // textures are composed of 64x64 icons
    // numeric indexed arrays mimick the position on the texture
    $cuNames = array(2 => array('ui-paperdoll-slot-chest' => 'inventoryslot_chest', 'ui-backpack-emptyslot' => 'inventoryslot_empty', 'ui-paperdoll-slot-feet' => 'inventoryslot_feet', 'ui-paperdoll-slot-finger' => 'inventoryslot_finger', 'ui-paperdoll-slot-hands' => 'inventoryslot_hands', 'ui-paperdoll-slot-head' => 'inventoryslot_head', 'ui-paperdoll-slot-legs' => 'inventoryslot_legs', 'ui-paperdoll-slot-mainhand' => 'inventoryslot_mainhand', 'ui-paperdoll-slot-neck' => 'inventoryslot_neck', 'ui-paperdoll-slot-secondaryhand' => 'inventoryslot_offhand', 'ui-paperdoll-slot-ranged' => 'inventoryslot_ranged', 'ui-paperdoll-slot-relic' => 'inventoryslot_relic', 'ui-paperdoll-slot-shirt' => 'inventoryslot_shirt', 'ui-paperdoll-slot-shoulder' => 'inventoryslot_shoulder', 'ui-paperdoll-slot-tabard' => 'inventoryslot_tabard', 'ui-paperdoll-slot-trinket' => 'inventoryslot_trinket', 'ui-paperdoll-slot-waist' => 'inventoryslot_waist', 'ui-paperdoll-slot-wrists' => 'inventoryslot_wrists'), 3 => array(['race_human_male', 'race_dwarf_male', 'race_gnome_male', 'race_nightelf_male', 'race_draenei_male'], ['race_tauren_male', 'race_scourge_male', 'race_troll_male', 'race_orc_male', 'race_bloodelf_male'], ['race_human_female', 'race_dwarf_female', 'race_gnome_female', 'race_nightelf_female', 'race_draenei_female'], ['race_tauren_female', 'race_scourge_female', 'race_troll_female', 'race_orc_female', 'race_bloodelf_female']), 4 => array(['class_warrior', 'class_mage', 'class_rogue', 'class_druid'], ['class_hunter', 'class_shaman', 'class_priest', 'class_warlock'], ['class_paladin', 'class_deathknight']), 5 => array(['faction_alliance', 'faction_horde']), 6 => array([], [null, 'quest_start', 'quest_end', 'quest_start_daily', 'quest_end_daily']), 10 => array('calendar_winterveilstart' => 'calendar_winterveilstart', 'calendar_noblegardenstart' => 'calendar_noblegardenstart', 'calendar_childrensweekstart' => 'calendar_childrensweekstart', 'calendar_fishingextravaganza' => 'calendar_fishingextravaganzastart', 'calendar_harvestfestivalstart' => 'calendar_harvestfestivalstart', 'calendar_hallowsendstart' => 'calendar_hallowsendstart', 'calendar_lunarfestivalstart' => 'calendar_lunarfestivalstart', 'calendar_loveintheairstart' => 'calendar_loveintheairstart', 'calendar_midsummerstart' => 'calendar_midsummerstart', 'calendar_brewfeststart' => 'calendar_brewfeststart', 'calendar_darkmoonfaireelwynnstart' => 'calendar_darkmoonfaireelwynnstart', 'calendar_darkmoonfairemulgorestart' => 'calendar_darkmoonfairemulgorestart', 'calendar_darkmoonfaireterokkarstart' => 'calendar_darkmoonfaireterokkarstart', 'calendar_piratesday' => 'calendar_piratesdaystart', 'calendar_wotlklaunch' => 'calendar_wotlklaunchstart', 'calendar_dayofthedeadstart' => 'calendar_dayofthedeadstart', 'calendar_fireworks' => 'calendar_fireworksstart'));
    $writeImage = function ($name, $ext, $src, $srcDims, $destDims, $done) {
        $ok = false;
        $dest = imagecreatetruecolor($destDims['w'], $destDims['h']);
        imagesavealpha($dest, true);
        if ($ext == 'png') {
            imagealphablending($dest, false);
        }
        imagecopyresampled($dest, $src, $destDims['x'], $destDims['x'], $srcDims['x'], $srcDims['y'], $destDims['w'], $destDims['h'], $srcDims['w'], $srcDims['h']);
        switch ($ext) {
            case 'jpg':
                $ok = imagejpeg($dest, $name . '.' . $ext, 85);
                break;
            case 'gif':
                $ok = imagegif($dest, $name . '.' . $ext);
                break;
            case 'png':
                $ok = imagepng($dest, $name . '.' . $ext);
                break;
            default:
                CLISetup::log($done . ' - unsupported file fromat: ' . $ext, CLISetup::LOG_WARN);
        }
        imagedestroy($dest);
        if ($ok) {
            chmod($name . '.' . $ext, Util::FILE_ACCESS);
            CLISetup::log($done . ' - image ' . $name . '.' . $ext . ' written', CLISetup::LOG_OK);
        } else {
            CLISetup::log($done . ' - could not create image ' . $name . '.' . $ext, CLISetup::LOG_ERROR);
        }
        return $ok;
    };
    $checkSourceDirs = function ($sub, &$missing = []) use($imgPath, $dbcPath, $paths) {
        $hasMissing = false;
        foreach (array_column($paths, 0) as $subDir) {
            $p = sprintf($imgPath, $sub) . $subDir;
            if (!CLISetup::fileExists($p)) {
                $hasMissing = true;
                $missing[] = $p;
            }
        }
        $p = sprintf($dbcPath, $sub);
        if (!CLISetup::fileExists($p)) {
            $hasMissing = true;
            $missing[] = $p;
        }
        return !$hasMissing;
    };
    if (isset(FileGen::$cliOpts['icons'])) {
        array_push($groups, 0, 2, 3, 4, 5, 10);
    }
    if (isset(FileGen::$cliOpts['glyphs'])) {
        $groups[] = 1;
    }
    if (isset(FileGen::$cliOpts['pagetexts'])) {
        array_push($groups, 7, 8, 9);
    }
    if (isset(FileGen::$cliOpts['loadingscreens'])) {
        $groups[] = 11;
    }
    // filter by pasaed options
    if (!$groups) {
        // by default do not generate loadingscreens
        unset($paths[11]);
    } else {
        foreach (array_keys($paths) as $k) {
            if (!in_array($k, $groups)) {
                unset($paths[$k]);
            }
        }
    }
    foreach (CLISetup::$expectedPaths as $xp => $__) {
        if ($xp) {
            // if in subDir add trailing slash
            $xp .= '/';
        }
        if ($checkSourceDirs($xp, $missing)) {
            $locStr = $xp;
            break;
        }
    }
    // if no subdir had sufficient data, diaf
    if ($locStr === null) {
        CLISetup::log('one or more required directories are missing:', CLISetup::LOG_ERROR);
        foreach ($missing as $m) {
            CLISetup::log(' - ' . $m, CLISetup::LOG_ERROR);
        }
        return;
    }
    // init directories
    foreach (array_column($paths, 1) as $subDirs) {
        foreach ($subDirs as $sd) {
            if (!CLISetup::writeDir($destDir . $sd[0])) {
                $success = false;
            }
        }
    }
    // ok, departure from std::procedure here
    // scan ItemDisplayInfo.dbc and SpellIcon.dbc for expected images and save them to an array
    // load all icon paths into another array and xor these two
    // excess entries for the directory are fine, excess entries for the dbc's are not
    $dbcEntries = [];
    if (isset($paths[0]) || isset($paths[1])) {
        if (isset($paths[0]) && !isset($paths[1])) {
            $siRows = DB::Aowow()->selectCol('SELECT iconPath FROM dbc_spellicon WHERE iconPath NOT LIKE "%glyph-rune%"');
        } else {
            if (!isset($paths[0]) && isset($paths[1])) {
                $siRows = DB::Aowow()->selectCol('SELECT iconPath FROM dbc_spellicon WHERE iconPath LIKE "%glyph-rune%"');
            } else {
                $siRows = DB::Aowow()->selectCol('SELECT iconPath FROM dbc_spellicon');
            }
        }
        foreach ($siRows as $icon) {
            $dbcEntries[] = strtolower(sprintf('setup/mpqdata/%s', $locStr) . strtr($icon, ['\\' => '/']) . '.blp');
        }
    }
    if (isset($paths[0])) {
        $itemIcons = DB::Aowow()->selectCol('SELECT inventoryIcon1 FROM dbc_itemdisplayinfo WHERE inventoryIcon1 <> ""');
        foreach ($itemIcons as $icon) {
            $dbcEntries[] = strtolower(sprintf($imgPath, $locStr) . 'Icons/' . $icon . '.blp');
        }
        $eventIcons = DB::Aowow()->selectCol('SELECT textureString FROM dbc_holidays WHERE textureString <> ""');
        foreach ($eventIcons as $icon) {
            $dbcEntries[] = strtolower(sprintf($imgPath, $locStr) . 'Calendar/Holidays/' . $icon . 'Start.blp');
        }
    }
    // case-insensitive array_unique *vomits silently into a corner*
    $dbcEntries = array_intersect_key($dbcEntries, array_unique($dbcEntries));
    $allPaths = [];
    foreach ($paths as $i => $p) {
        $path = sprintf($imgPath, $locStr) . $p[0];
        if (!CLISetup::fileExists($path)) {
            continue;
        }
        $files = glob($path . $p[2], GLOB_BRACE);
        $allPaths = array_merge($allPaths, $files);
        CLISetup::log('processing ' . count($files) . ' files in ' . $path . '...');
        $j = 0;
        foreach ($files as $f) {
            ini_set('max_execution_time', 30);
            // max 30sec per image (loading takes the most time)
            $src = null;
            $img = explode('.', array_pop(explode('/', $f)));
            array_pop($img);
            // there are a hand full of images with multiple file endings or random dots in the name
            $img = implode('.', $img);
            // file not from dbc -> name from array or skip file
            if (!empty($cuNames[$i])) {
                if (!empty($cuNames[$i][strtolower($img)])) {
                    $img = $cuNames[$i][strtolower($img)];
                } else {
                    if (!$p[4]) {
                        $j += count($p[1]);
                        CLISetup::log('skipping extraneous file ' . $img . ' (+' . count($p[1]) . ')');
                        continue;
                    }
                }
            }
            $nFiles = count($p[1]) * ($p[4] ? array_sum(array_map('count', $cuNames[$i])) : count($files));
            foreach ($p[1] as $info) {
                if ($p[4]) {
                    foreach ($cuNames[$i] as $y => $row) {
                        foreach ($row as $x => $name) {
                            $j++;
                            $img = $p[3] ? strtolower($name) : $name;
                            $done = ' - ' . str_pad($j . '/' . $nFiles, 12) . str_pad('(' . number_format($j * 100 / $nFiles, 2) . '%)', 9);
                            if (!isset(FileGen::$cliOpts['force']) && file_exists($destDir . $info[0] . $img . '.' . $info[1])) {
                                CLISetup::log($done . ' - file ' . $info[0] . $img . '.' . $info[1] . ' was already processed');
                                continue;
                            }
                            if (!$src) {
                                $src = $loadImageFile($f);
                            }
                            if (!$src) {
                                // error should be created by imagecreatefromblp
                                continue;
                            }
                            $from = array('x' => $info[4] + $p[4] * $x, 'y' => $info[4] + $p[4] * $y, 'w' => $p[4] - $info[4] * 2, 'h' => $p[4] - $info[4] * 2);
                            $to = array('x' => 0, 'y' => 0, 'w' => $info[3], 'h' => $info[3]);
                            if (!$writeImage($destDir . $info[0] . $img, $info[1], $src, $from, $to, $done)) {
                                $success = false;
                            }
                        }
                    }
                    // custom handle for combined icon 'quest_startend'
                    /* not used due to alphaChannel issues
                                            if ($p[4] == 32)
                                            {
                                                $dest = imagecreatetruecolor(19, 16);
                                                imagesavealpha($dest, true);
                                                imagealphablending($dest, true);
                    
                                                // excalmationmark, questionmark
                                                imagecopyresampled($dest, $src, 0, 1, 32 + 5, 32 + 2,  8, 15, 18, 30);
                                                imagecopyresampled($dest, $src, 5, 0, 64 + 1, 32 + 1, 10, 16, 18, 28);
                    
                                                if (imagegif($dest, $destDir.$info[0].'quest_startend.gif'))
                                                    CLISetup::log('                extra - image '.$destDir.$info[0].'quest_startend.gif written', CLISetup::LOG_OK);
                                                else
                                                {
                                                    CLISetup::log('                extra - could not create image '.$destDir.$info[0].'quest_startend.gif', CLISetup::LOG_ERROR);
                                                    $success = false;
                                                }
                    
                                                imagedestroy($dest);
                                            }
                                            */
                } else {
                    // icon -> lowercase
                    if ($p[3]) {
                        $img = strtolower($img);
                    }
                    $j++;
                    $done = ' - ' . str_pad($j . '/' . $nFiles, 12) . str_pad('(' . number_format($j * 100 / $nFiles, 2) . '%)', 9);
                    if (!isset(FileGen::$cliOpts['force']) && file_exists($destDir . $info[0] . $img . '.' . $info[1])) {
                        CLISetup::log($done . ' - file ' . $info[0] . $img . '.' . $info[1] . ' was already processed');
                        continue;
                    }
                    if (!$src) {
                        $src = $loadImageFile($f);
                    }
                    if (!$src) {
                        // error should be created by imagecreatefromblp
                        continue;
                    }
                    $from = array('x' => $info[4], 'y' => $info[4], 'w' => ($info[2] ?: imagesx($src)) - $info[4] * 2, 'h' => ($info[2] ?: imagesy($src)) - $info[4] * 2);
                    $to = array('x' => 0, 'y' => 0, 'w' => $info[3] ?: imagesx($src), 'h' => $info[3] ?: imagesy($src));
                    if (!$writeImage($destDir . $info[0] . $img, $info[1], $src, $from, $to, $done)) {
                        $success = false;
                    }
                }
            }
            unset($src);
        }
    }
    // reset execTime
    ini_set('max_execution_time', FileGen::$defaultExecTime);
    if ($missing = array_diff(array_map('strtolower', $dbcEntries), array_map('strtolower', $allPaths))) {
        asort($missing);
        CLISetup::log('the following ' . count($missing) . ' images where referenced by DBC but not in the mpqData directory. They may need to be converted by hand later on.', CLISetup::LOG_WARN);
        foreach ($missing as $m) {
            CLISetup::log(' - ' . $m);
        }
    }
    return $success;
}
Esempio n. 2
0
     continue;
 }
 for ($i = 0; $i < 12; $i++) {
     $img = imagecreatefromblp($prefix . ($i + 1) . ".blp");
     imagecopyresampled($map, $img, 256 * ($i % 4), 256 * intval($i / 4), 0, 0, 256, 256, imagesx($img), imagesy($img));
     imagedestroy($img);
 }
 echo ".";
 if (isset($wmo[$zid])) {
     foreach ($wmo[$zid] as $row) {
         $i = 1;
         $y = 0;
         while ($y < $row["height"]) {
             $x = 0;
             while ($x < $row["width"]) {
                 $img = imagecreatefromblp($worldmapdir . $mapname . "/" . $row["name"] . $i . ".blp");
                 imagecopy($mapfg, $img, $row["left"] + $x, $row["top"] + $y, 0, 0, imagesx($img), imagesy($img));
                 imagedestroy($img);
                 $x += 256;
                 $i++;
             }
             $y += 256;
         }
     }
     echo ".";
     if (isset($outtmpdir)) {
         $tmp = imagecreate(1000, 1000);
         $cbg = imagecolorallocate($tmp, 255, 255, 255);
         $cfg = imagecolorallocate($tmp, 0, 0, 0);
         for ($y = 0; $y < 1000; $y++) {
             for ($x = 0; $x < 1000; $x++) {
Esempio n. 3
0
function complexImg()
{
    if (isset(FileGen::$cliOpts['help'])) {
        echo "\n";
        echo "available options for subScript 'complexImg':\n";
        // modeMask
        echo "--talentbgs  (backgrounds for talent calculator)\n";
        // 0x01
        echo "--maps       (generates worldmaps)\n";
        // 0x02
        echo "--spawn-maps (creates alphaMasks of each zone to check spawns against)\n";
        // 0x04
        echo "--artwork    (optional: imagery from /glues/credits (not used, skipped by default))\n";
        // 0x08
        echo "--area-maps  (optional: renders maps with highlighted subZones for each area)\n";
        // 0x10
        return true;
    }
    $mapWidth = 1002;
    $mapHeight = 668;
    $threshold = 95;
    // alpha threshold to define subZones: set it too low and you have unspawnable areas inside a zone; set it too high and the border regions overlap
    $runTime = ini_get('max_execution_time');
    $locStr = null;
    $dbcPath = CLISetup::$srcDir . '%sDBFilesClient/';
    $imgPath = CLISetup::$srcDir . '%sInterface/';
    $destDir = 'static/images/wow/';
    $success = true;
    $paths = ['WorldMap/', 'TalentFrame/', 'Glues/Credits/'];
    $modeMask = 0x7;
    // talentBGs, regular maps, spawn-related alphaMaps
    $createAlphaImage = function ($w, $h) {
        $img = imagecreatetruecolor($w, $h);
        imagesavealpha($img, true);
        imagealphablending($img, false);
        $bgColor = imagecolorallocatealpha($img, 0, 0, 0, 127);
        imagefilledrectangle($img, 0, 0, imagesx($img) - 1, imagesy($img) - 1, $bgColor);
        imagecolortransparent($img, $bgColor);
        imagealphablending($img, true);
        imagecolordeallocate($img, $bgColor);
        return $img;
    };
    // prefer manually converted PNG files (as the imagecreatefromblp-script has issues with some formats)
    // alpha channel issues observed with locale deDE Hilsbrad and Elwynn - maps
    // see: https://github.com/Kanma/BLPConverter
    $loadImageFile = function ($path) {
        $result = null;
        $file = $path . '.png';
        if (CLISetup::fileExists($file)) {
            CLISetup::log('manually converted png file present for ' . $path . '.', CLISetup::LOG_WARN);
            $result = imagecreatefrompng($file);
        }
        if (!$result) {
            $file = $path . '.blp';
            if (CLISetup::fileExists($file)) {
                $result = imagecreatefromblp($file);
            }
        }
        return $result;
    };
    $assembleImage = function ($baseName, $order, $w, $h) use($loadImageFile) {
        $dest = imagecreatetruecolor($w, $h);
        imagesavealpha($dest, true);
        imagealphablending($dest, false);
        $_h = $h;
        foreach ($order as $y => $row) {
            $_w = $w;
            foreach ($row as $x => $suffix) {
                $src = $loadImageFile($baseName . $suffix);
                if (!$src) {
                    CLISetup::log(' - complexImg: tile ' . $baseName . $suffix . '.blp missing.', CLISetup::LOG_ERROR);
                    unset($dest);
                    return null;
                }
                imagecopyresampled($dest, $src, 256 * $x, 256 * $y, 0, 0, min($_w, 256), min($_h, 256), min($_w, 256), min($_h, 256));
                $_w -= 256;
                unset($src);
            }
            $_h -= 256;
        }
        return $dest;
    };
    $writeImage = function ($name, $ext, $src, $w, $h, $done) {
        $ok = false;
        $dest = imagecreatetruecolor($w, $h);
        imagesavealpha($dest, true);
        imagealphablending($dest, false);
        imagecopyresampled($dest, $src, 0, 0, 0, 0, $w, $h, imagesx($src), imagesy($src));
        switch ($ext) {
            case 'jpg':
                $ok = imagejpeg($dest, $name . '.' . $ext, 85);
                break;
            case 'png':
                $ok = imagepng($dest, $name . '.' . $ext);
                break;
            default:
                CLISetup::log($done . ' - unsupported file fromat: ' . $ext, CLISetup::LOG_WARN);
        }
        imagedestroy($dest);
        if ($ok) {
            chmod($name . '.' . $ext, CLISetup::FILE_ACCESS);
            CLISetup::log($done . ' - image ' . $name . '.' . $ext . ' written', CLISetup::LOG_OK);
        } else {
            CLISetup::log($done . ' - could not create image ' . $name . '.' . $ext, CLISetup::LOG_ERROR);
        }
        return $ok;
    };
    $createSpawnMap = function ($img, $zoneId) use($mapHeight, $mapWidth, $threshold) {
        CLISetup::log(' - creating spawn map');
        $tmp = imagecreate(1000, 1000);
        $cbg = imagecolorallocate($tmp, 255, 255, 255);
        $cfg = imagecolorallocate($tmp, 0, 0, 0);
        for ($y = 0; $y < 1000; $y++) {
            for ($x = 0; $x < 1000; $x++) {
                $a = imagecolorat($img, $x * $mapWidth / 1000, $y * $mapHeight / 1000) >> 24;
                imagesetpixel($tmp, $x, $y, $a < $threshold ? $cfg : $cbg);
            }
        }
        imagepng($tmp, 'setup/generated/alphaMaps/' . $zoneId . '.png');
        imagecolordeallocate($tmp, $cbg);
        imagecolordeallocate($tmp, $cfg);
        imagedestroy($tmp);
    };
    $checkSourceDirs = function ($sub, &$missing = []) use($imgPath, $dbcPath, $paths, &$modeMask) {
        $hasMissing = false;
        foreach ($paths as $idx => $subDir) {
            if ($idx == 0 && !($modeMask & 0x16)) {
                // map related
                continue;
            } else {
                if ($idx == 1 && !($modeMask & 0x1)) {
                    // talentBGs
                    continue;
                } else {
                    if ($idx == 2 && !($modeMask & 0x8)) {
                        // artwork
                        continue;
                    }
                }
            }
            $p = sprintf($imgPath, $sub) . $subDir;
            if (!CLISetup::fileExists($p)) {
                $hasMissing = true;
                $missing[] = $p;
            }
        }
        if ($modeMask & 0x17) {
            $p = sprintf($dbcPath, $sub);
            if (!CLISetup::fileExists($p)) {
                $hasMissing = true;
                $missing[] = $p;
            }
        }
        return !$hasMissing;
    };
    // do not change order of params!
    if ($_ = FileGen::hasOpt('talentbgs', 'maps', 'spawn-maps', 'artwork', 'area-maps')) {
        $modeMask = $_;
    }
    foreach (CLISetup::$expectedPaths as $xp => $__) {
        if ($xp) {
            // if in subDir add trailing slash
            $xp .= '/';
        }
        if ($checkSourceDirs($xp, $missing)) {
            $locStr = $xp;
            break;
        }
    }
    // if no subdir had sufficient data, diaf
    if ($locStr === null) {
        CLISetup::log('one or more required directories are missing:', CLISetup::LOG_ERROR);
        foreach ($missing as $m) {
            CLISetup::log(' - ' . $m, CLISetup::LOG_ERROR);
        }
        return;
    }
    /**************/
    /* TalentTabs */
    /**************/
    if ($modeMask & 0x1) {
        if (CLISetup::writeDir($destDir . 'hunterpettalents/') && CLISetup::writeDir($destDir . 'talents/backgrounds/')) {
            // [classMask, creatureFamilyMask, tabNr, textureStr]
            $tTabs = DB::Aowow()->select('SELECT tt.creatureFamilyMask, tt.textureFile, tt.tabNumber, cc.fileString FROM dbc_talenttab tt LEFT JOIN dbc_chrclasses cc ON cc.Id = (LOG(2, tt.classMask) + 1)');
            $order = array(['-TopLeft', '-TopRight'], ['-BottomLeft', '-BottomRight']);
            if ($tTabs) {
                $sum = 0;
                $total = count($tTabs);
                CLISetup::log('Processing ' . $total . ' files from TalentFrame/ ...');
                foreach ($tTabs as $tt) {
                    ini_set('max_execution_time', 30);
                    // max 30sec per image (loading takes the most time)
                    $sum++;
                    $done = ' - ' . str_pad($sum . '/' . $total, 8) . str_pad('(' . number_format($sum * 100 / $total, 2) . '%)', 9);
                    if ($tt['creatureFamilyMask']) {
                        $size = [244, 364];
                        $name = $destDir . 'hunterpettalents/bg_' . (log($tt['creatureFamilyMask'], 2) + 1);
                    } else {
                        $size = [204, 554];
                        $name = $destDir . 'talents/backgrounds/' . strtolower($tt['fileString']) . '_' . ($tt['tabNumber'] + 1);
                    }
                    if (!isset(FileGen::$cliOpts['force']) && file_exists($name . '.jpg')) {
                        CLISetup::log($done . ' - file ' . $name . '.jpg was already processed');
                        continue;
                    }
                    $im = $assembleImage(sprintf($imgPath, $locStr) . 'TalentFrame/' . $tt['textureFile'], $order, 256 + 44, 256 + 75);
                    if (!$im) {
                        CLISetup::log(' - could not assemble file ' . $tt['textureFile'], CLISetup::LOG_ERROR);
                        continue;
                    }
                    if (!$writeImage($name, 'jpg', $im, $size[0], $size[1], $done)) {
                        $success = false;
                    }
                }
            } else {
                $success = false;
            }
            ini_set('max_execution_time', $runTime);
        } else {
            $success = false;
        }
    }
    /************/
    /* Worldmap */
    /************/
    if ($modeMask & 0x16) {
        $mapDirs = array(['maps/%snormal/', 'jpg', 488, 325], ['maps/%soriginal/', 'jpg', 0, 0], ['maps/%ssmall/', 'jpg', 224, 163], ['maps/%szoom/', 'jpg', 772, 515]);
        // as the js expects them
        $baseLevelFix = array(4264 => 1, 4265 => 1, 4415 => 1, 4416 => 1, 4493 => 0, 4500 => 1, 4603 => 1, 4723 => 1, 4809 => 1, 4813 => 1, 4820 => 1, 717 => 1, 3713 => 1, 2437 => 1, 3716 => 1, 3847 => 1, 718 => 1, 3717 => 1, 3714 => 1, 3562 => 1, 722 => 1, 491 => 1, 3792 => 1, 3789 => 1, 1477 => 1, 3959 => 0, 3845 => 1, 2717 => 1, 3923 => 1, 3607 => 1, 3836 => 1, 2159 => 1, 4075 => 0);
        $wmo = DB::Aowow()->select('SELECT *, worldMapAreaId AS ARRAY_KEY, Id AS ARRAY_KEY2 FROM dbc_worldmapoverlay WHERE textureString <> ""');
        $wma = DB::Aowow()->select('SELECT * FROM dbc_worldmaparea');
        if (!$wma || !$wmo) {
            $success = false;
            CLISetup::log(' - could not read required dbc files: WorldMapArea.dbc [' . count($wma) . ' entries]; WorldMapOverlay.dbc  [' . count($wmo) . ' entries]', CLISetup::LOG_ERROR);
            return;
        }
        // fixups...
        foreach ($wma as &$a) {
            if ($a['areaId']) {
                continue;
            }
            switch ($a['Id']) {
                case 13:
                    $a['areaId'] = -6;
                    break;
                    // Kalimdor
                // Kalimdor
                case 14:
                    $a['areaId'] = -3;
                    break;
                    // Eastern Kingdoms
                // Eastern Kingdoms
                case 466:
                    $a['areaId'] = -2;
                    break;
                    // Outland
                // Outland
                case 485:
                    $a['areaId'] = -5;
                    break;
                    // Northrend
            }
        }
        array_unshift($wma, ['Id' => -1, 'areaId' => -1, 'nameINT' => 'World'], ['Id' => -4, 'areaId' => -4, 'nameINT' => 'Cosmic']);
        $sumMaps = count(CLISetup::$localeIds) * count($wma);
        CLISetup::log('Processing ' . $sumMaps . ' files from WorldMap/ ...');
        foreach (CLISetup::$localeIds as $progressLoc => $l) {
            // create destination directories
            $dirError = false;
            foreach ($mapDirs as $md) {
                if (!CLISetup::writeDir($destDir . sprintf($md[0], strtolower(Util::$localeStrings[$l]) . '/'))) {
                    $dirError = true;
                }
            }
            if ($modeMask & 0x4) {
                if (!CLISetup::writeDir('setup/generated/alphaMaps')) {
                    $dirError = true;
                }
            }
            if ($dirError) {
                $success = false;
                CLISetup::log(' - complexImg: could not create map directories for locale ' . $l . '. skipping...', CLISetup::LOG_ERROR);
                continue;
            }
            // source for mapFiles
            $mapSrcDir = null;
            $locDirs = array_filter(CLISetup::$expectedPaths, function ($var) use($l) {
                return !$var || $var == $l;
            });
            foreach ($locDirs as $mapLoc => $__) {
                if ($mapLoc) {
                    // and trailing slash again
                    $mapLoc .= '/';
                }
                $p = sprintf($imgPath, $mapLoc) . $paths[0];
                if (CLISetup::fileExists($p)) {
                    CLISetup::log(' - using files from ' . ($mapLoc ?: '/') . ' for locale ' . Util::$localeStrings[$l], CLISetup::LOG_WARN);
                    $mapSrcDir = $p . '/';
                    break;
                }
            }
            if ($mapSrcDir === null) {
                $success = false;
                CLISetup::log(' - no suitable localized map files found for locale ' . $l, CLISetup::LOG_ERROR);
                continue;
            }
            foreach ($wma as $progressArea => $areaEntry) {
                $curMap = $progressArea + count($wma) * $progressLoc;
                $progress = ' - ' . str_pad($curMap . '/' . $sumMaps, 10) . str_pad('(' . number_format($curMap * 100 / $sumMaps, 2) . '%)', 9);
                $wmaId = $areaEntry['Id'];
                $zoneId = $areaEntry['areaId'];
                $textureStr = $areaEntry['nameINT'];
                $path = $mapSrcDir . $textureStr;
                if (!CLISetup::fileExists($path)) {
                    $success = false;
                    CLISetup::log('worldmap file ' . $path . ' missing for selected locale ' . Util::$localeStrings[$l], CLISetup::LOG_ERROR);
                    continue;
                }
                $fmt = array([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]);
                CLISetup::log($textureStr . " [" . $zoneId . "]");
                $overlay = $createAlphaImage($mapWidth, $mapHeight);
                // zone has overlays (is in open world; is not multiLeveled)
                if (isset($wmo[$wmaId])) {
                    CLISetup::log(' - area has ' . count($wmo[$wmaId]) . ' overlays');
                    foreach ($wmo[$wmaId] as &$row) {
                        $i = 1;
                        $y = 0;
                        while ($y < $row['h']) {
                            $x = 0;
                            while ($x < $row['w']) {
                                $img = $loadImageFile($path . '/' . $row['textureString'] . $i);
                                if (!$img) {
                                    CLISetup::log(' - complexImg: tile ' . $path . '/' . $row['textureString'] . $i . '.blp missing.', CLISetup::LOG_ERROR);
                                    break 2;
                                }
                                imagecopy($overlay, $img, $row['x'] + $x, $row['y'] + $y, 0, 0, imagesx($img), imagesy($img));
                                // prepare subzone image
                                if ($modeMask & 0x10) {
                                    if (!isset($row['maskimage'])) {
                                        $row['maskimage'] = $createAlphaImage($row['w'], $row['h']);
                                        $row['maskcolor'] = imagecolorallocatealpha($row['maskimage'], 255, 64, 192, 64);
                                    }
                                    for ($my = 0; $my < imagesy($img); $my++) {
                                        for ($mx = 0; $mx < imagesx($img); $mx++) {
                                            if (imagecolorat($img, $mx, $my) >> 24 < $threshold) {
                                                imagesetpixel($row['maskimage'], $x + $mx, $y + $my, $row['maskcolor']);
                                            }
                                        }
                                    }
                                }
                                imagedestroy($img);
                                $x += 256;
                                $i++;
                            }
                            $y += 256;
                        }
                    }
                    // create spawn-maps if wanted
                    if ($modeMask & 0x4) {
                        $createSpawnMap($overlay, $zoneId);
                    }
                }
                // check, if the current zone is multiLeveled
                // if there are also files present without layer-suffix assume them as layer: 0
                $multiLeveled = false;
                $multiLevel = 0;
                do {
                    if (!CLISetup::filesInPath('/' . $textureStr . '\\/' . $textureStr . ($multiLevel + 1) . '_\\d\\.blp/i', true)) {
                        break;
                    }
                    $multiLevel++;
                    $multiLeveled = true;
                } while ($multiLevel < 18);
                // Karazhan has 17 frickin floors
                // check if we can create base map anyway
                $file = $path . '/' . $textureStr . '1.blp';
                $hasBaseMap = CLISetup::fileExists($file);
                CLISetup::log(' - area has ' . ($multiLeveled ? $multiLevel . ' levels' : 'only base level'));
                $map = null;
                for ($i = 0; $i <= $multiLevel; $i++) {
                    ini_set('max_execution_time', 120);
                    // max 120sec per image
                    $file = $path . '/' . $textureStr;
                    if (!$i && !$hasBaseMap) {
                        continue;
                    }
                    // if $multiLeveled also suffix -0 to baseMap if it exists
                    if ($i && $multiLeveled) {
                        $file .= $i . '_';
                    }
                    $doSkip = 0x0;
                    $outFile = [];
                    foreach ($mapDirs as $idx => $info) {
                        $outFile[$idx] = $destDir . sprintf($info[0], strtolower(Util::$localeStrings[$l]) . '/') . $zoneId;
                        $floor = $i;
                        if ($zoneId == 4100) {
                            // ToCStratholme: map order fix
                            $floor += 1;
                        }
                        if ($multiLeveled && !(isset($baseLevelFix[$zoneId]) && $i == $baseLevelFix[$zoneId])) {
                            $outFile[$idx] .= '-' . $floor;
                        }
                        if (!isset(FileGen::$cliOpts['force']) && file_exists($outFile[$idx] . '.' . $info[1])) {
                            CLISetup::log($progress . ' - file ' . $outFile[$idx] . '.' . $info[1] . ' was already processed');
                            $doSkip |= 1 << $idx;
                        }
                    }
                    if ($doSkip == 0xf) {
                        continue;
                    }
                    $map = $assembleImage($file, $fmt, $mapWidth, $mapHeight);
                    if (!$map) {
                        $success = false;
                        CLISetup::log(' - could not create image resource for map ' . $zoneId . ($multiLevel ? ' level ' . $i : ''));
                        continue;
                    }
                    if (!$multiLeveled) {
                        imagecopymerge($map, $overlay, 0, 0, 0, 0, imagesx($overlay), imagesy($overlay), 100);
                        imagedestroy($overlay);
                    }
                    // create map
                    if ($modeMask & 0x2) {
                        foreach ($mapDirs as $idx => $info) {
                            if ($doSkip & 1 << $idx) {
                                continue;
                            }
                            if (!$writeImage($outFile[$idx], $info[1], $map, $info[2] ?: $mapWidth, $info[3] ?: $mapHeight, $progress)) {
                                $success = false;
                            }
                        }
                    }
                }
                // also create subzone-maps
                if ($map && isset($wmo[$wmaId]) && $modeMask & 0x10) {
                    foreach ($wmo[$wmaId] as &$row) {
                        $doSkip = 0x0;
                        $outFile = [];
                        foreach ($mapDirs as $idx => $info) {
                            $outFile[$idx] = $destDir . sprintf($info[0], strtolower(Util::$localeStrings[$l]) . '/') . $row['areaTableId'];
                            if (!isset(FileGen::$cliOpts['force']) && file_exists($outFile[$idx] . '.' . $info[1])) {
                                CLISetup::log($progress . ' - file ' . $outFile[$idx] . '.' . $info[1] . ' was already processed');
                                $doSkip |= 1 << $idx;
                            }
                        }
                        if ($doSkip == 0xf) {
                            continue;
                        }
                        $subZone = imagecreatetruecolor($mapWidth, $mapHeight);
                        imagecopy($subZone, $map, 0, 0, 0, 0, imagesx($map), imagesy($map));
                        imagecopy($subZone, $row['maskimage'], $row['x'], $row['y'], 0, 0, imagesx($row['maskimage']), imagesy($row['maskimage']));
                        foreach ($mapDirs as $idx => $info) {
                            if ($doSkip & 1 << $idx) {
                                continue;
                            }
                            if (!$writeImage($outFile[$idx], $info[1], $subZone, $info[2] ?: $mapWidth, $info[3] ?: $mapHeight, $progress)) {
                                $success = false;
                            }
                        }
                        imagedestroy($subZone);
                    }
                }
                if ($map) {
                    imagedestroy($map);
                }
            }
        }
    }
    /***********/
    /* Credits */
    /***********/
    if ($modeMask & 0x8) {
        if (CLISetup::writeDir($destDir . 'Interface/Glues/Credits/')) {
            // tile ordering
            $order = array(1 => array([1]), 2 => array([1], [2]), 4 => array([1, 2], [3, 4]), 6 => array([1, 2, 3], [4, 5, 6]), 8 => array([1, 2, 3, 4], [5, 6, 7, 8]));
            $imgGroups = [];
            $srcPath = sprintf($imgPath, $locStr) . 'Glues/Credits/';
            $files = CLISetup::filesInPath($srcPath);
            foreach ($files as $f) {
                if (preg_match('/([^\\/]+)(\\d).blp/i', $f, $m)) {
                    if ($m[1] && $m[2]) {
                        if (!isset($imgGroups[$m[1]])) {
                            $imgGroups[$m[1]] = $m[2];
                        } else {
                            if ($imgGroups[$m[1]] < $m[2]) {
                                $imgGroups[$m[1]] = $m[2];
                            }
                        }
                    }
                }
            }
            // errör-korrekt
            $imgGroups['Desolace'] = 4;
            $imgGroups['BloodElf_Female'] = 6;
            $total = count($imgGroups);
            $sum = 0;
            CLISetup::log('Processing ' . $total . ' files from Glues/Credits/...');
            foreach ($imgGroups as $file => $fmt) {
                ini_set('max_execution_time', 30);
                // max 30sec per image (loading takes the most time)
                $sum++;
                $done = ' - ' . str_pad($sum . '/' . $total, 8) . str_pad('(' . number_format($sum * 100 / $total, 2) . '%)', 9);
                $name = $destDir . 'Interface/Glues/Credits/' . $file;
                if (!isset(FileGen::$cliOpts['force']) && file_exists($name . '.png')) {
                    CLISetup::log($done . ' - file ' . $name . '.png was already processed');
                    continue;
                }
                if (!isset($order[$fmt])) {
                    CLISetup::log(' - pattern for file ' . $name . ' not set. skipping', CLISetup::LOG_WARN);
                    continue;
                }
                $im = $assembleImage($srcPath . $file, $order[$fmt], count($order[$fmt][0]) * 256, count($order[$fmt]) * 256);
                if (!$im) {
                    CLISetup::log(' - could not assemble file ' . $name, CLISetup::LOG_ERROR);
                    continue;
                }
                if (!$writeImage($name, 'png', $im, count($order[$fmt][0]) * 256, count($order[$fmt]) * 256, $done)) {
                    $success = false;
                }
            }
            ini_set('max_execution_time', $runTime);
        } else {
            $success = false;
        }
    }
    return $success;
}
Esempio n. 4
0
function process($dbcfile, $dbcfmt)
{
    global $mpqdir, $largedir, $mediumdir, $smalldir, $tinydir;
    status("Reading icons list from {$dbcfile}...");
    $dbc = dbc2array_($dbcfile, $dbcfmt);
    $count = count($dbc);
    status($count . " icons found\n");
    $current = 0;
    $status = array();
    $lastfile = array();
    foreach ($dbc as $row) {
        $srcfilename = strtolower(str_replace("\\", "/", $row[1]));
        if (strpos($srcfilename, "/") === FALSE) {
            $srcfilename = "interface/icons/" . $srcfilename;
        }
        $src = $mpqdir . $srcfilename . ".blp";
        $stat_src = @stat($src);
        if ($row[1] == "") {
            echo " ";
        } else {
            if ($stat_src == NULL || $stat_src['size'] == 0) {
                $msg = "Not found";
                $status[$msg] = isset($status[$msg]) ? $status[$msg] + 1 : 1;
                $lastfile[$msg][] = $src;
                echo "-";
            } else {
                $dstfilename = strtolower(substr(strrchr($srcfilename, "/"), 1));
                $stat_dst = @stat($largedir . $dstfilename . ".jpg");
                if ($stat_dst != NULL && $stat_dst['mtime'] >= $stat_src['mtime']) {
                    $msg = "Already up-to-date";
                    $status[$msg] = isset($status[$msg]) ? $status[$msg] + 1 : 1;
                    //$lastfile[$msg][] = $src;
                    $lastfile[$msg][0] = "...";
                    $lastfile[$msg][1] = $src;
                    echo ".";
                } else {
                    $img = imagecreatefromblp($src);
                    resave($largedir . $dstfilename . ".jpg", $img, 56, 56);
                    resave($mediumdir . $dstfilename . ".jpg", $img, 36, 36);
                    resave($smalldir . $dstfilename . ".jpg", $img, 18, 18);
                    resave($tinydir . $dstfilename . ".gif", $img, 15, 15);
                    echo "+";
                }
            }
        }
        $current++;
        if ($current % 60 == 0) {
            status(" " . $current . "/" . $count . " (" . round(100 * $current / $count) . "%)\n");
        }
    }
    if ($current % 60 != 0) {
        status(" " . $current . "/" . $count . " (100%)\n");
    }
    echo "Done\n";
    if (count($status) > 0) {
        echo "Status:\n";
        foreach ($status as $s => $row) {
            echo "  " . $s . ": " . $row . "\n";
            //        foreach ($lastfile[$s] as $file)
            //          echo "    $file\n";
        }
    }
}