Exemple #1
0
 function verifySigature($message, $sign, $exponent, $modulus)
 {
     $intSign = bin2int(hex2bin($sign));
     $intExponent = bin2int(hex2bin($exponent));
     $intModulus = bin2int(hex2bin($modulus));
     $intResult = powmod($intSign, $intExponent, $intModulus);
     $hexResult = bin2hex(int2bin($intResult));
     $md5Message = md5($message);
     if ($md5Message == substr($hexResult, -32)) {
         return "1";
     } else {
         return "0";
     }
 }
Exemple #2
0
function bitOr($num1, $num2, $start_pos)
{
    $start_byte = intval($start_pos / 8);
    $start_bit = $start_pos % 8;
    $tmp1 = int2bin($num1);
    $num2 = bcmul($num2, 1 << $start_bit);
    $tmp2 = int2bin($num2);
    if ($start_byte < strlen($tmp1)) {
        $tmp2 |= substr($tmp1, $start_byte);
        $tmp1 = substr($tmp1, 0, $start_byte) . $tmp2;
    } else {
        $tmp1 = str_pad($tmp1, $start_byte, "") . $tmp2;
    }
    return bin2int($tmp1);
}
Exemple #3
0
function rsa_decrypt($enc_data, $p, $q, $d)
{
    $enc_data = int2bin($enc_data);
    $exp = $d;
    $modulus = bcmul($p, $q);
    $data_len = strlen($enc_data);
    $chunk_len = bitLen($modulus) - 1;
    $block_len = (int) ceil($chunk_len / 8);
    $curr_pos = 0;
    $bit_pos = 0;
    $plain_data = 0;
    while ($curr_pos < $data_len) {
        $tmp = bin2int(substr($enc_data, $curr_pos, $block_len));
        $tmp = bcpowmod($tmp, $exp, $modulus);
        $plain_data = bitOr($plain_data, $tmp, $bit_pos);
        $bit_pos += $chunk_len;
        $curr_pos += $block_len;
    }
    return int2bin($plain_data);
}
Exemple #4
0
function build_replace($reg)
{
    global $gwbbcode_tpl;
    global $userdata;
    $gwbbcode_root_path = GWBBCODE_ROOT;
    $gwbbcode_img_path = GWBBCODE_IMG_PATH;
    list($all, $att, $skills) = $reg;
    $att = str_replace("\n", "<br/>\n", html_safe_decode($att));
    $attr_list_raw = attribute_list_raw($att);
    $attr_list = attribute_list($att);
    $load = rand();
    //Build name
    $build_name = gws_build_name($att);
    $build_name = str_replace('{br}', '<br/>', str_replace('{br/}', '<br/>', str_replace('{BR}', '<br/>', str_replace('{BR/}', '<br/>', $build_name))));
    //Professions
    $prof = gws_build_profession($att);
    $prof_imgs = '';
    $cursor = 'help';
    if ($prof !== false) {
        $primary = gws_prof_name($prof['primary']);
        $secondary = gws_prof_name($prof['secondary']);
        if ($secondary == $primary) {
            $secondary = 'No profession';
        }
        $showimg = '';
        $prof_imgs .= str_replace('{profession}', $primary, $gwbbcode_tpl['prof_icon']);
        if ($secondary != 'No profession') {
            $prof_imgs .= str_replace('{profession}', $secondary, $gwbbcode_tpl['prof_icon']);
            //Remove secondary profession main attribute, or set it to 0 for skill description coherence
            unset($attr_list_raw[gws_main_attribute($secondary)]);
            $att .= ' ' . gws_attribute_name(gws_main_attribute($secondary)) . '=0';
        }
        $prof_imgs = preg_replace("#\\{(.*?)\\}#ise", "isset(\$\\1)?\$\\1:'\\0'", $prof_imgs);
    } else {
        $showimg = ' ;display: none';
        $primary = 'Any';
        $secondary = 'Any';
    }
    //Attributes
    $attributes = '';
    foreach ($attr_list_raw as $attribute_name => $attribute_value) {
        $attributes .= preg_replace("#\\{(.*?)\\}#ise", "isset(\$\\1)?\$\\1:'\\0'", $gwbbcode_tpl['attribute']);
    }
    $attributes = preg_replace('/\\s*\\+\\s*/', ' + ', $attributes);
    $skills = str_replace('[skill', '[skill ' . $att, $skills);
    //Build description
    $desc = preg_match('|desc=\\"([^"]+)\\"|', $att, $reg) ? $reg[1] : '';
    $desc = empty($desc) ? '' : $desc . '<br/>';
    $desc = str_replace('{br}', '<br/>', str_replace('{br/}', '<br/>', str_replace('{BR}', '<br/>', str_replace('{BR/}', '<br/>', $desc))));
    //Primary attribute effect on build
    if (!empty($attr_list['Energy Storage'])) {
        $desc .= '<span class="expert">Your maximum Energy is raised by <b>' . 3 * $attr_list['Energy Storage'] . '</b>.</span><br/>';
    } else {
        if (!empty($attr_list['Soul Reaping'])) {
            $desc .= '<span class="expert">When they die near you, you gain <b>' . $attr_list['Soul Reaping'] . '</b> Energy per creature, or <b>' . floor($attr_list['Soul Reaping'] / 2) . '</b> Energy per Spirit under your control, up to 3 times every 15 seconds.</span><br/>';
        } else {
            if (!empty($attr_list['Critical Strikes'])) {
                $desc .= '<span class="expert">You have an additonal <b>' . $attr_list['Critical Strikes'] . '</b>% chance to critical hit. Whenever you critical hit, you get <b>' . round($attr_list['Critical Strikes'] / 5) . '</b> Energy.</span><br/>';
            } else {
                if (!empty($attr_list['Mysticism'])) {
                    $desc .= '<span class="expert">Whenever an Enchantment ends, you gain <b>' . $attr_list['Mysticism'] . '</b> Health and <b>' . floor($attr_list['Mysticism'] / 3) . '</b> Energy.</span><br/>';
                }
            }
        }
    }
    //Pickup status
    $pickup_id = preg_match('|pickup=\\"([^"]+)\\"|', $att, $reg) ? $reg[1] : '';
    //Get all pickup users
    $pickup = load(PICKUP_PATH);
    if (!empty($pickup_id) && $pickup !== false) {
        //Output status
        $cursor = 'pointer';
        $pickup = "Can play it: <span id=\"pickup_{$pickup_id}\">" . pickup_users($pickup, $userdata['username'], $pickup_id, 'No one can!') . '</span>';
        $pickup_link = " onclick=\"pickup('switch', '{$pickup_id}')\"";
    } else {
        $pickup = '';
        $pickup_link = '';
    }
    $prof_imgs = str_replace('{cursor}', $cursor, $prof_imgs);
    //Template: professions
    $invalid_template = false;
    static $prof_ids = array('No profession', 'Warrior', 'Ranger', 'Monk', 'Necromancer', 'Mesmer', 'Elementalist', 'Assassin', 'Ritualist', 'Paragon', 'Dervish');
    $template = '0111000000';
    $template .= int2bin(array_search($primary, $prof_ids), 4);
    $template .= int2bin(array_search($secondary, $prof_ids), 4);
    //Template: attributes
    static $attr_ids = array('fas', 'ill', 'dom', 'ins', 'blo', 'dea', 'sou', 'cur', 'air', 'ear', 'fir', 'wat', 'ene', 'hea', 'smi', 'pro', 'div', 'str', 'axe', 'ham', 'swo', 'tac', 'bea', 'exp', 'wil', 'mar', 29 => 'dag', 'dead', 'sha', 'com', 'res', 'cha', 'cri', 'spa', 'spe', 'comma', 'mot', 'lea', 'scy', 'win', 'earthp', 'mys');
    static $prof_attr_list = array('Air Magic' => 'Elementalist', 'Earth Magic' => 'Elementalist', 'Energy Storage' => 'Elementalist', 'Fire Magic' => 'Elementalist', 'Water Magic' => 'Elementalist', 'Domination Magic' => 'Mesmer', 'Fast Casting' => 'Mesmer', 'Illusion Magic' => 'Mesmer', 'Inspiration Magic' => 'Mesmer', 'Divine Favor' => 'Monk', 'Healing Prayers' => 'Monk', 'Protection Prayers' => 'Monk', 'Smiting Prayers' => 'Monk', 'Blood Magic' => 'Necromancer', 'Curses' => 'Necromancer', 'Death Magic' => 'Necromancer', 'Soul Reaping' => 'Necromancer', 'Beast Mastery' => 'Ranger', 'Expertise' => 'Ranger', 'Marksmanship' => 'Ranger', 'Wilderness Survival' => 'Ranger', 'Axe Mastery' => 'Warrior', 'Hammer Mastery' => 'Warrior', 'Strength' => 'Warrior', 'Swordsmanship' => 'Warrior', 'Tactics' => 'Warrior', 'Critical Strikes' => 'Assassin', 'Dagger Mastery' => 'Assassin', 'Deadly Arts' => 'Assassin', 'Shadow Arts' => 'Assassin', 'Spawning Power' => 'Ritualist', 'Channeling Magic' => 'Ritualist', 'Communing' => 'Ritualist', 'Restoration Magic' => 'Ritualist', 'Spear Mastery' => 'Paragon', 'Command' => 'Paragon', 'Motivation' => 'Paragon', 'Leadership' => 'Paragon', 'Scythe Mastery' => 'Dervish', 'Wind Prayers' => 'Dervish', 'Earth Prayers' => 'Dervish', 'Mysticism' => 'Dervish');
    arsort($attr_list_raw);
    //=> First attribute is attribute of highest level
    //Prepare a base attribute level and rune bonus list for primary and secondary attributes
    $attr_primary = array();
    $attr_secondary = array();
    $attr_runes = array();
    $available_helmet = true;
    //Ignore secondary profession main attribute
    if ($secondary != 'No profession') {
        unset($attr_list_raw[gws_main_attribute($secondary)]);
    }
    foreach ($attr_list_raw as $attr => $raw_level) {
        //Separate base level and bonus
        preg_match('@^([0-9]+)(\\+[+0-9]+)?@', $raw_level, $reg);
        $base_level = $reg[1];
        $bonus = isset($reg[2]) ? $reg[2] : '0';
        //Primary attributes
        if ($prof_attr_list[$attr] == $primary) {
            $bonus_level = @eval('return ' . $bonus . ';');
            //Invalid attribute level bonus
            if ($bonus_level > 4 || $bonus_level < 0 || $bonus_level == 4 && !$available_helmet) {
                $invalid_template = "Invalid attribute level bonus";
            } else {
                if ($available_helmet && ($bonus_level == 4 || substr_count($bonus, '+') > 1 && strpos($bonus, '+1') !== false)) {
                    $available_helmet = false;
                    $attr_primary[$attr] = $base_level;
                    $attr_runes[$attr] = $bonus_level - 1;
                } else {
                    $attr_primary[$attr] = $base_level;
                    $attr_runes[$attr] = $bonus_level;
                }
            }
        } else {
            if ($prof_attr_list[$attr] == $secondary) {
                $attr_secondary[$attr] = $base_level;
            }
        }
    }
    //Manage primary attribute levels
    $points_secondary = attr_points($attr_secondary);
    if (!empty($attr_primary)) {
        //Set helmet if needed
        if ($available_helmet && (max($attr_primary) > 12 || attr_points($attr_primary) + $points_secondary > 200)) {
            reset($attr_primary);
            $attr_primary[key($attr_primary)]--;
            //First attribute is attribute of highest level, the one needing a helmet the most
        }
        //Assign runes
        while ((max($attr_primary) > 12 || attr_points($attr_primary) + $points_secondary > 200) && min($attr_runes) < 3) {
            arsort($attr_primary);
            foreach ($attr_runes as $attr => $rune) {
                if ($rune < 3) {
                    $attr_primary[$attr]--;
                    $attr_runes[$attr]++;
                    break;
                }
            }
        }
    }
    $attr_list_raw = array_merge($attr_primary, $attr_secondary);
    $template .= int2bin(count($attr_list_raw), 4);
    if (!empty($attr_list_raw) && (max($attr_list_raw) > 12 || min($attr_list_raw) < 0 || attr_points($attr_list_raw) > 200)) {
        $invalid_template = "More attribute levels than attribute points can handle";
    }
    $attr_bit_size = 5;
    $template_attrs = array();
    foreach ($attr_list_raw as $attr => $level) {
        $id = array_search(gws_attribute_name($attr), $attr_ids);
        $template_attrs[$id] = $level;
        if ($id >= 32) {
            $attr_bit_size = 6;
        }
    }
    $template .= int2bin($attr_bit_size - 4, 4);
    ksort($template_attrs);
    foreach ($template_attrs as $id => $level) {
        $template .= int2bin($id, $attr_bit_size);
        $template .= int2bin($level, 4);
    }
    //Template: skills
    //and Kurzick/Luxon adaptation
    $skill_bit_size = 9;
    $skill_id_max = pow(2, $skill_bit_size);
    $template_skills = array();
    if (preg_match_all('#\\[skill[^\\]]*\\](.*?)\\[/skill\\][ ]?#isS', $skills, $regs, PREG_SET_ORDER)) {
        foreach ($regs as $reg) {
            $skill_name = $reg[1];
            $id = gws_skill_id($skill_name);
            if ($id !== false) {
                $skill = gws_details($id);
                //Handle faction-less skills
                if ($skill['attr'] == 'kur' && strpos($skill_name, '(') === false) {
                    //By default, unaligned skills are kurzick
                    //Change to default allegiance
                    $default_id = $id;
                    if (strpos(strtolower(GWBBCODE_ALLEGIANCE), 'kurzick') === false) {
                        $id = gws_skill_id($skill_name . ' (luxon)');
                        $skill = gws_details($id);
                        $default_id = $id;
                    }
                    //Try the other allegiance if default one is already used
                    if (array_search($id, $template_skills) !== false) {
                        $id = gws_skill_id($skill_name . ($skill['attr'] == 'kur' ? ' (Luxon)' : ' (Kurzick)'));
                        //Change back to default allegiance if both allegiance skills were used
                        if (array_search($id, $template_skills) !== false) {
                            $id = $default_id;
                        }
                        $skill = gws_details($id);
                    }
                    //Update skill names in $skills
                    $new_skill_str = str_replace($skill_name, $skill_name . ($skill['attr'] == 'kur' ? ' (Kurzick)' : ' (Luxon)'), $reg[0]);
                    $new_skill_str = str_replace('$', '\\$', $new_skill_str);
                    //you never know..
                    $skills = preg_replace('@' . preg_quote($reg[0]) . '@', $new_skill_str, $skills, 1);
                }
                if (($skill['profession'] == $primary || $skill['profession'] == $secondary || $skill['prof'] == '?') && (array_search($id, $template_skills) === false || $id == 0)) {
                    if ($id >= $skill_id_max) {
                        $skill_bit_size = floor(log($id, 2)) + 1;
                        $skill_id_max = pow(2, $skill_bit_size);
                    }
                } else {
                    if (array_search($id, $template_skills) !== false) {
                        $invalid_template = "Skill {$skill_name} can't be specified twice in the same build";
                    } else {
                        $invalid_template = "Skill {$skill_name} is not from one of the build professions";
                    }
                }
                $template_skills[] = $id;
                //Keep the list of skills indenpendently from their build validity
            }
        }
    }
    $template .= int2bin($skill_bit_size - 8, 4);
    if (count($template_skills) > 8) {
        $invalid_template = "You specified more skills than a build can handle";
    } else {
        foreach ($template_skills as $id) {
            $template .= int2bin($id, $skill_bit_size);
        }
        //Complete with 0s
        $template .= str_repeat(str_repeat('0', $skill_bit_size), 8 - count($template_skills));
    }
    //Manage template save icons
    if (preg_match("/ nosave/i", $att)) {
        $template_html = '';
    } else {
        if ($invalid_template === false) {
            //Prepare template bbcode
            $template_code = bin_to_template($template . '0');
            //Added a 0 since that's what GW does and GWFreaks needs this to be respected
            $template_name = preg_replace('@[];]@', '', preg_replace('@<br/>.*@', '', $build_name));
            if (empty($template_name)) {
                $template_name = gws_profession_abbr($primary);
                if ($secondary != 'No profession' && $secondary != $primary) {
                    $template_name .= '/' . gws_profession_abbr($secondary);
                }
            }
            $template_bbcode = "&#91;{$template_name};{$template_code}]";
            //Used &#91; to prevent double parsing anomalies
            $template_size = strlen($template_bbcode);
            $template_html = $gwbbcode_tpl['template'];
        } else {
            $template_error_msg = htmlspecialchars($invalid_template);
            $template_html = $gwbbcode_tpl['no_template'];
        }
    }
    //Show a box around skills if "box" is in the build attribute list
    if (preg_match("/ box/i", $att)) {
        $buildbox_left = 'class="gwbuildbox_left"';
        $buildbox_center = 'class="gwbuildbox_center"';
        $buildbox_right = 'class="gwbuildbox_right"';
    } else {
        $buildbox_left = '';
        $buildbox_center = '';
        $buildbox_right = '';
    }
    $tpl = $gwbbcode_tpl['build'];
    //Replace all "{var_name}" by $var_name till there is none to replace (i.e a tag replacement can contain other tags)
    do {
        $prev_tpl = $tpl;
        $tpl = preg_replace("#\\{\\{(.*?)\\}\\}#ise", "isset(\$gwbbcode_tpl['\\1'])?\$gwbbcode_tpl['\\1']:'\\0'", $tpl);
        //"{{skill_description}}" is replaced by $gwbbcode_tpl['skill_description']
        $tpl = preg_replace("#\\{(.*?)\\}#ise", "isset(\$\\1)?\$\\1:'\\0'", $tpl);
        //"{desc}" is replaced by $desc
    } while ($prev_tpl != $tpl);
    return $tpl;
}
Exemple #5
0
function build_replace($reg)
{
    global $gwbbcode_tpl;
    global $userdata;
    global $art_titel;
    $art_name = $art_titel;
    $gwbbcode_root_path = GWBBCODE_ROOT;
    list($all, $att, $skills) = $reg;
    $att = str_replace("\n", "<br/>\n", html_safe_decode($att));
    $load = rand();
    $build = $gwbbcode_tpl['build'];
    //Build name
    $build_name = gws_build_name($att);
    $build_name = str_replace('{br}', '<br/>', str_replace('{br/}', '<br/>', str_replace('{BR}', '<br/>', str_replace('{BR/}', '<br/>', $build_name))));
    //Professions
    $prof = gws_build_profession($att);
    $prof_imgs = '';
    $cursor = 'help';
    if ($prof !== false) {
        $prof_img = '<img class="build_icon" src="http://images.pvxbuilds.com/img_interface/{profession}.gif?r=1" style="cursor: {cursor};" onmouseover="return overlib(div(\'load' . $load . '\').innerHTML);" onmouseout="return nd();"/>';
        $primary = gws_prof_name($prof['primary']);
        $secondary = gws_prof_name($prof['secondary']);
        $showimg = '';
        $prof_imgs .= str_replace('{profession}', $primary, $prof_img);
        if ($secondary != 'No profession' && $secondary != $primary) {
            $prof_imgs .= str_replace('{profession}', $secondary, $prof_img);
        }
    } else {
        $showimg = ' ;display: none';
        $primary = '?';
        $secondary = '?';
    }
    //Attributes
    $attributes = '';
    foreach (explode(' ', gws_attributes_clean($att)) as $value) {
        $value = explode('=', $value);
        if ($att_name = gws_attr_name($value[0])) {
            $attributes .= str_replace('{attribute_name}', $att_name, $gwbbcode_tpl['attribute']);
            $value[1] = str_replace('+', ' + ', $value[1]);
            $attributes = str_replace('{attribute_value}', $value[1], $attributes);
        }
    }
    $skills = str_replace('[skill', '[skill ' . $att, $skills);
    //Build description
    $desc = preg_match('|desc=\\"([^"]+)\\"|', $att, $reg) ? $reg[1] : '';
    $desc = empty($desc) ? '' : $desc . '<br/>';
    $desc = str_replace('{br}', '<br/>', str_replace('{br/}', '<br/>', str_replace('{BR}', '<br/>', str_replace('{BR/}', '<br/>', $desc))));
    //Pickup status
    $pickup_id = preg_match('|pickup=\\"([^"]+)\\"|', $att, $reg) ? $reg[1] : '';
    //Get all pickup users
    $pickup = load(PICKUP_PATH);
    if (!empty($pickup_id) && $pickup !== false) {
        //Output status
        $cursor = 'pointer';
        $pickup = "Can play it: <span id=\"pickup_{$pickup_id}\">" . pickup_users($pickup, $userdata['username'], $pickup_id, 'No one can!') . '</span>';
        $pickup_link = " onclick=\"pickup('switch', '{$pickup_id}')\"";
    } else {
        $pickup = '';
        $pickup_link = '';
    }
    $prof_imgs = str_replace('{cursor}', $cursor, $prof_imgs);
    //Template: professions
    $invalid_template = false;
    static $prof_ids = array('No profession', 'Warrior', 'Ranger', 'Monk', 'Necromancer', 'Mesmer', 'Elementalist', 'Assassin', 'Ritualist', 'Paragon', 'Dervish');
    $template = '0111000000';
    $template .= int2bin(array_search($primary, $prof_ids), 4);
    $template .= int2bin(array_search($secondary, $prof_ids), 4);
    //Template: attributes
    static $attr_ids = array('fas', 'ill', 'dom', 'ins', 'blo', 'dea', 'sou', 'cur', 'air', 'ear', 'fir', 'wat', 'ene', 'hea', 'smi', 'pro', 'div', 'str', 'axe', 'ham', 'swo', 'tac', 'bea', 'exp', 'wil', 'mar', 29 => 'dag', 'dead', 'sha', 'com', 'res', 'cha', 'cri', 'spa', 'spe', 'comma', 'mot', 'lea', 'scy', 'win', 'earthp', 'mys');
    static $prof_attr_list = array('Air Magic' => 'Elementalist', 'Earth Magic' => 'Elementalist', 'Energy Storage' => 'Elementalist', 'Fire Magic' => 'Elementalist', 'Water Magic' => 'Elementalist', 'Domination Magic' => 'Mesmer', 'Fast Casting' => 'Mesmer', 'Illusion Magic' => 'Mesmer', 'Inspiration Magic' => 'Mesmer', 'Divine Favor' => 'Monk', 'Healing Prayers' => 'Monk', 'Protection Prayers' => 'Monk', 'Smiting Prayers' => 'Monk', 'Blood Magic' => 'Necromancer', 'Curses' => 'Necromancer', 'Death Magic' => 'Necromancer', 'Soul Reaping' => 'Necromancer', 'Beast Mastery' => 'Ranger', 'Expertise' => 'Ranger', 'Marksmanship' => 'Ranger', 'Wilderness Survival' => 'Ranger', 'Axe Mastery' => 'Warrior', 'Hammer Mastery' => 'Warrior', 'Strength' => 'Warrior', 'Swordsmanship' => 'Warrior', 'Tactics' => 'Warrior', 'Critical Strikes' => 'Assassin', 'Dagger Mastery' => 'Assassin', 'Deadly Arts' => 'Assassin', 'Shadow Arts' => 'Assassin', 'Spawning Power' => 'Ritualist', 'Channeling Magic' => 'Ritualist', 'Communing' => 'Ritualist', 'Restoration Magic' => 'Ritualist', 'Spear Mastery' => 'Paragon', 'Command' => 'Paragon', 'Motivation' => 'Paragon', 'Leadership' => 'Paragon', 'Scythe Mastery' => 'Dervish', 'Wind Prayers' => 'Dervish', 'Earth Prayers' => 'Dervish', 'Mysticism' => 'Dervish');
    $attr_list = attribute_list_raw($att);
    arsort($attr_list);
    //=> First attribute is attribute of highest level
    //Prepare a base attribute level and rune bonus list for primary and secondary attributes
    $attr_primary = array();
    $attr_secondary = array();
    $attr_runes = array();
    $available_helmet = true;
    foreach ($attr_list as $attr => $raw_level) {
        //Separate base level and bonus
        preg_match('@^([0-9]+)(\\+[+0-9]+)?@', $raw_level, $reg);
        $base_level = $reg[1];
        $bonus = isset($reg[2]) ? $reg[2] : '0';
        //Primary attributes
        if ($prof_attr_list[$attr] == $primary) {
            $bonus_level = @eval('return ' . $bonus . ';');
            //Invalid attribute level bonus
            if ($bonus_level > 4 || $bonus_level < 0 || $bonus_level == 4 && !$available_helmet) {
                $invalid_template = true;
            } else {
                if ($available_helmet && ($bonus_level == 4 || substr_count($bonus, '+') > 1 && strpos($bonus, '+1') !== false)) {
                    $available_helmet = false;
                    $attr_primary[$attr] = $base_level;
                    $attr_runes[$attr] = $bonus_level - 1;
                } else {
                    $attr_primary[$attr] = $base_level;
                    $attr_runes[$attr] = $bonus_level;
                }
            }
        } else {
            if ($prof_attr_list[$attr] == $secondary) {
                $attr_secondary[$attr] = $base_level;
            }
        }
    }
    //Manage primary attribute levels
    $points_secondary = attr_points($attr_secondary);
    if (!empty($attr_primary)) {
        //Set helmet if needed
        if ($available_helmet && (max($attr_primary) > 12 || attr_points($attr_primary) + $points_secondary > 200)) {
            reset($attr_primary);
            $attr_primary[key($attr_primary)]--;
            //First attribute is attribute of highest level, the one needing a helmet the most
        }
        //Assign runes
        while ((max($attr_primary) > 12 || attr_points($attr_primary) + $points_secondary > 200) && min($attr_runes) < 3) {
            arsort($attr_primary);
            foreach ($attr_runes as $attr => $rune) {
                if ($rune < 3) {
                    $attr_primary[$attr]--;
                    $attr_runes[$attr]++;
                    break;
                }
            }
        }
    }
    $attr_list = array_merge($attr_primary, $attr_secondary);
    $template .= int2bin(count($attr_list), 4);
    if (!empty($attr_list) && (max($attr_list) > 12 || min($attr_list) < 0 || attr_points($attr_list) > 200)) {
        $invalid_template = true;
    }
    $attr_bit_size = 5;
    $template_attrs = array();
    foreach ($attr_list as $attr => $level) {
        $id = array_search(gws_attribute_name($attr), $attr_ids);
        $template_attrs[$id] = $level;
        if ($id >= 32) {
            $attr_bit_size = 6;
        }
    }
    $template .= int2bin($attr_bit_size - 4, 4);
    ksort($template_attrs);
    foreach ($template_attrs as $id => $level) {
        $template .= int2bin($id, $attr_bit_size);
        $template .= int2bin($level, 4);
    }
    //Template: skills
    $skill_bit_size = 9;
    $template_skills = array();
    if (preg_match_all('#\\[skill[^\\]]*\\](.*?)\\[/skill\\][ ]?#isS', $skills, $regs, PREG_PATTERN_ORDER)) {
        foreach ($regs[1] as $skill_name) {
            if (($id = gws_skill_id($skill_name)) !== false) {
                $template_skills[] = $id;
                if ($id > 512) {
                    $skill_bit_size = 11;
                }
            }
        }
    }
    $template .= int2bin($skill_bit_size - 8, 4);
    if (count($template_skills) > 8) {
        $invalid_template = true;
    } else {
        foreach ($template_skills as $id) {
            $template .= int2bin($id, $skill_bit_size);
        }
        //Complete with 0s
        $template .= str_repeat(str_repeat('0', $skill_bit_size), 8 - count($template_skills));
    }
    //Manage template save icons
    if (strstr($att, 'nosave') !== false) {
        $template_download = '';
    } else {
        if (!$invalid_template) {
            //Prepare template bbcode
            $template_code = bin_to_template($template);
            $template_name = preg_replace('@[];]@', '', preg_replace('@<br/>.*@', '', $build_name));
            if (empty($template_name)) {
                $template_name = gws_profession_abbr($primary);
                if ($secondary != 'No profession' && $secondary != $primary) {
                    $template_name .= '/' . gws_profession_abbr($secondary);
                }
            }
            $p_abbr = gws_profession_abbr($primary);
            $s_abbr = gws_profession_abbr($secondary);
            // if our build has its own name, lets use it
            if (strlen($build_name) != 0) {
                $art_name = $p_abbr . "/" . $s_abbr . " " . $build_name;
            }
            $template_bbcode = "[{$art_name};{$template_code}]";
            $template_code = urlencode($template_code);
            $template_size = strlen($template_bbcode);
            $template_download = "<a href=\"\" onclick=\"return switch_template('{$load}');\"><img class=\"no_link\" src=\"http://images.pvxbuilds.com/img_interface/download.gif\" title=\"Copy {$template_bbcode}\" style=\"vertical-align: top;\"/></a>";
        } else {
            $template_download = "<img class=\"no_link\" src=\"http://images.pvxbuilds.com/img_interface/download_no.gif\" title=\"Incorrect build\" style=\"vertical-align: top;\"/>";
        }
    }
    //Show a box around skills if "box" is in the build attribute list
    if (strstr(strtolower($att), 'box') !== false) {
        $buildbox_left = 'class="buildbox_left"';
        $buildbox_center = 'class="buildbox_center"';
        $buildbox_right = 'class="buildbox_right"';
    } else {
        $buildbox_left = '';
        $buildbox_center = '';
        $buildbox_right = '';
    }
    return preg_replace("#\\{(.*?)\\}#ise", "isset(\$\\1)?\$\\1:'\\0'", $build);
}