function hunterslodge_customarmour_run()
{
    require_once "lib/sanitize.php";
    require_once "lib/names.php";
    global $session;
    $op = httpget("op");
    $free = httpget("free");
    page_header("Choose your Custom Armour");
    switch ($op) {
        case "change":
            output("Want to change your Custom Armour?  No problem.  Enter your desired armour in the box below.  You've got 25 characters to play around with.`n(leave this blank to disable custom armour naming and return to default, game-supplied armour names)`n`n");
            rawoutput("<form action='runmodule.php?module=hunterslodge_customarmour&op=confirm&free=" . $free . "' method='POST'>");
            $armour = get_module_pref("customarmour");
            rawoutput("<input id='input' name='newarmour' width='25' maxlength='25' value='" . htmlentities($armour, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "'>");
            rawoutput("<input type='submit' class='button' value='Preview'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=hunterslodge_customarmour&op=confirm&free=" . $free);
            addnav("Cancel");
            addnav("Don't set custom armour, just go back to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
        case "confirm":
            $newarmour = httppost("newarmour");
            $sub = httpget("sub");
            $newarmour = str_replace("`", "", $newarmour);
            $newarmour = comment_sanitize($newarmour);
            $newarmour = substr($newarmour, 0, 25);
            if ($newarmour) {
                output("Your new custom armour is:`n%s`nWould you like to set your new armour now?`n`n", $newarmour);
            } else {
                output("You've chosen to go back to the default, game-supplied armours.  Are you sure that's what you want?`n`n");
            }
            addnav("Confirm");
            addnav("Set custom armour", "runmodule.php?module=hunterslodge_customarmour&op=set&free={$free}&newarmour=" . rawurlencode($newarmour));
            addnav("Cancel");
            addnav("Don't set custom armour, just go back to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
        case "set":
            $newarmour = rawurldecode(httpget("newarmour"));
            if ($newarmour == "") {
                output("Your custom armour name has been removed.  The next time you change your armour, you'll return to game-supplied armour names.`n`n");
            } else {
                output("Your custom armour has been set to %s!`n`n", $newarmour);
                $session['user']['armor'] = $newarmour;
            }
            set_module_pref("customarmour", $newarmour);
            if (!$free) {
                require_once "modules/iitems/lib/lib.php";
                $id = has_item("hunterslodge_customarmour");
                delete_item($id);
            }
            addnav("Return");
            addnav("Return to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
    }
    page_footer();
}
function hunterslodge_namedmount_run()
{
    require_once "lib/sanitize.php";
    require_once "lib/names.php";
    global $session;
    global $playermount;
    $op = httpget("op");
    $free = httpget("free");
    page_header("Name your Mount");
    switch ($op) {
        case "change":
            output("Want to change your Mount's name?  No problem.  Enter your desired name in the box below.  You've got 25 characters to play around with.`n(leave this blank to disable mount naming)`n`n");
            rawoutput("<form action='runmodule.php?module=hunterslodge_namedmount&op=confirm&free=" . $free . "' method='POST'>");
            rawoutput("<input id='input' name='newname' width='25' maxlength='25' value='" . htmlentities($race, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "'>");
            rawoutput("<input type='submit' class='button' value='Preview'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=hunterslodge_namedmount&op=confirm&free=" . $free);
            addnav("Cancel");
            addnav("Don't set a mount name, just go back to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
        case "confirm":
            $newname = httppost("newname");
            $sub = httpget("sub");
            $newname = comment_sanitize($newname);
            $newname = substr($newname, 0, 25);
            if ($newname) {
                output("Your Mount's name is now:`n%s`0 the %s`nWould you like to set your mount's name now?`n`n", $newname, $playermount['mountname']);
            } else {
                output("You've chosen to go back to having an unnamed Mount.  Are you sure that's what you want?`n`n");
            }
            addnav("Confirm");
            addnav("Set mount name", "runmodule.php?module=hunterslodge_namedmount&op=set&free={$free}&newname=" . rawurlencode($newname));
            addnav("Cancel");
            addnav("Don't set a custom mount name, just go back to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
        case "set":
            $newname = rawurldecode(httpget("newname"));
            output("You now ride %s`0 the %s!`n`n", $newname, $playermount['mountname']);
            set_module_pref("mountname", $newname);
            if (!$free) {
                $id = has_item("hunterslodge_namedmount");
                delete_item($id);
            }
            addnav("Return");
            addnav("Return to the Lodge", "runmodule.php?module=iitems_hunterslodge&op=start");
            break;
    }
    page_footer();
}
     // If this is a module userpref handle and skip
     debug("Setting {$key} to {$val}");
     if (strstr($key, "___")) {
         $val = httppost($key);
         $x = explode("___", $key);
         $module = $x[0];
         $key = $x[1];
         modulehook("notifyuserprefchange", array("name" => $key, "old" => $oldvalues[$module . "___" . $key], "new" => $val));
         set_module_pref($key, $val, $module);
         continue;
     }
     $session['user']['prefs'][$key] = httppost($key);
 }
 $bio = stripslashes(httppost('bio'));
 $bio = comment_sanitize($bio);
 if ($bio != comment_sanitize($session['user']['bio'])) {
     if ($session['user']['biotime'] > "9000-01-01") {
         output("`\$You cannot modify your bio.");
         output("It has been blocked by the administrators!`0`n");
     } else {
         $session['user']['bio'] = $bio;
         $session['user']['biotime'] = date("Y-m-d H:i:s");
     }
 }
 $email = httppost('email');
 if ($email != $session['user']['emailaddress']) {
     if (is_email($email)) {
         if (getsetting("requirevalidemail", 0) == 1) {
             output("`#Your email cannot be changed, system settings prohibit it.");
             output("(Emails may only be changed if the server allows more than one account per email.)");
             output("Use the Petition link to ask the  server administrator to change your email address if this one is no longer valid.`n");
function viewcommentary($section, $message = "Interject your own commentary?", $limit = 10, $talkline = "says", $schema = false)
{
    global $session, $REQUEST_URI, $doublepost, $translation_namespace;
    global $emptypost;
    // *** DRAGONBG.COM CORE PATCH START ***
    if ($section) {
        rawoutput("<a name='{$section}'></a>");
        // Let's add a hook for modules to block commentary sections
        $args = modulehook("blockcommentarea", array("section" => $section));
        if (isset($args['block']) && $args['block'] == "yes") {
            return;
        }
    }
    // *** DRAGONBG.COM CORE PATCH END ***
    if ($schema === false) {
        $schema = $translation_namespace;
    }
    tlschema("commentary");
    $nobios = array("motd.php" => true);
    if (!array_key_exists(basename($_SERVER['SCRIPT_NAME']), $nobios)) {
        $nobios[basename($_SERVER['SCRIPT_NAME'])] = false;
    }
    if ($nobios[basename($_SERVER['SCRIPT_NAME'])]) {
        $linkbios = false;
    } else {
        $linkbios = true;
    }
    if ($message == "X") {
        $linkbios = true;
    }
    if ($doublepost) {
        output("`\$`bDouble post?`b`0`n");
    }
    if ($emptypost) {
        output("`\$`bWell, they say silence is a virtue.`b`0`n");
    }
    // *** DRAGONBG.COM CORE PATCH START ***
    $clanrankcolors = array(CLAN_APPLICANT => "`!", CLAN_MEMBER => "`#", CLAN_OFFICER => "`^", CLAN_LEADER => "`&", CLAN_FOUNDER => "`\$");
    $args = modulehook("clanrankcolors", array("clanrankcolors" => $clanrankcolors, "clanid" => $session['user']['clanid']));
    $clanrankcolors = $args['clanrankcolors'];
    // *** DRAGONBG.COM CORE PATCH END ***
    // Needs to be here because scrolling through the commentary pages, entering a bio, then scrolling again forward
    // then re-entering another bio will lead to $com being smaller than 0 and this will lead to an SQL error later on.
    $com = (int) httpget("comscroll");
    if ($com < 0) {
        $com = 0;
    }
    $cc = false;
    if (httpget("comscroll") !== false && (int) $session['lastcom'] == $com + 1) {
        $cid = (int) $session['lastcommentid'];
    } else {
        $cid = 0;
    }
    $session['lastcom'] = $com;
    if ($com > 0 || $cid > 0) {
        // Find newly added comments.
        // *** DRAGONBG.COM CORE PATCH START ***
        $sql = "SELECT COUNT(commentid) AS newadded FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author WHERE " . ($section ? "section='{$section}' AND " : '') . "(" . db_prefix("accounts") . ".locked=0 or " . db_prefix('accounts') . ".locked is null) AND commentid > '{$cid}'";
        $result = db_query($sql);
        $row = db_fetch_assoc($result);
        $newadded = $row['newadded'];
        // *** DRAGONBG.COM CORE PATCH END ***
    } else {
        $newadded = 0;
    }
    $commentbuffer = array();
    if ($cid == 0) {
        $sql = "SELECT " . db_prefix("commentary") . ".*, " . db_prefix("accounts") . ".name, " . db_prefix("accounts") . ".acctid, " . db_prefix("accounts") . ".clanrank, " . db_prefix("clans") . ".clanshort FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author LEFT JOIN " . db_prefix("clans") . " ON " . db_prefix("clans") . ".clanid=" . db_prefix("accounts") . ".clanid WHERE " . ($section ? "section='{$section}' AND " : '') . "( " . db_prefix("accounts") . ".locked=0 OR " . db_prefix("accounts") . ".locked is null ) " . "ORDER BY commentid DESC LIMIT " . $com * $limit . ",{$limit}";
        // *** DRAGONBG.COM CORE PATCH END ***
        if ($com == 0 && strstr($_SERVER['REQUEST_URI'], "/moderate.php") !== $_SERVER['REQUEST_URI']) {
            $result = db_query_cached($sql, "comments-{$section}");
        } else {
            $result = db_query($sql);
        }
        while ($row = db_fetch_assoc($result)) {
            $commentbuffer[] = $row;
        }
    } else {
        // *** DRAGONBG.COM CORE PATCH START ***
        $sql = "SELECT " . db_prefix("commentary") . ".*, " . db_prefix("accounts") . ".name, " . db_prefix("accounts") . ".acctid, " . db_prefix("accounts") . ".clanrank, " . db_prefix("clans") . ".clanshort FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author LEFT JOIN " . db_prefix("clans") . " ON " . db_prefix("clans") . ".clanid=" . db_prefix("accounts") . ".clanid WHERE " . ($section ? "section='{$section}' AND " : '') . "( " . db_prefix("accounts") . ".locked=0 OR " . db_prefix("accounts") . ".locked is null ) " . "AND commentid > '{$cid}' " . "ORDER BY commentid ASC LIMIT {$limit}";
        // *** DRAGONBG.COM CORE PATCH END ***
        $result = db_query($sql);
        while ($row = db_fetch_assoc($result)) {
            $commentbuffer[] = $row;
        }
        $commentbuffer = array_reverse($commentbuffer);
    }
    $rowcount = count($commentbuffer);
    if ($rowcount > 0) {
        $session['lastcommentid'] = $commentbuffer[0]['commentid'];
    }
    $counttoday = 0;
    $commentbuffer = modulehook("pagecommentary", $commentbuffer);
    // debug($commentbuffer);
    for ($i = 0; $i < $rowcount; $i++) {
        $row = $commentbuffer[$i];
        $row['comment'] = comment_sanitize($row['comment']);
        $commentids[$i] = $row['commentid'];
        if (date("Y-m-d", strtotime($row['postdate'])) == date("Y-m-d")) {
            if ($row['name'] == $session['user']['name']) {
                $counttoday++;
            }
        }
        $x = 0;
        $ft = "";
        for ($x = 0; strlen($ft) < 5 && $x < strlen($row['comment']); $x++) {
            if (substr($row['comment'], $x, 1) == "`" && strlen($ft) == 0) {
                $x++;
            } else {
                $ft .= substr($row['comment'], $x, 1);
            }
        }
        $link = "bio.php?char=" . $row['acctid'] . "&ret=" . URLEncode($_SERVER['REQUEST_URI']);
        if (substr($ft, 0, 2) == "::") {
            $ft = substr($ft, 0, 2);
        } elseif (substr($ft, 0, 1) == ":") {
            $ft = substr($ft, 0, 1);
        } elseif (substr($ft, 0, 3) == "/me") {
            $ft = substr($ft, 0, 3);
        }
        if ($row['clanrank']) {
            $row['name'] = ($row['clanshort'] > "" ? "{$clanrankcolors[$row['clanrank']]}&lt;`2{$row['clanshort']}{$clanrankcolors[$row['clanrank']]}&gt; `&" : "") . $row['name'];
        }
        if ($ft == "::" || $ft == "/me" || $ft == ":") {
            $x = strpos($row['comment'], $ft);
            if ($x !== false) {
                if ($linkbios) {
                    $op[$i] = str_replace("&amp;", "&", htmlentities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0<a href='{$link}' style='text-decoration: none'>\n`&{$row['name']}`0</a>\n`& " . str_replace("&amp;", "&", htmlentities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
                } else {
                    $op[$i] = str_replace("&amp;", "&", htmlentities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&{$row['name']}`0`& " . str_replace("&amp;", "&", htmlentities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
                }
                $rawc[$i] = str_replace("&amp;", "&", htmlentities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&{$row['name']}`0`& " . str_replace("&amp;", "&", htmlentities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
            }
        }
        if ($ft == "/game" && !$row['name']) {
            $x = strpos($row['comment'], $ft);
            if ($x !== false) {
                $op[$i] = str_replace("&amp;", "&", htmlentities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&" . str_replace("&amp;", "&", htmlentities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
            }
        }
        if (!isset($op) || !is_array($op)) {
            $op = array();
        }
        if (!array_key_exists($i, $op) || $op[$i] == "") {
            if ($linkbios) {
                $op[$i] = "`0<a href='{$link}' style='text-decoration: none'>`&{$row['name']}`0</a>`3 says, \"`#" . str_replace("&amp;", "&", htmlentities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
            } elseif (substr($ft, 0, 5) == '/game' && !$row['name']) {
                $op[$i] = str_replace("&amp;", "&", htmlentities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1")));
            } else {
                $op[$i] = "`&{$row['name']}`3 says, \"`#" . str_replace("&amp;", "&", htmlentities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
            }
            $rawc[$i] = "`&{$row['name']}`3 says, \"`#" . str_replace("&amp;", "&", htmlentities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
        }
        if (!array_key_exists('timestamp', $session['user']['prefs'])) {
            $session['user']['prefs']['timestamp'] = 0;
        }
        $session['user']['prefs']['timeoffset'] = round($session['user']['prefs']['timeoffset'], 1);
        if ($session['user']['prefs']['timestamp'] == 1) {
            if (!isset($session['user']['prefs']['timeformat'])) {
                $session['user']['prefs']['timeformat'] = "[m/d h:ia]";
            }
            $time = strtotime($row['postdate']) + $session['user']['prefs']['timeoffset'] * 60 * 60;
            $s = date("`7" . $session['user']['prefs']['timeformat'] . "`0 ", $time);
            $op[$i] = $s . $op[$i];
        } elseif ($session['user']['prefs']['timestamp'] == 2) {
            $s = reltime(strtotime($row['postdate']));
            $op[$i] = "`7({$s})`0 " . $op[$i];
        }
        if ($message == "X") {
            $op[$i] = "`0({$row['section']}) " . $op[$i];
        }
        if ($row['postdate'] >= $session['user']['recentcomments']) {
            $op[$i] = "<img src='images/new.gif' alt='&gt;' width='3' height='5' align='absmiddle'> " . $op[$i];
        }
        addnav("", $link);
        $auth[$i] = $row['author'];
        if (isset($rawc[$i])) {
            $rawc[$i] = full_sanitize($rawc[$i]);
            $rawc[$i] = htmlentities($rawc[$i], ENT_QUOTES, getsetting("charset", "ISO-8859-1"));
        }
    }
    $i--;
    $outputcomments = array();
    $sect = "x";
    $moderating = false;
    if ($session['user']['superuser'] & SU_EDIT_COMMENTS && $message == "X") {
        $moderating = true;
    }
    $del = translate_inline("Del");
    $scriptname = substr($_SERVER['SCRIPT_NAME'], strrpos($_SERVER['SCRIPT_NAME'], "/") + 1);
    $pos = strpos($_SERVER['REQUEST_URI'], "?");
    $return = $scriptname . ($pos == false ? "" : substr($_SERVER['REQUEST_URI'], $pos));
    $one = strstr($return, "?") == false ? "?" : "&";
    for (; $i >= 0; $i--) {
        $out = "";
        if ($moderating) {
            if ($session['user']['superuser'] & SU_EDIT_USERS) {
                $out .= "`0[ <input type='checkbox' name='comment[{$commentids[$i]}]'> | <a href='user.php?op=setupban&userid=" . $auth[$i] . "&reason=" . rawurlencode($rawc[$i]) . "'>Ban</a> ]&nbsp;";
                addnav("", "user.php?op=setupban&userid={$auth[$i]}&reason=" . rawurlencode($rawc[$i]));
            } else {
                $out .= "`0[ <input type='checkbox' name='comment[{$commentids[$i]}]'> ]&nbsp;";
            }
            $matches = array();
            preg_match("/[(]([^)]*)[)]/", $op[$i], $matches);
            $sect = trim($matches[1]);
            if (substr($sect, 0, 5) != "clan-" || $sect == $section) {
                if (substr($sect, 0, 4) != "pet-") {
                    $out .= $op[$i];
                    if (!isset($outputcomments[$sect]) || !is_array($outputcomments[$sect])) {
                        $outputcomments[$sect] = array();
                    }
                    array_push($outputcomments[$sect], $out);
                }
            }
        } else {
            if ($session['user']['superuser'] & SU_EDIT_COMMENTS) {
                $out .= "`2[<a href='" . $return . $one . "removecomment={$commentids[$i]}&section={$section}&returnpath=" . URLEncode($return) . "'>{$del}</a>`2]`0&nbsp;";
                addnav("", $return . $one . "removecomment={$commentids[$i]}&section={$section}&returnpath=" . URLEncode($return) . "");
            }
            $out .= $op[$i];
            if (!array_key_exists($sect, $outputcomments) || !is_array($outputcomments[$sect])) {
                $outputcomments[$sect] = array();
            }
            array_push($outputcomments[$sect], $out);
        }
    }
    if ($moderating) {
        $scriptname = substr($_SERVER['SCRIPT_NAME'], strrpos($_SERVER['SCRIPT_NAME'], "/") + 1);
        addnav("", "{$scriptname}?op=commentdelete&return=" . URLEncode($_SERVER['REQUEST_URI']));
        $mod_Del1 = htmlentities(translate_inline("Delete Checked Comments"), ENT_COMPAT, getsetting("charset", "ISO-8859-1"));
        $mod_Del2 = htmlentities(translate_inline("Delete Checked & Ban (3 days)"), ENT_COMPAT, getsetting("charset", "ISO-8859-1"));
        $mod_Del_confirm = addslashes(htmlentities(translate_inline("Are you sure you wish to ban this user and have you specified the exact reason for the ban, i.e. cut/pasted their offensive comments?"), ENT_COMPAT, getsetting("charset", "ISO-8859-1")));
        $mod_reason = translate_inline("Reason:");
        $mod_reason_desc = htmlentities(translate_inline("Banned for comments you posted."), ENT_COMPAT, getsetting("charset", "ISO-8859-1"));
        // *** DRAGONBG.COM CORE PATCH START ***
        output_notl("<form action='{$scriptname}?op=commentdelete&return=" . URLEncode($_SERVER['REQUEST_URI']) . "' method='POST' id='comments'>", true);
        // *** DRAGONBG.COM CORE PATCH END ***
        output_notl("<input type='submit' class='button' value=\"{$mod_Del1}\">", true);
        output_notl("<input type='submit' class='button' name='delnban' value=\"{$mod_Del2}\" onClick=\"return confirm('{$mod_Del_confirm}');\">", true);
        // *** DRAGONBG.COM CORE PATCH START ***
        $mod_checkall = htmlspecialchars(translate_inline("Check all"));
        // Check all - by Pr0t3ct0r
        output_notl('<script type="text/javascript">function checkall() { 
			var isChecked = document.getElementById("CheckAllID").checked 
			var f = document.getElementById("comments") 
			for (var i=0;i<f.length;i++) { 
			  if (f.elements[i].type == "checkbox"){ 
				  f.elements[i].checked = isChecked 
			  }
			} 
		}</script>', true);
        output_notl("<input type='checkbox' id='CheckAllID' onclick='checkall()' /> {$mod_checkall}", true);
        output_notl("`n{$mod_reason} <input name='reason0' id='reason0' size='40' value=\"{$mod_reason_desc}\" onChange=\"document.getElementById('reason').value=this.value;\">", true);
        // *** DRAGONBG.COM CORE PATCH END ***
    }
    //output the comments
    ksort($outputcomments);
    reset($outputcomments);
    $sections = commentarylocs();
    $needclose = 0;
    while (list($sec, $v) = each($outputcomments)) {
        if ($sec != "x") {
            output_notl("`n<hr><a href='moderate.php?area=%s'>`b`^%s`0`b</a>`n", $sec, isset($sections[$sec]) ? $sections[$sec] : "({$sec})", true);
            addnav("", "moderate.php?area={$sec}");
        }
        reset($v);
        while (list($key, $val) = each($v)) {
            $args = array('commentline' => $val, 'area' => $section);
            $args = modulehook("viewcommentary", $args);
            $val = $args['commentinfo'] . $args['commentline'];
            output_notl($val, true);
        }
    }
    $sql = "SELECT count(commentid) AS c FROM " . db_prefix("commentary") . " WHERE section='{$section}'";
    $r = db_query($sql);
    $val = db_fetch_assoc($r);
    $val = round($val['c'] / $limit + 0.5, 0) - 1;
    rawoutput("<table cellpadding=0 cellspacing=5 width=100%><tr><td valign=\"top\" width=50%>");
    // *** AJAX CHAT MOD START ***
    if (round($limit / 2, 0) - $counttoday < 3) {
        output("`)(You have %s posts left today)`n`0", round($limit / 2, 0) - $counttoday);
    }
    rawoutput('</div>');
    // *** AJAX CHAT MOD END ***
    if ($moderating && $needclose) {
        modulehook("}collapse");
        $needclose = 0;
    }
    if ($moderating) {
        output_notl("`n");
        rawoutput("<input type='submit' class='button' value=\"{$mod_Del1}\">");
        rawoutput("<input type='submit' class='button' name='delnban' value=\"{$mod_Del2}\" onClick=\"return confirm('{$mod_Del_confirm}');\">");
        output_notl("`n%s ", $mod_reason);
        // *** DRAGONBG.COM CORE PATCH START ***
        rawoutput("<input name='reason' size='40' id='reason' value=\"{$mod_reason_desc}\" onchange=\"document.getElementById('reason0').value=this.value;\">");
        // *** DRAGONBG.COM CORE PATCH END ***
        rawoutput("</form>");
        output_notl("`n");
    }
    if ($session['user']['loggedin']) {
        $args = modulehook("insertcomment", array("section" => $section));
        if (array_key_exists("mute", $args) && $args['mute'] && !($session['user']['superuser'] & SU_EDIT_COMMENTS)) {
            output_notl("%s", $args['mutemsg']);
        } elseif ($counttoday < $limit / 2 || $session['user']['superuser'] & ~SU_DOESNT_GIVE_GROTTO || !getsetting('postinglimit', 1)) {
            if ($message != "X") {
                $message = "`n`@{$message}`n";
                output($message);
                talkform($section, $talkline, $limit, $schema);
            }
        } else {
            $message = "`n`@{$message}`n";
            output($message);
            output("Sorry, you've exhausted your posts in this section for now.`0`n");
        }
    }
    $jump = false;
    if (!isset($session['user']['prefs']['nojump']) || $session['user']['prefs']['nojump'] == false) {
        $jump = true;
    }
    //new-style commentary display with page numbers
    if (!$cc) {
        db_free_result($result);
    }
    tlschema();
    if ($needclose) {
        modulehook("}collapse");
    }
    rawoutput("</td><td valign=\"top\" width=50%>");
    $nlink = comscroll_sanitize($REQUEST_URI);
    $nlink = str_replace("?&", "?", $nlink);
    if (!strpos($nlink, "?")) {
        $nlink = str_replace("&", "?", $nlink);
    }
    $nlink .= "&refresh=1";
    //reinstating back and forward links
    output_notl("`n");
    $prev = translate_inline("&lt;&lt;");
    $next = translate_inline("&gt;&gt;");
    if ($rowcount >= $limit || $cid > 0) {
        $req = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . ($com + 1);
        $req = str_replace("?&", "?", $req);
        if (!strpos($req, "?")) {
            $req = str_replace("&", "?", $req);
        }
        $req .= "&refresh=1";
        if ($jump) {
            $req .= "#{$section}";
        }
        output_notl("<a href=\"{$req}\">{$prev}</a> ", true);
        addnav("", $req);
    }
    output_notl("<a href=\"{$nlink}\">Refresh Commentary</a>", true);
    if ($com > 0 || $cid > 0 && $newadded > $limit) {
        $req = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . ($com - 1);
        $req = str_replace("?&", "?", $req);
        if (!strpos($req, "?")) {
            $req = str_replace("&", "?", $req);
        }
        $req .= "&refresh=1";
        if ($jump) {
            $req .= "#{$section}";
        }
        output_notl(" <a href=\"{$req}\">{$next}</a>", true);
        addnav("", $req);
    }
    //
    addnav("", $nlink);
    output("`n`n`0Jump to commentary page:");
    for ($i = $val; $i >= 0; $i--) {
        $nlink = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . $i;
        $nlink = str_replace("?&", "?", $nlink);
        if (!strpos($nlink, "?")) {
            $nlink = str_replace("&", "?", $nlink);
        }
        $nlink .= "&refresh=1";
        if ($jump) {
            $nlink .= "#{$section}";
        }
        $ndisp = 1 + $val - $i;
        if (httpget('comscroll') != $i) {
            output_notl("<a href=\"{$nlink}\">{$ndisp}</a> ", true);
            addnav("", $nlink);
        } else {
            output_notl("`@{$ndisp}`0 ", true);
        }
    }
    modulehook("commentaryoptions");
    rawoutput("</td></tr></table");
    // *** AJAX CHAT MOD START ***
    modulehook("viewcommentaryfooter");
    // *** AJAX CHAT MOD END ***
}
function commentaryicons_customrace_run()
{
    require_once "lib/sanitize.php";
    require_once "lib/names.php";
    global $session;
    $op = httpget("op");
    page_header("Custom Races");
    $costfirst = get_module_setting("initialpoints");
    $costsub = get_module_setting("extrapoints");
    $costperm = get_module_setting("permanent");
    $hasperm = get_module_pref("permanent");
    $playerpoints = $session['user']['donation'] - $session['user']['donationspent'];
    switch ($op) {
        case "change":
            output("Want to change your Custom Race?  No problem.  Enter your desired race in the box below.  You've got 25 characters to play around with.`n(leave this blank to disable custom race naming and return to default, game-supplied race names)`n`n");
            rawoutput("<form action='runmodule.php?module=commentaryicons_customrace&op=confirm&sub=change' method='POST'>");
            $race = get_module_pref("customrace");
            rawoutput("<input id='input' name='newrace' width='25' maxlength='25' value='" . htmlentities($race, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "'>");
            rawoutput("<input type='submit' class='button' value='Preview'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=commentaryicons_customrace&op=confirm&sub=change");
            break;
        case "firstchange":
            output("Changing your Custom Race will affect how other players see you.  In commentary areas, your race will show up as whatever you select here (the icon will be a little silver question mark, with the name of your race embedded in hover text like the other Race icons).  In the game mechanics, your race will be unchanged.  Think of it like a costume; you'll still be a %s inside, but your friends will think of you as whatever you enter in the box below.  You've got 25 characters to play around with.`n(leave this blank to disable custom race naming and return to default, game-supplied race names)`n`n", $session['user']['race']);
            rawoutput("<form action='runmodule.php?module=commentaryicons_customrace&op=confirm&sub=firstchange' method='POST'>");
            $race = get_module_pref("customrace");
            rawoutput("<input id='input' name='newrace' width='25' maxlength='25' value='" . htmlentities($race, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "'>");
            rawoutput("<input type='submit' class='button' value='Preview'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=commentaryicons_customrace&op=confirm&sub=firstchange");
            break;
        case "permanent":
            output("Buying permanent free changes means you'll pay %s points now, and then you can change your custom race as often as you like without paying again.`n`n", $costperm);
            addnav("Unlimited Custom Race changes");
            if ($playerpoints >= $costperm) {
                addnav(array("Buy permanent access (%s Points)", $costperm), "runmodule.php?module=commentaryicons_customrace&op=set&type=perm");
            } else {
                addnav(array("Sorry, but you need %s more points to do that.", $costperm - $playerpoints), "");
            }
            addnav("Cancel", "lodge.php");
            break;
        case "confirm":
            $newrace = httppost("newrace");
            $sub = httpget("sub");
            $newrace = str_replace("`", "", $newrace);
            $newrace = comment_sanitize($newrace);
            $newrace = substr($newrace, 0, 25);
            output("Your new custom race is:`n%s`nWould you like to set your new Race now?", $newrace);
            addnav("Confirm");
            switch ($sub) {
                case "change":
                    if ($hasperm) {
                        addnav("Set Custom Race (free)", "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=change");
                    } else {
                        addnav(array("Set Custom Race (%s Points)", $costsub), "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=change");
                    }
                    break;
                case "firstchange":
                    if ($hasperm) {
                        addnav("Set Custom Race (free)", "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=change");
                    } else {
                        addnav(array("Set Custom Race (%s Points)", $costfirst), "runmodule.php?module=commentaryicons_customrace&op=set&newrace=" . rawurlencode($newrace) . "&type=firstchange");
                    }
                    break;
            }
            break;
        case "set":
            $newrace = rawurldecode(httpget("newrace"));
            switch (httpget("type")) {
                case "change":
                    output("Your custom race has been set to %s!`n`n", $newrace);
                    set_module_pref("customrace", $newrace);
                    increment_module_pref("numchanges");
                    if (!get_module_pref("permanent")) {
                        $session['user']['donationspent'] += $costsub;
                        increment_module_setting("totalpoints", $costsub);
                    }
                    break;
                case "firstchange":
                    output("Your custom race has been set to %s!`n`n", $newrace);
                    set_module_pref("customrace", $newrace);
                    increment_module_pref("numchanges");
                    if (!get_module_pref("permanent")) {
                        $session['user']['donationspent'] += $costfirst;
                        increment_module_setting("totalpoints", $costfirst);
                    }
                    break;
                case "perm":
                    output("You've got permanent free custom race changes!  Woo!`n`n");
                    set_module_pref("permanent", 1);
                    $session['user']['donationspent'] += $costperm;
                    break;
            }
            break;
    }
    addnav("Return");
    addnav("L?Return to the Lodge", "lodge.php");
    page_footer();
}
function viewcommentary($section, $message = "Interject your own commentary?", $limit = 10, $talkline = "says", $schema = false)
{
    global $session, $REQUEST_URI, $doublepost, $translation_namespace;
    global $emptypost;
    rawoutput("<a name='{$section}'></a>");
    // Let's add a hook for modules to block commentary sections
    $args = modulehook("blockcommentarea", array("section" => $section));
    if (isset($args['block']) && $args['block'] == "yes") {
        return;
    }
    if ($schema === false) {
        $schema = $translation_namespace;
    }
    tlschema("commentary");
    $nobios = array("motd.php" => true);
    if (!array_key_exists(basename($_SERVER['SCRIPT_NAME']), $nobios)) {
        $nobios[basename($_SERVER['SCRIPT_NAME'])] = false;
    }
    if ($nobios[basename($_SERVER['SCRIPT_NAME'])]) {
        $linkbios = false;
    } else {
        $linkbios = true;
    }
    if ($message == "X") {
        $linkbios = true;
    }
    if ($doublepost) {
        output("`\$`bDouble post?`b`0`n");
    }
    if ($emptypost) {
        output("`\$`bWell, they say silence is a virtue.`b`0`n");
    }
    $clanrankcolors = array("`!", "`#", "`^", "`&", "`\$");
    // Needs to be here because scrolling through the commentary pages, entering a bio, then scrolling again forward
    // then re-entering another bio will lead to $com being smaller than 0 and this will lead to an SQL error later on.
    $com = (int) httpget("comscroll");
    if ($com < 0) {
        $com = 0;
    }
    $cc = false;
    if (httpget("comscroll") !== false && (int) $session['lastcom'] == $com + 1) {
        $cid = (int) $session['lastcommentid'];
    } else {
        $cid = 0;
    }
    $session['lastcom'] = $com;
    if ($com > 0 || $cid > 0) {
        // Find newly added comments.
        $sql = "SELECT COUNT(commentid) AS newadded FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author WHERE section='{$section}' AND " . "(" . db_prefix("accounts") . ".locked=0 or " . db_prefix('accounts') . ".locked is null) AND commentid > '{$cid}'";
        $result = db_query($sql);
        $row = db_fetch_assoc($result);
        $newadded = $row['newadded'];
    } else {
        $newadded = 0;
    }
    $commentbuffer = array();
    if ($cid == 0) {
        $sql = "SELECT " . db_prefix("commentary") . ".*, " . db_prefix("accounts") . ".name, " . db_prefix("accounts") . ".acctid, " . db_prefix("accounts") . ".clanrank, " . db_prefix("clans") . ".clanshort FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author LEFT JOIN " . db_prefix("clans") . " ON " . db_prefix("clans") . ".clanid=" . db_prefix("accounts") . ".clanid WHERE section = '{$section}' AND " . "( " . db_prefix("accounts") . ".locked=0 OR " . db_prefix("accounts") . ".locked is null ) " . "ORDER BY commentid DESC LIMIT " . $com * $limit . ",{$limit}";
        if ($com == 0 && strstr($_SERVER['REQUEST_URI'], "/moderate.php") !== $_SERVER['REQUEST_URI']) {
            $result = db_query_cached($sql, "comments-{$section}");
        } else {
            $result = db_query($sql);
        }
        while ($row = db_fetch_assoc($result)) {
            $commentbuffer[] = $row;
        }
    } else {
        $sql = "SELECT " . db_prefix("commentary") . ".*, " . db_prefix("accounts") . ".name, " . db_prefix("accounts") . ".acctid, " . db_prefix("accounts") . ".clanrank, " . db_prefix("clans") . ".clanshort FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author LEFT JOIN " . db_prefix("clans") . " ON " . db_prefix("clans") . ".clanid=" . db_prefix("accounts") . ".clanid WHERE section = '{$section}' AND " . "( " . db_prefix("accounts") . ".locked=0 OR " . db_prefix("accounts") . ".locked is null ) " . "AND commentid > '{$cid}' " . "ORDER BY commentid ASC LIMIT {$limit}";
        $result = db_query($sql);
        while ($row = db_fetch_assoc($result)) {
            $commentbuffer[] = $row;
        }
        $commentbuffer = array_reverse($commentbuffer);
    }
    $rowcount = count($commentbuffer);
    if ($rowcount > 0) {
        $session['lastcommentid'] = $commentbuffer[0]['commentid'];
    }
    $counttoday = 0;
    for ($i = 0; $i < $rowcount; $i++) {
        $row = $commentbuffer[$i];
        $row['comment'] = comment_sanitize($row['comment']);
        $commentids[$i] = $row['commentid'];
        if (date("Y-m-d", strtotime($row['postdate'])) == date("Y-m-d")) {
            if ($row['name'] == $session['user']['name']) {
                $counttoday++;
            }
        }
        $x = 0;
        $ft = "";
        for ($x = 0; strlen($ft) < 5 && $x < strlen($row['comment']); $x++) {
            if (substr($row['comment'], $x, 1) == "`" && strlen($ft) == 0) {
                $x++;
            } else {
                $ft .= substr($row['comment'], $x, 1);
            }
        }
        $link = "bio.php?char=" . $row['acctid'] . "&ret=" . URLEncode($_SERVER['REQUEST_URI']);
        if (substr($ft, 0, 2) == "::") {
            $ft = substr($ft, 0, 2);
        } elseif (substr($ft, 0, 1) == ":") {
            $ft = substr($ft, 0, 1);
        } elseif (substr($ft, 0, 3) == "/me") {
            $ft = substr($ft, 0, 3);
        }
        $row['comment'] = holidayize($row['comment'], 'comment');
        $row['name'] = holidayize($row['name'], 'comment');
        if ($row['clanrank']) {
            $row['name'] = ($row['clanshort'] > "" ? "{$clanrankcolors[ceil($row['clanrank'] / 10)]}&lt;`2{$row['clanshort']}{$clanrankcolors[ceil($row['clanrank'] / 10)]}&gt; `&" : "") . $row['name'];
        }
        if ($ft == "::" || $ft == "/me" || $ft == ":") {
            $x = strpos($row['comment'], $ft);
            if ($x !== false) {
                if ($linkbios) {
                    $op[$i] = str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0<a href='{$link}' style='text-decoration: none'>\n`&{$row['name']}`0</a>\n`& " . str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
                } else {
                    $op[$i] = str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&{$row['name']}`0`& " . str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
                }
                $rawc[$i] = str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&{$row['name']}`0`& " . str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
            }
        }
        if ($ft == "/game" && !$row['name']) {
            $x = strpos($row['comment'], $ft);
            if ($x !== false) {
                $op[$i] = str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&" . str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
            }
        }
        if (!isset($op) || !is_array($op)) {
            $op = array();
        }
        if (!array_key_exists($i, $op) || $op[$i] == "") {
            if ($linkbios) {
                $op[$i] = "`0<a href='{$link}' style='text-decoration: none'>`&{$row['name']}`0</a>`3 says, \"`#" . str_replace("&amp;", "&", HTMLEntities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
            } elseif (substr($ft, 0, 5) == '/game' && !$row['name']) {
                $op[$i] = str_replace("&amp;", "&", HTMLEntities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1")));
            } else {
                $op[$i] = "`&{$row['name']}`3 says, \"`#" . str_replace("&amp;", "&", HTMLEntities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
            }
            $rawc[$i] = "`&{$row['name']}`3 says, \"`#" . str_replace("&amp;", "&", HTMLEntities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
        }
        if (!array_key_exists('timestamp', $session['user']['prefs'])) {
            $session['user']['prefs']['timestamp'] = 0;
        }
        $session['user']['prefs']['timeoffset'] = round($session['user']['prefs']['timeoffset'], 1);
        if ($session['user']['prefs']['timestamp'] == 1) {
            if (!isset($session['user']['prefs']['timeformat'])) {
                $session['user']['prefs']['timeformat'] = "[m/d h:ia]";
            }
            $time = strtotime($row['postdate']) + $session['user']['prefs']['timeoffset'] * 60 * 60;
            $s = date("`7" . $session['user']['prefs']['timeformat'] . "`0 ", $time);
            $op[$i] = $s . $op[$i];
        } elseif ($session['user']['prefs']['timestamp'] == 2) {
            $s = reltime(strtotime($row['postdate']));
            $op[$i] = "`7({$s})`0 " . $op[$i];
        }
        if ($message == "X") {
            $op[$i] = "`0({$row['section']}) " . $op[$i];
        }
        if ($row['postdate'] >= $session['user']['recentcomments']) {
            $op[$i] = "<img src='images/new.gif' alt='&gt;' width='3' height='5' align='absmiddle'> " . $op[$i];
        }
        addnav("", $link);
        $auth[$i] = $row['author'];
        if (isset($rawc[$i])) {
            $rawc[$i] = full_sanitize($rawc[$i]);
            $rawc[$i] = htmlentities($rawc[$i], ENT_QUOTES, getsetting("charset", "ISO-8859-1"));
        }
    }
    $i--;
    $outputcomments = array();
    $sect = "x";
    $moderating = false;
    if ($session['user']['superuser'] & SU_EDIT_COMMENTS && $message == "X") {
        $moderating = true;
    }
    $del = translate_inline("Del");
    $scriptname = substr($_SERVER['SCRIPT_NAME'], strrpos($_SERVER['SCRIPT_NAME'], "/") + 1);
    $pos = strpos($_SERVER['REQUEST_URI'], "?");
    $return = $scriptname . ($pos == false ? "" : substr($_SERVER['REQUEST_URI'], $pos));
    $one = strstr($return, "?") == false ? "?" : "&";
    for (; $i >= 0; $i--) {
        $out = "";
        if ($moderating) {
            if ($session['user']['superuser'] & SU_EDIT_USERS) {
                $out .= "`0[ <input type='checkbox' name='comment[{$commentids[$i]}]'> | <a href='user.php?op=setupban&userid=" . $auth[$i] . "&reason=" . rawurlencode($rawc[$i]) . "'>Ban</a> ]&nbsp;";
                addnav("", "user.php?op=setupban&userid={$auth[$i]}&reason=" . rawurlencode($rawc[$i]));
            } else {
                $out .= "`0[ <input type='checkbox' name='comment[{$commentids[$i]}]'> ]&nbsp;";
            }
            $matches = array();
            preg_match("/[(]([^)]*)[)]/", $op[$i], $matches);
            $sect = trim($matches[1]);
            if (substr($sect, 0, 5) != "clan-" || $sect == $section) {
                if (substr($sect, 0, 4) != "pet-") {
                    $out .= $op[$i];
                    if (!isset($outputcomments[$sect]) || !is_array($outputcomments[$sect])) {
                        $outputcomments[$sect] = array();
                    }
                    array_push($outputcomments[$sect], $out);
                }
            }
        } else {
            if ($session['user']['superuser'] & SU_EDIT_COMMENTS) {
                $out .= "`2[<a href='" . $return . $one . "removecomment={$commentids[$i]}&section={$section}&returnpath=" . URLEncode($return) . "'>{$del}</a>`2]`0&nbsp;";
                addnav("", $return . $one . "removecomment={$commentids[$i]}&section={$section}&returnpath=" . URLEncode($return) . "");
            }
            $out .= $op[$i];
            if (!array_key_exists($sect, $outputcomments) || !is_array($outputcomments[$sect])) {
                $outputcomments[$sect] = array();
            }
            array_push($outputcomments[$sect], $out);
        }
    }
    if ($moderating) {
        $scriptname = substr($_SERVER['SCRIPT_NAME'], strrpos($_SERVER['SCRIPT_NAME'], "/") + 1);
        addnav("", "{$scriptname}?op=commentdelete&return=" . URLEncode($_SERVER['REQUEST_URI']));
        $mod_Del1 = htmlentities(translate_inline("Delete Checked Comments"), ENT_COMPAT, getsetting("charset", "ISO-8859-1"));
        $mod_Del2 = htmlentities(translate_inline("Delete Checked & Ban (3 days)"), ENT_COMPAT, getsetting("charset", "ISO-8859-1"));
        $mod_Del_confirm = addslashes(htmlentities(translate_inline("Are you sure you wish to ban this user and have you specified the exact reason for the ban, i.e. cut/pasted their offensive comments?"), ENT_COMPAT, getsetting("charset", "ISO-8859-1")));
        $mod_reason = translate_inline("Reason:");
        $mod_reason_desc = htmlentities(translate_inline("Banned for comments you posted."), ENT_COMPAT, getsetting("charset", "ISO-8859-1"));
        output_notl("<form action='{$scriptname}?op=commentdelete&return=" . URLEncode($_SERVER['REQUEST_URI']) . "' method='POST'>", true);
        output_notl("<input type='submit' class='button' value=\"{$mod_Del1}\">", true);
        output_notl("<input type='submit' class='button' name='delnban' value=\"{$mod_Del2}\" onClick=\"return confirm('{$mod_Del_confirm}');\">", true);
        output_notl("`n{$mod_reason} <input name='reason0' size='40' value=\"{$mod_reason_desc}\" onChange=\"document.getElementById('reason').value=this.value;\">", true);
    }
    //output the comments
    ksort($outputcomments);
    reset($outputcomments);
    $sections = commentarylocs();
    $needclose = 0;
    while (list($sec, $v) = each($outputcomments)) {
        if ($sec != "x") {
            if ($needclose) {
                modulehook("}collapse");
            }
            output_notl("`n<hr><a href='moderate.php?area=%s'>`b`^%s`0`b</a>`n", $sec, isset($sections[$sec]) ? $sections[$sec] : "({$sec})", true);
            addnav("", "moderate.php?area={$sec}");
            modulehook("collapse{", array("name" => "com-" . $sec));
            $needclose = 1;
        } else {
            modulehook("collapse{", array("name" => "com-" . $section));
            $needclose = 1;
        }
        reset($v);
        while (list($key, $val) = each($v)) {
            $args = array('commentline' => $val);
            $args = modulehook("viewcommentary", $args);
            $val = $args['commentline'];
            output_notl($val, true);
        }
    }
    if ($moderating && $needclose) {
        modulehook("}collapse");
        $needclose = 0;
    }
    if ($moderating) {
        output_notl("`n");
        rawoutput("<input type='submit' class='button' value=\"{$mod_Del1}\">");
        rawoutput("<input type='submit' class='button' name='delnban' value=\"{$mod_Del2}\" onClick=\"return confirm('{$mod_Del_confirm}');\">");
        output_notl("`n%s ", $mod_reason);
        rawoutput("<input name='reason' size='40' id='reason' value=\"{$mod_reason_desc}\">");
        rawoutput("</form>");
        output_notl("`n");
    }
    if ($session['user']['loggedin']) {
        $args = modulehook("insertcomment", array("section" => $section));
        if (array_key_exists("mute", $args) && $args['mute'] && !($session['user']['superuser'] & SU_EDIT_COMMENTS)) {
            output_notl("%s", $args['mutemsg']);
        } elseif ($counttoday < $limit / 2 || $session['user']['superuser'] & ~SU_DOESNT_GIVE_GROTTO || !getsetting('postinglimit', 1)) {
            if ($message != "X") {
                $message = "`n`@{$message}`n";
                output($message);
                talkform($section, $talkline, $limit, $schema);
            }
        } else {
            $message = "`n`@{$message}`n";
            output($message);
            output("Sorry, you've exhausted your posts in this section for now.`0`n");
        }
    }
    $jump = false;
    if (!isset($session['user']['prefs']['nojump']) || $session['user']['prefs']['nojump'] == false) {
        $jump = true;
    }
    $firstu = translate_inline("&lt;&lt; First Unseen");
    $prev = translate_inline("&lt; Previous");
    $ref = translate_inline("Refresh");
    $next = translate_inline("Next &gt;");
    $lastu = translate_inline("Last Page &gt;&gt;");
    if ($rowcount >= $limit || $cid > 0) {
        $sql = "SELECT count(commentid) AS c FROM " . db_prefix("commentary") . " WHERE section='{$section}' AND postdate > '{$session['user']['recentcomments']}'";
        $r = db_query($sql);
        $val = db_fetch_assoc($r);
        $val = round($val['c'] / $limit + 0.5, 0) - 1;
        if ($val > 0) {
            $first = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . $val;
            $first = str_replace("?&", "?", $first);
            if (!strpos($first, "?")) {
                $first = str_replace("&", "?", $first);
            }
            $first .= "&refresh=1";
            if ($jump) {
                $first .= "#{$section}";
            }
            output_notl("<a href=\"{$first}\">{$firstu}</a>", true);
            addnav("", $first);
        } else {
            output_notl($firstu, true);
        }
        $req = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . ($com + 1);
        $req = str_replace("?&", "?", $req);
        if (!strpos($req, "?")) {
            $req = str_replace("&", "?", $req);
        }
        $req .= "&refresh=1";
        if ($jump) {
            $req .= "#{$section}";
        }
        output_notl("<a href=\"{$req}\">{$prev}</a>", true);
        addnav("", $req);
    } else {
        output_notl("{$firstu} {$prev}", true);
    }
    $last = appendlink(comscroll_sanitize($REQUEST_URI), "refresh=1");
    // Okay.. we have some smart-ass (or stupidass, you guess) players
    // who think that the auto-reload firefox plugin is a good way to
    // avoid our timeouts.  Won't they be surprised when I take that little
    // hack away.
    $last = appendcount($last);
    $last = str_replace("?&", "?", $last);
    if ($jump) {
        $last .= "#{$section}";
    }
    //if (!strpos($last,"?")) $last = str_replace("&","?",$last);
    //debug($last);
    output_notl("&nbsp;<a href=\"{$last}\">{$ref}</a>&nbsp;", true);
    addnav("", $last);
    if ($com > 0 || $cid > 0 && $newadded > $limit) {
        $req = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . ($com - 1);
        $req = str_replace("?&", "?", $req);
        if (!strpos($req, "?")) {
            $req = str_replace("&", "?", $req);
        }
        $req .= "&refresh=1";
        if ($jump) {
            $req .= "#{$section}";
        }
        output_notl(" <a href=\"{$req}\">{$next}</a>", true);
        addnav("", $req);
        output_notl(" <a href=\"{$last}\">{$lastu}</a>", true);
    } else {
        output_notl("{$next} {$lastu}", true);
    }
    if (!$cc) {
        db_free_result($result);
    }
    tlschema();
    if ($needclose) {
        modulehook("}collapse");
    }
}
function commentaryarchive_run()
{
    global $session;
    popup_header("Commentary Export");
    debug($args);
    if ($session['user']['donation'] >= 1000) {
        $sec = $session['user']['chatloc'];
        if ($sec) {
            output("This is a HTML output of the entire Commentary section you're currently viewing, complete with colour codes.  Use it for archiving memorable roleplaying sessions, outputting on forums or blogs, or what-have-you.`n`nTo use it, copy-paste the output in the textarea below into your favourite plain-text editor (notepad will do in a pinch) and save the results as somefilenameoranother.html.`n`nIf you need help archiving, feel free to ask around for assistance in the Enquirer or Location Four.`n`n`bImportant`b - when trying to copy-paste (or even output) a commentary area with hundreds of commentary pages, your computer may hang for a while.  If this happens, quit pressing buttons, go and have a cup of tea and let it get on with it.`n`nHave fun!`n`n");
            $sql = "SELECT " . db_prefix("commentary") . ".*, " . db_prefix("accounts") . ".name, " . db_prefix("accounts") . ".acctid, " . db_prefix("accounts") . ".clanrank, " . db_prefix("clans") . ".clanshort FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author LEFT JOIN " . db_prefix("clans") . " ON " . db_prefix("clans") . ".clanid=" . db_prefix("accounts") . ".clanid WHERE " . ($sec ? "section='{$sec}' AND " : '') . "( " . db_prefix("accounts") . ".locked=0 OR " . db_prefix("accounts") . ".locked is null ) " . "ORDER BY commentid ASC";
            $result = db_query($sql);
            rawoutput("<textarea>");
            rawoutput("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            rawoutput("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
            rawoutput("        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
            rawoutput("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">");
            rawoutput("<head>");
            rawoutput("\t<title>Improbable Island Commentary Export from section " . $sec . "</title>");
            rawoutput("\t<meta http-equiv=\"content-type\" ");
            rawoutput("\t\tcontent=\"text/html;charset=utf-8\" />");
            rawoutput("\t<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />");
            rawoutput("\t<style type=\"text/css\">");
            rawoutput("\t\tbody {background-color: #C9B18B; font-family: georgia, serif; font-size:smaller; color:#111111;}");
            rawoutput("\t\t.colDkBlue    { color: #000040; }");
            rawoutput("\t\t.colDkGreen   { color: #004000; }");
            rawoutput("\t\t.colDkCyan    { color: #004040; }");
            rawoutput("\t\t.colDkRed     { color: #400000; }");
            rawoutput("\t\t.colDkMagenta { color: #400040; }");
            rawoutput("\t\t.colDkYellow  { color: #404000; }");
            rawoutput("\t\t.colDkWhite   { color: #303030; }");
            rawoutput("\t\t.colLtBlue    { color: #000060; }");
            rawoutput("\t\t.colLtGreen   { color: #006000; }");
            rawoutput("\t\t.colLtCyan    { color: #006060; }");
            rawoutput("\t\t.colLtRed     { color: #600000; }");
            rawoutput("\t\t.colLtMagenta { color: #600060; }");
            rawoutput("\t\t.colLtYellow  { color: #606000; }");
            rawoutput("\t\t.colLtWhite   { color: #505050; }");
            rawoutput("\t\t.colLtBlack   { color: #222222; }");
            rawoutput("\t\t.colDkOrange  { color: #4a2100; }");
            rawoutput("\t\t.colLtOrange  { color: #994400; }");
            rawoutput("\t\t.colBlue  \t{ color: #0070FF; }");
            rawoutput("\t\t.colLime  \t{ color: #DDFFBB; }");
            rawoutput("\t\t.colBlack  \t{ color: #000000; }");
            rawoutput("\t\t.colRose \t{ color: #9F819F; }");
            rawoutput("\t\t.colblueviolet \t{ color: #9A5BEE; }");
            rawoutput("\t\t.coliceviolet\t{ color: #6D7B9F; }");
            rawoutput("\t\t.colLtBrown \t{ color: #8F7D47; }");
            rawoutput("\t\t.colDkBrown \t{ color: #6b563f; }");
            rawoutput("\t\t.colXLtGreen\t{ color: #009900; }");
            rawoutput("\t\t.colAttention \t{ background-color: #00FF00; color: #FF0000; }");
            rawoutput("\t\t.colWhiteBlack \t{ background-color: #FFFFFF; color: #000000; }");
            rawoutput("\t\t.colbeige  { color: #F5F5DC; }");
            rawoutput("\t\t.colkhaki  { color: #F0E68C; }");
            rawoutput("\t\t.coldarkkhaki  { color: #5F5B35; }");
            rawoutput("\t\t.colaquamarine  { color: #7FFFD4; }");
            rawoutput("\t\t.coldarkseagreen  { color: #8FBC8F; }");
            rawoutput("\t\t.collightsalmon  { color: #8F6859; }");
            rawoutput("\t\t.colsalmon  { color: #7F5D4F; }");
            rawoutput("\t\t.colwheat  { color: #F5DEB3; }");
            rawoutput("\t\t.coltan  { color: #D2B48C; }");
            rawoutput("\t\t.colBack  \t{ background-color: #00FFFF; color: #000000; }");
            rawoutput("\t\t.colLtLinkBlue { color: #0069AF; }");
            rawoutput("\t\t.colDkLinkBlue { color: #004C7F; }");
            rawoutput("\t\t.colDkRust { color: #8D6060; }");
            rawoutput("\t\t.colLtRust { color: #B07878; }");
            rawoutput("\t\t.colMdBlue { color: #0000F0; }");
            rawoutput("\t\t.colMdGrey { color: #444444; }");
            rawoutput("\t\t.colburlywood { color: #DEB887; }");
            rawoutput("\t</style>");
            rawoutput("</head>");
            rawoutput("<body>");
            for ($i = 0; $i < db_num_rows($result); $i++) {
                $row = db_fetch_assoc($result);
                $row['comment'] = comment_sanitize($row['comment']);
                output("`0" . $row['postdate'] . ": " . $row['name'] . ": `#" . $row['comment'] . "</span><br />");
            }
            rawoutput("</body>");
            rawoutput("</html>");
            rawoutput("</textarea>");
        } else {
            output("You're not in any commentary area right now.`n`n");
        }
    } else {
        output("Commentary Export is a pretty high-load deal - for that reason, we've restricted it to donators only.  Sorry about that.`n`n");
    }
    // array(9) {
    // 'commentid' = '103'
    // 'section' = 'village-Mutant'
    // 'author' = '1'
    // 'comment' = '1'
    // 'postdate' = '2009-09-24 10:52:29'
    // 'name' = 'Admin CavemanJoe'
    // 'acctid' = '1'
    // 'clanrank' = '0'
    // 'clanshort' = ''
    // }
    popup_footer();
}
function hunterslodge_customrace_run()
{
    require_once "lib/sanitize.php";
    require_once "lib/names.php";
    global $session;
    $op = httpget("op");
    $free = httpget("free");
    $context = httpget("context");
    switch ($context) {
        case "village":
            $backlink = "village.php";
            break;
        case "forest":
            $backlink = "forest.php";
            break;
        case "worldmap":
            $backlink = "runmodule.php?module=worldmapen&op=continue";
            break;
        case "lodge":
            $backlink = "runmodule.php?module=iitems_hunterslodge&op=start";
            break;
    }
    page_header("Choose your Custom Race");
    switch ($op) {
        case "change":
            output("Want to change your Custom Race?  No problem.  Enter your desired race in the box below.  You've got 25 characters to play around with.`n(leave this blank to disable custom race naming and return to default, game-supplied race names)`n`n");
            rawoutput("<form action='runmodule.php?module=hunterslodge_customrace&op=confirm&context={$context}&free=" . $free . "' method='POST'>");
            $race = get_module_pref("customrace");
            rawoutput("<input id='input' name='newrace' width='25' maxlength='25' value='" . htmlentities($race, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "'>");
            rawoutput("<input type='submit' class='button' value='Preview'>");
            rawoutput("</form>");
            addnav("", "runmodule.php?module=hunterslodge_customrace&op=confirm&context={$context}&free=" . $free);
            addnav("Cancel");
            addnav("Don't set a custom race, just go back to where I came from", $backlink);
            break;
        case "confirm":
            $newrace = httppost("newrace");
            $sub = httpget("sub");
            $newrace = str_replace("`", "", $newrace);
            $newrace = comment_sanitize($newrace);
            $newrace = substr($newrace, 0, 25);
            if ($newrace) {
                output("Your new custom race is:`n%s`nWould you like to set your new Race now?`n`n", $newrace);
            } else {
                output("You've chosen to go back to the default, game-supplied races.  Are you sure that's what you want?`n`n");
            }
            addnav("Confirm");
            addnav("Set custom race", "runmodule.php?module=hunterslodge_customrace&op=set&free={$free}&context={$context}&newrace=" . rawurlencode($newrace));
            addnav("Cancel");
            addnav("Don't set a custom race, just go back to where I came from", $backlink);
            break;
        case "set":
            $newrace = rawurldecode(httpget("newrace"));
            output("Your custom race has been set to %s!`n`n", $newrace);
            set_module_pref("customrace", $newrace);
            if (!$free) {
                $id = has_item("hunterslodge_customrace");
                delete_item($id);
            }
            addnav("Return");
            addnav("Back to where I came from", $backlink);
            break;
    }
    page_footer();
}
function getcommentary($section, $limit = 25, $talkline, $customsql = false, $showmodlink = false)
{
    global $session, $REQUEST_URI, $translation_namespace;
    global $chatloc, $bottomcid;
    if ($showmodlink) {
        $link = buildcommentarylink("&bulkdelete=true&comscroll=" . $com);
        addnav("", $link);
        rawoutput("<form action=" . $link . " id='bulkdelete' method='post'>");
        $del = "Del";
        $undel = "UNDel";
    }
    //stops people from clicking on Bio links in the MoTD
    $nobios = array("motd.php" => true);
    if (!array_key_exists(basename($_SERVER['SCRIPT_NAME']), $nobios)) {
        $nobios[basename($_SERVER['SCRIPT_NAME'])] = false;
    }
    if ($nobios[basename($_SERVER['SCRIPT_NAME'])]) {
        $linkbios = false;
    } else {
        $linkbios = true;
    }
    // Needs to be here because scrolling through the commentary pages, entering a bio, then scrolling again forward
    // then re-entering another bio will lead to $com being smaller than 0 and this will lead to an SQL error later on.
    $com = (int) httpget("comscroll");
    if ($com < 0) {
        $com = 0;
    }
    if (httpget("comscroll") !== false && (int) $session['lastcom'] == $com + 1) {
        $cid = (int) $session['lastcommentid'];
    } else {
        $cid = 0;
    }
    $session['lastcom'] = $com;
    if (!$cid) {
        $cid = 1;
    }
    if ($customsql) {
        $sql = $customsql;
    } else {
        if ($section == "all") {
            $sql = "SELECT * FROM " . db_prefix("commentary") . " WHERE section NOT LIKE 'dwelling%' AND section NOT LIKE 'clan%' AND section NOT LIKE 'pet-%' ORDER BY commentid DESC LIMIT " . $com * $limit . ",{$limit}";
            $result = db_query($sql);
            $viewingallsections = 1;
        } else {
            $sql = "SELECT * FROM " . db_prefix("commentary") . " WHERE section='{$section}' ORDER BY commentid DESC LIMIT " . $com * $limit . ",{$limit}";
            if ($com) {
                $result = db_query($sql);
            } else {
                $result = db_query_cached($sql, "latestcommentary_" . $section);
            }
        }
    }
    $commentbuffer = array();
    while ($row = db_fetch_assoc($result)) {
        $row['info'] = @stripslashes($row['info']);
        $row['info'] = @unserialize($row['info']);
        if (!is_array($row['info'])) {
            $row['info'] = array();
        }
        $commentbuffer[] = $row;
    }
    //pre-formatting
    $commentbuffer = modulehook("commentbuffer-preformat", $commentbuffer);
    $rowcount = count($commentbuffer);
    if ($rowcount > 0) {
        $session['lastcommentid'] = $commentbuffer[0]['commentid'];
    }
    //figure out whether to handle absolute or relative time
    if (!array_key_exists('timestamp', $session['user']['prefs'])) {
        $session['user']['prefs']['timestamp'] = 0;
    }
    $session['user']['prefs']['timeoffset'] = round($session['user']['prefs']['timeoffset'], 1);
    if (!array_key_exists('commentary_reverse', $session['user']['prefs'])) {
        $session['user']['prefs']['commentary_reverse'] = 0;
    }
    //this array of userids means that with a single query we can figure out who's online and nearby
    $acctidstoquery = array();
    //prepare the actual comment line part of the comment
    for ($i = 0; $i < $rowcount; $i++) {
        if (!$commentbuffer[$i]['info']['hidecomment'] || $showmodlink) {
            $thiscomment = "";
            if ($viewingallsections) {
                $thiscomment .= "`b" . $row['section'] . "`0`b: ";
            }
            $row = $commentbuffer[$i];
            $row['acctid'] = $row['author'];
            $acctidstoquery[] = $row['author'];
            $row['comment'] = comment_sanitize($row['comment']);
            if (substr($row['comment'], 0, 1) == ":" || substr($row['comment'], 0, 3) == "/me") {
                $row['skiptalkline'] = true;
                //remove beginning /me
                $length = strlen($row['comment']);
                if (substr($row['comment'], 0, 3) == "/me") {
                    //debug("Match on ".$row['comment']);
                    $row['comment'] = substr($row['comment'], 3, $length);
                } else {
                    if (substr($row['comment'], 0, 2) == "::") {
                        //debug("Match on ".$row['comment']);
                        $row['comment'] = substr($row['comment'], 2, $length);
                    } else {
                        if (substr($row['comment'], 0, 1) == ":") {
                            //debug("Match on ".$row['comment']);
                            $row['comment'] = substr($row['comment'], 1, $length);
                        }
                    }
                }
            }
            if (substr($row['comment'], 0, 5) == "/game" && !$row['name'] || $row['info']['gamecomment']) {
                //debug("Game Comment: ".$row['comment']);
                $row['gamecomment'] = true;
                $row['skiptalkline'] = true;
                $row['info']['icons'] = array();
                $length = strlen($row['comment']);
                $row['comment'] = str_replace("/game", "", $row['comment']);
            }
            if ($linkbios) {
                $row['biolink'] = true;
            }
            if ($showmodlink) {
                if ($row['info']['hidecomment']) {
                    $link = buildcommentarylink("&restorecomment=" . $row['commentid'] . "&comscroll=" . $com);
                    $thiscomment .= "`0[<a href='{$link}'>{$undel}</a>]`0 <del>";
                    addnav("", $link);
                } else {
                    $link = buildcommentarylink("&removecomment=" . $row['commentid'] . "&comscroll=" . $com);
                    $thiscomment .= "`0[<a href='{$link}'>{$del}</a>] <input type='checkbox' name='deletecomment_" . $row['commentid'] . "'> `0 ";
                    addnav("", $link);
                }
            }
            if (!$row['gamecomment'] && ($row['info']['clanid'] || $row['info']['clanid'] === 0) && $row['info']['clanrank']) {
                $clanrankcolors = array(CLAN_APPLICANT => "`!", CLAN_MEMBER => "`#", CLAN_OFFICER => "`^", CLAN_LEADER => "`&", CLAN_FOUNDER => "`\$");
                $thiscomment .= "`0<a title=\"" . $row['info']['clanname'] . "\">&lt;" . $clanrankcolors[$row['info']['clanrank']] . $row['info']['clanshort'] . "`0&gt;</a>";
            }
            if ($row['biolink'] && !$row['gamecomment']) {
                $bio = "bio.php?char=" . $row['acctid'] . "&ret=" . URLEncode($_SERVER['REQUEST_URI']);
                if (!$row['skiptalkline']) {
                    $thiscomment .= "<a href=\"{$bio}\" style=\"text-decoration: none\">`&" . $row['name'] . "</a>`& ";
                } else {
                    $thiscomment .= "<a href=\"{$bio}\" style=\"text-decoration: none\">`&" . $row['name'] . "</a>`&";
                }
                addnav("", $bio);
            }
            // if ($row['skiptalkline']){
            // $thiscomment.="`&";
            // }
            if (!$row['skiptalkline']) {
                $thiscomment .= $talkline . " \"`#";
            }
            $thiscomment .= str_replace("&amp;", "&", htmlentities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1")));
            if (!$row['skiptalkline']) {
                $thiscomment .= "`0\"";
            }
            if ($row['info']['hidecomment']) {
                $thiscomment .= "</del>";
            }
            $commentbuffer[$i]['comment'] = $thiscomment;
            $commentbuffer[$i]['icons'] = $row['info']['icons'];
            $commentbuffer[$i]['time'] = strtotime($row['postdate']);
            if ($session['user']['prefs']['timestamp'] == 1) {
                if (!isset($session['user']['prefs']['timeformat'])) {
                    $session['user']['prefs']['timeformat'] = "[m/d h:ia]";
                }
                $time = strtotime($row['postdate']) + $session['user']['prefs']['timeoffset'] * 60 * 60;
                $s = date("`7" . $session['user']['prefs']['timeformat'] . "`0 ", $time);
                $commentbuffer[$i]['displaytime'] = $s;
            } elseif ($session['user']['prefs']['timestamp'] == 2) {
                $s = reltime(strtotime($row['postdate']));
                $commentbuffer[$i]['displaytime'] = "`7({$s})`0 ";
            }
        } else {
            unset($commentbuffer[$i]);
        }
        $bottomcid = $commentbuffer[$i]['commentid'];
    }
    //send through a modulehook for additional processing by modules
    $commentbuffer = modulehook("commentbuffer", $commentbuffer);
    //get offline/online/nearby status
    $acctids = join(',', $acctidstoquery);
    $onlinesql = "SELECT acctid, laston, loggedin, chatloc FROM " . db_prefix("accounts") . " WHERE acctid IN ({$acctids})";
    $onlineresult = db_query($onlinesql);
    $onlinestatus = array();
    $offline = date("Y-m-d H:i:s", strtotime("-" . getsetting("LOGINTIMEOUT", 900) . " seconds"));
    while ($row = db_fetch_assoc($onlineresult)) {
        $onlinestatus[$row['acctid']] = $row;
    }
    $onlinestatus[$session['user']['acctid']]['chatloc'] = $chatloc;
    $commentbuffer = array_values($commentbuffer);
    $rowcount = count($commentbuffer);
    for ($i = 0; $i < $rowcount; $i++) {
        if (isset($commentbuffer[$i])) {
            $row = $commentbuffer[$i];
            if ($onlinestatus[$row['author']]['chatloc'] == "AFK") {
                $commentbuffer[$i]['info']['online'] = -1;
                $icon = array('icon' => "images/icons/onlinestatus/afk.png", 'mouseover' => "Away from Keyboard");
                $commentbuffer[$i]['info']['icons']['online'] = $icon;
                continue;
            }
            if ($onlinestatus[$row['author']]['chatloc'] == "DNI") {
                $commentbuffer[$i]['info']['online'] = -1;
                $icon = array('icon' => "images/icons/onlinestatus/dni.png", 'mouseover' => "DNI (please don't try to talk to this player right now!)");
                $commentbuffer[$i]['info']['icons']['online'] = $icon;
                continue;
            }
            if ($onlinestatus[$row['author']]['laston'] < $offline || !$onlinestatus[$row['author']]['loggedin']) {
                $commentbuffer[$i]['info']['online'] = 0;
                $icon = array('icon' => "images/icons/onlinestatus/offline.png", 'mouseover' => "Offline");
            } else {
                if ($onlinestatus[$row['author']]['chatloc'] == $chatloc) {
                    $commentbuffer[$i]['info']['online'] = 2;
                    $icon = array('icon' => "images/icons/onlinestatus/nearby.png", 'mouseover' => "Nearby");
                } else {
                    $commentbuffer[$i]['info']['online'] = 1;
                    $icon = array('icon' => "images/icons/onlinestatus/online.png", 'mouseover' => "Online");
                }
            }
            $commentbuffer[$i]['info']['icons']['online'] = $icon;
        }
    }
    //debug($commentbuffer);
    return $commentbuffer;
}
function getcommentary($section, $limit = 25, $talkline = "says", $commentid = 0)
{
    global $session, $REQUEST_URI, $doublepost, $translation_namespace, $counttoday;
    $textreturn = "";
    if ((int) getsetting("expirecontent", 180) > 0 && e_rand(1, 1000) == 1) {
        $sql = "DELETE FROM " . db_prefix("commentary") . " WHERE postdate<'" . date("Y-m-d H:i:s", strtotime("-" . getsetting("expirecontent", 180) . " days")) . "'";
        db_query($sql);
    }
    $sql = "SELECT COUNT(commentid) AS newadded FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author WHERE section='{$section}' AND " . db_prefix("accounts") . ".locked=0 AND commentid > '{$commentid}'";
    $result = db_query($sql);
    $row = db_fetch_assoc($result);
    if ($row['newadded'] < 1) {
        return $commentid;
    }
    $newadded = $row['newadded'];
    $commentbuffer = array();
    //		if ($commentid == 0) {
    $sql = "SELECT " . db_prefix("commentary") . ".*, " . db_prefix("accounts") . ".name, " . db_prefix("accounts") . ".acctid, " . db_prefix("accounts") . ".clanrank, " . db_prefix("clans") . ".clanshort FROM " . db_prefix("commentary") . " LEFT JOIN " . db_prefix("accounts") . " ON " . db_prefix("accounts") . ".acctid = " . db_prefix("commentary") . ".author LEFT JOIN " . db_prefix("clans") . " ON " . db_prefix("clans") . ".clanid=" . db_prefix("accounts") . ".clanid WHERE " . ($section ? "section='{$section}' AND " : '') . "( " . db_prefix("accounts") . ".locked=0 OR " . db_prefix("accounts") . ".locked is null ) " . "AND commentid > '{$cid}' " . "ORDER BY commentid DESC LIMIT {$limit}";
    $result = db_query($sql);
    while ($row = db_fetch_assoc($result)) {
        $commentbuffer[] = $row;
    }
    /*		} else {
    			$sql = "SELECT " . db_prefix("commentary") . ".*, " .
    				db_prefix("accounts").".name, " . 
    				db_prefix("accounts").".login, " . 
    				db_prefix("accounts").".clanrank, " .
    				db_prefix("clans").".clanshort FROM " .
    				db_prefix("commentary") . " INNER JOIN " .
    				db_prefix("accounts") . " ON " .
    				db_prefix("accounts").".acctid = " .
    				db_prefix("commentary"). ".author LEFT JOIN " .
    				db_prefix("clans") . " ON " .
    				db_prefix("clans") . ".clanid=" .
    				db_prefix("accounts") .".clanid WHERE section = '$section' AND " .
    				db_prefix("accounts") . ".locked=0 AND commentid > '$commentid' ORDER BY commentid ASC LIMIT $limit";
    				$result = db_query($sql);
    				while ($row = db_fetch_assoc($result)) $commentbuffer[] = $row;
    				$commentbuffer = array_reverse($commentbuffer);
    		}
    */
    $rowcount = count($commentbuffer);
    if ($rowcount > 0) {
        $session['lastcommentid'] = $commentbuffer[0]['commentid'];
        $lastcommentid = $commentbuffer[0]['commentid'];
    }
    $counttoday = 0;
    for ($i = 0; $i < $rowcount; $i++) {
        $row = $commentbuffer[$i];
        $row['comment'] = comment_sanitize($row['comment']);
        $commentids[$i] = $row['commentid'];
        if (date("Y-m-d", strtotime($row['postdate'])) == date("Y-m-d")) {
            if ($row['name'] == $session['user']['name']) {
                $counttoday++;
            }
        }
        $x = 0;
        $ft = "";
        for ($x = 0; strlen($ft) < 5 && $x < strlen($row['comment']); $x++) {
            if (substr($row['comment'], $x, 1) == "`" && strlen($ft) == 0) {
                $x++;
            } else {
                $ft .= substr($row['comment'], $x, 1);
            }
        }
        $location = get_module_pref("location", "ajaxcommentary");
        if ($location) {
            $link = "bio.php?char=" . $row['author'] . "&ret=" . $location;
            addnav("", $link);
        } else {
            $link = '';
        }
        if (substr($ft, 0, 2) == "::") {
            $ft = substr($ft, 0, 2);
        } elseif (substr($ft, 0, 1) == ":") {
            $ft = substr($ft, 0, 1);
        } elseif (substr($ft, 0, 3) == "/me") {
            $ft = substr($ft, 0, 3);
        }
        $row['comment'] = holidayize($row['comment'], 'comment');
        $row['name'] = holidayize($row['name'], 'comment');
        $clanrankcolors = array(CLAN_APPLICANT => "`!", CLAN_MEMBER => "`#", CLAN_OFFICER => "`^", CLAN_LEADER => "`&", CLAN_FOUNDER => "`\$");
        if ($row['clanrank']) {
            $row['name'] = ($row['clanshort'] ? "{$clanrankcolors[$row['clanrank']]}&lt;`2{$row['clanshort']}{$clanrankcolors[$row['clanrank']]}&gt; `&" : "") . $row['name'];
        }
        if ($ft == "::" || $ft == "/me" || $ft == ":") {
            $x = strpos($row['comment'], $ft);
            if ($x !== false) {
                $op[$i] = str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0" . ($link ? "<a href='{$link}' style='text-decoration: none'>\n" : "") . "`&{$row['name']}`0" . ($link ? "</a>" : "") . "\n`& " . str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
                $rawc[$i] = str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&{$row['name']}`0`& " . str_replace("&amp;", "&", HTMLEntities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
            }
        }
        if ($ft == "/game" && !$row['name']) {
            $x = strpos($row['comment'], $ft);
            //if ($x!==false){
            $op[$i] = str_replace("&amp;", "&", htmlentities(substr($row['comment'], 0, $x), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`&" . str_replace("&amp;", "&", htmlentities(substr($row['comment'], $x + strlen($ft)), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0`n";
            //}
        }
        if (!isset($op) || !is_array($op)) {
            $op = array();
        }
        if (!array_key_exists($i, $op) || $op[$i] == "") {
            $op[$i] = "`0" . ($link ? "<a href='{$link}' style='text-decoration: none'>\n" : "") . "`&{$row['name']}`0" . ($link ? "</a>" : "") . "`3 says, \"`#" . str_replace("&amp;", "&", HTMLEntities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
            $rawc[$i] = "`&{$row['name']}`3 says, \"`#" . str_replace("&amp;", "&", HTMLEntities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`3\"`0`n";
        }
        if (!array_key_exists('timestamp', $session['user']['prefs'])) {
            $session['user']['prefs']['timestamp'] = 0;
        }
        if ($session['user']['prefs']['timestamp'] == 1) {
            if (!isset($session['user']['prefs']['timeformat'])) {
                $session['user']['prefs']['timeformat'] = "[m/d h:ia]";
            }
            $time = strtotime($row['postdate']) + $session['user']['prefs']['timeoffset'] * 60 * 60;
            $s = "`7" . date($session['user']['prefs']['timeformat'], $time) . "`0 ";
            $op[$i] = $s . $op[$i];
        } elseif ($session['user']['prefs']['timestamp'] == 2) {
            $s = reltime(strtotime($row['postdate']));
            $op[$i] = "`7({$s})`0 " . $op[$i];
        }
        if ($row['postdate'] >= $session['user']['recentcomments']) {
            $op[$i] = "<img src='images/new.gif' alt='&gt;' width='3' height='5' align='absmiddle'> " . $op[$i];
        }
        $auth[$i] = $row['author'];
        $rawc[$i] = full_sanitize($rawc[$i]);
        $rawc[$i] = htmlentities($rawc[$i], ENT_QUOTES, getsetting("charset", "ISO-8859-1"));
    }
    $outputcomments = array();
    $sect = "x";
    for (; $i > -1; $i--) {
        $out = "";
        $out .= $op[$i];
        if (!array_key_exists($sect, $outputcomments) || !is_array($outputcomments[$sect])) {
            $outputcomments[$sect] = array();
        }
        array_push($outputcomments[$sect], $out);
    }
    ksort($outputcomments);
    reset($outputcomments);
    $sections = commentarylocs();
    while (list($sec, $v) = each($outputcomments)) {
        reset($v);
        while (list($key, $val) = each($v)) {
            $args = array('commentline' => $val);
            $args = modulehook("viewcommentary", $args);
            $val = $args['commentline'];
            output_notl($val, true);
        }
    }
    return $lastcommentid;
}
        rawoutput("<td><input type='checkbox' name='mod[{$row['modid']}]' value='1'></td>");
        rawoutput("<td>");
        output_notl("%s", $row['name']);
        rawoutput("</td>");
        rawoutput("<td>");
        output_notl("%s", $row['moddate']);
        rawoutput("</td>");
        rawoutput("<td>");
        $comment = unserialize($row['comment']);
        output_notl("`0(%s)", $comment['section']);
        if ($comment['clanrank'] > 0) {
            output_notl("%s<%s%s>`0", $clanrankcolors[ceil($comment['clanrank'] / 10)], $comment['clanshort'], $clanrankcolors[ceil($comment['clanrank'] / 10)]);
        }
        output_notl("%s", $comment['name']);
        output_notl("-");
        output_notl("%s", comment_sanitize($comment['comment']));
        rawoutput("</td>");
        rawoutput("</tr>");
    }
    rawoutput("</table>");
    rawoutput("<input type='submit' class='button' value='{$unmod}'>");
    rawoutput("</form>");
}
addnav("Sections");
tlschema("commentary");
$vname = getsetting("villagename", LOCATION_FIELDS);
addnav(array("%s Square", $vname), "moderate.php?area=village");
if ($session['user']['superuser'] & ~SU_DOESNT_GIVE_GROTTO) {
    addnav("Grotto", "moderate.php?area=superuser");
}
addnav("Land of the Shades", "moderate.php?area=shade");
function viewcommentary($section, $message = "Interject your own commentary?", $limit = 10, $talkline = "says", $schema = false)
{
    global $session, $REQUEST_URI, $doublepost, $translation_namespace;
    global $emptypost;
    global $chatloc;
    $chatloc = $section;
    if ($section) {
        rawoutput("<a name='{$section}'></a>");
        // Let's add a hook for modules to block commentary sections
        $args = modulehook("blockcommentarea", array("section" => $section));
        if (isset($args['block']) && $args['block'] == "yes") {
            return;
        }
    }
    //stops people from clicking on Bio links in the MoTD
    $nobios = array("motd.php" => true);
    if (!array_key_exists(basename($_SERVER['SCRIPT_NAME']), $nobios)) {
        $nobios[basename($_SERVER['SCRIPT_NAME'])] = false;
    }
    if ($nobios[basename($_SERVER['SCRIPT_NAME'])]) {
        $linkbios = false;
    } else {
        $linkbios = true;
    }
    if ($doublepost) {
        output("`\$`bDouble post?`b`0`n");
    }
    if ($emptypost) {
        output("`\$`bWell, they say silence is a virtue.`b`0`n");
    }
    // Needs to be here because scrolling through the commentary pages, entering a bio, then scrolling again forward
    // then re-entering another bio will lead to $com being smaller than 0 and this will lead to an SQL error later on.
    $com = (int) httpget("comscroll");
    if ($com < 0) {
        $com = 0;
    }
    $cc = false;
    if (httpget("comscroll") !== false && (int) $session['lastcom'] == $com + 1) {
        $cid = (int) $session['lastcommentid'];
    } else {
        $cid = 0;
    }
    $session['lastcom'] = $com;
    //getting clans takes up far too much in the way of resources.  What we really need is a brand new commentary table with an info field, into which the clan ranks and icons and such can go.
    //Functionality that keeps information updated such as the player's name, their clan, whether or not they're banned etc. can go away.
    if (!$cid) {
        $cid = 1;
    }
    $sql = "SELECT * FROM " . db_prefix("commentary") . " WHERE commentid > '{$cid}' AND section='{$section}' ORDER BY commentid DESC LIMIT " . $com * $limit . ",{$limit}";
    $result = db_query($sql);
    $commentbuffer = array();
    while ($row = db_fetch_assoc($result)) {
        $row['info'] = @unserialize($row['info']);
        if (!is_array($row['info'])) {
            $row['info'] = array();
        }
        $commentbuffer[] = $row;
    }
    debug($commentbuffer);
    $commentbuffer = modulehook("commentbuffer", $commentbuffer);
    debug($commentbuffer);
    $rowcount = count($commentbuffer);
    if ($rowcount > 0) {
        $session['lastcommentid'] = $commentbuffer[0]['commentid'];
    }
    //obtain return link
    $scriptname = substr($_SERVER['SCRIPT_NAME'], strrpos($_SERVER['SCRIPT_NAME'], "/") + 1);
    $pos = strpos($_SERVER['REQUEST_URI'], "?");
    $return = $scriptname . ($pos == false ? "" : substr($_SERVER['REQUEST_URI'], $pos));
    $one = strstr($return, "?") == false ? "?" : "&";
    //figure out whether to handle absolute or relative time
    if (!array_key_exists('timestamp', $session['user']['prefs'])) {
        $session['user']['prefs']['timestamp'] = 0;
    }
    $session['user']['prefs']['timeoffset'] = round($session['user']['prefs']['timeoffset'], 1);
    //this array of userids means that with a single query we can figure out who's online and nearby
    $acctidstoquery = array();
    //prepare the actual comment line part of the comment
    for ($i = 0; $i < $rowcount; $i++) {
        $thiscomment = "";
        $row = $commentbuffer[$i];
        $row['acctid'] = $row['author'];
        $acctidstoquery[] = $row['author'];
        $row['comment'] = comment_sanitize($row['comment']);
        if (substr($row['comment'], 0, 1) == ":" || substr($row['comment'], 0, 3) == "/me") {
            $row['skiptalkline'] = true;
        }
        if (substr($row['comment'], 0, 5) == "/game" && !$row['name'] || $row['info']['gamecomment']) {
            $row['gamecomment'] = true;
            $row['skiptalkline'] = true;
            $row['info']['icons'] = array();
        }
        if ($linkbios) {
            $row['biolink'] = true;
        }
        if ($session['user']['superuser'] & SU_EDIT_COMMENTS) {
            $row['modlink'] = true;
        }
        if ($row['modlink']) {
            $thiscomment .= "`2[<a href='" . $return . $one . "removecomment=" . $row['commentid'] . "&returnpath=" . URLEncode($return) . "'>{$del}</a>`2] ";
            addnav("", $return . $one . "removecomment=" . $row['commentid'] . "&returnpath=" . URLEncode($return) . "");
        }
        if ($row['biolink'] && !$row['gamecomment']) {
            $bio = "bio.php?char=" . $row['acctid'] . "&ret=" . URLEncode($_SERVER['REQUEST_URI']);
            $thiscomment .= "<a href=\"{$bio}\">`0" . $row['name'] . "`0</a> ";
            addnav("", $bio);
        }
        if (!$row['skiptalkline']) {
            $thiscomment .= $talkline . " \"`#";
        }
        $thiscomment .= str_replace("&amp;", "&", htmlentities($row['comment'], ENT_COMPAT, getsetting("charset", "ISO-8859-1"))) . "`0\"";
        $commentbuffer[$i]['comment'] = $thiscomment;
        $commentbuffer[$i]['icons'] = $row['info']['icons'];
        $commentbuffer[$i]['time'] = strtotime($row['postdate']);
        if ($session['user']['prefs']['timestamp'] == 1) {
            if (!isset($session['user']['prefs']['timeformat'])) {
                $session['user']['prefs']['timeformat'] = "[m/d h:ia]";
            }
            $time = strtotime($row['postdate']) + $session['user']['prefs']['timeoffset'] * 60 * 60;
            $s = date("`7" . $session['user']['prefs']['timeformat'] . "`0 ", $time);
            $commentbuffer[$i]['displaytime'] = $s;
        } elseif ($session['user']['prefs']['timestamp'] == 2) {
            $s = reltime(strtotime($row['postdate']));
            $commentbuffer[$i]['displaytime'] = "`7({$s})`0 ";
        }
    }
    //get offline/online/nearby status
    $acctids = join(',', $acctidstoquery);
    $onlinesql = "SELECT acctid, laston, loggedin, chatloc FROM " . db_prefix("accounts") . " WHERE acctid IN ({$acctids})";
    $onlineresult = db_query($onlinesql);
    $onlinestatus = array();
    $offline = date("Y-m-d H:i:s", strtotime("-" . getsetting("LOGINTIMEOUT", 900) . " seconds"));
    while ($row = db_fetch_assoc($onlineresult)) {
        $onlinestatus[$row['acctid']] = $row;
    }
    for ($i = 0; $i < $rowcount; $i++) {
        $row = $commentbuffer[$i];
        if ($onlinestatus[$row['author']]['laston'] < $offline || !$onlinestatus[$row['author']]['loggedin']) {
            $commentbuffer[$row]['online'] = 0;
            $commentbuffer[$row]['icons'][] = "images/offline.png";
        } else {
            if ($onlinestatus[$row['author']]['chatloc'] == $chatloc) {
                $commentbuffer[$row]['online'] = 2;
                $commentbuffer[$row]['icons'][] = "images/nearby.png";
            } else {
                $commentbuffer[$row]['online'] = 1;
                $commentbuffer[$row]['icons'][] = "images/online.png";
            }
        }
    }
    $finaloutput = "";
    //output the comments!
    for ($i = 0; $i < $rowcount; $i++) {
        $row = $commentbuffer[$i];
        $icons = $row['icons'];
        foreach ($icons as $icon) {
            $finaloutput .= $icon;
        }
        $finaloutput .= $row['displaytime'];
        $finaloutput .= $row['comment'];
        output_notl("{$finaloutput}`n");
    }
    // debug($commentbuffer);
    //output the comments
    // ksort($outputcomments);
    // reset($outputcomments);
    // $sections = commentarylocs();
    // $needclose = 0;
    // while (list($sec,$v)=each($outputcomments)){
    // if ($sec!="x") {
    // output_notl("`n<hr><a href='moderate.php?area=%s'>`b`^%s`0`b</a>`n",$sec, isset($sections[$sec]) ? $sections[$sec] : "($sec)", true);
    // addnav("", "moderate.php?area=$sec");
    // }
    // reset($v);
    // while (list($key,$val)=each($v)){
    // $args = array('commentline'=>$val,'area'=>$section);
    // $args = modulehook("viewcommentary", $args);
    // $val = $args['commentinfo'].$args['commentline'];
    // output_notl($val, true);
    // }
    // }
    //Output page jumpers
    // $sql = "SELECT count(commentid) AS c FROM " . db_prefix("commentary") . " WHERE section='$section'";
    // $r = db_query($sql);
    // $val = db_fetch_assoc($r);
    // $val = round($val['c'] / $limit + 0.5,0) - 1;
    rawoutput("<table cellpadding=0 cellspacing=5 width=100%><tr><td valign=\"top\" width=50%>");
    if ($session['user']['loggedin']) {
        if ($message != "X") {
            $message = "`n`@{$message}`n";
            output($message);
            talkform($section, $talkline, $limit, $schema);
        }
    }
    $jump = false;
    if (!isset($session['user']['prefs']['nojump']) || $session['user']['prefs']['nojump'] == false) {
        $jump = true;
    }
    //new-style commentary display with page numbers
    // if (!$cc) db_free_result($result);
    // tlschema();
    // if ($needclose) modulehook("}collapse");
    rawoutput("</td><td valign=\"top\" width=50%>");
    $nlink = comscroll_sanitize($REQUEST_URI);
    $nlink = str_replace("?&", "?", $nlink);
    if (!strpos($nlink, "?")) {
        $nlink = str_replace("&", "?", $nlink);
    }
    $nlink .= "&refresh=1";
    //reinstating back and forward links
    output_notl("`n");
    $prev = translate_inline("&lt;&lt;");
    $next = translate_inline("&gt;&gt;");
    if ($rowcount >= $limit || $cid > 0) {
        $req = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . ($com + 1);
        $req = str_replace("?&", "?", $req);
        if (!strpos($req, "?")) {
            $req = str_replace("&", "?", $req);
        }
        $req .= "&refresh=1";
        if ($jump) {
            $req .= "#{$section}";
        }
        output_notl("<a href=\"{$req}\">{$prev}</a> ", true);
        addnav("", $req);
    }
    output_notl("<a href=\"{$nlink}\">Refresh Commentary</a>", true);
    if ($com > 0 || $cid > 0 && $newadded > $limit) {
        $req = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . ($com - 1);
        $req = str_replace("?&", "?", $req);
        if (!strpos($req, "?")) {
            $req = str_replace("&", "?", $req);
        }
        $req .= "&refresh=1";
        if ($jump) {
            $req .= "#{$section}";
        }
        output_notl(" <a href=\"{$req}\">{$next}</a>", true);
        addnav("", $req);
    }
    //
    addnav("", $nlink);
    output("`n`n`0Jump to commentary page:");
    for ($i = $val; $i >= 0; $i--) {
        $nlink = comscroll_sanitize($REQUEST_URI) . "&comscroll=" . $i;
        $nlink = str_replace("?&", "?", $nlink);
        if (!strpos($nlink, "?")) {
            $nlink = str_replace("&", "?", $nlink);
        }
        $nlink .= "&refresh=1";
        if ($jump) {
            $nlink .= "#{$section}";
        }
        $ndisp = 1 + $val - $i;
        if (httpget('comscroll') != $i) {
            output_notl("<a href=\"{$nlink}\">{$ndisp}</a> ", true);
            addnav("", $nlink);
        } else {
            output_notl("`@{$ndisp}`0 ", true);
        }
    }
    modulehook("commentaryoptions");
    rawoutput("</td></tr></table");
    // *** AJAX CHAT MOD START ***
    //modulehook("viewcommentaryfooter");
    // *** AJAX CHAT MOD END ***
}
function namedmount_run()
{
    require_once "lib/sanitize.php";
    global $session;
    global $playermount;
    $op = httpget("op");
    if (count($playermount) == 0 && $op != "permanent") {
        page_header("Hunter's Lodge");
        output("You have to have a mount in order to name it, silly!");
        addnav("L?Return to the Lodge", "lodge.php");
        page_footer();
    }
    $pointsavailable = $session['user']['donation'] - $session['user']['donationspent'];
    $permcost = get_module_setting("permanent");
    if ($op == "permanent") {
        page_header("Unlimited Mount Name Changes");
        output("For %s Donator Points, you can change the name of your Mount as often as you like without paying again.`n`n", $permcost);
        addnav("Unlimited Changes");
        if ($pointsavailable >= $permcost) {
            addnav(array("Get permanent free Mount Name changes (%s Points)", $permcost), "runmodule.php?module=namedmount&op=permanentconfirm");
        } else {
            addnav(array("Sorry, but you need %s more Donator Points for this option.", $permcost - $pointsavailable), "");
        }
        addnav("Cancel", "lodge.php");
        page_footer();
    }
    if ($op == "permanentconfirm") {
        page_header("Unlimited Mount Name Changes");
        output("You've got unlimited Mount Name Changes!");
        addnav("Back to the Lodge", "lodge.php");
        set_module_pref("permanent", 1);
        $session['user']['donationspent'] += $permcost;
        page_footer();
    }
    if ($op == "setname" || $op == "preview") {
        page_header("Hunter's Lodge");
        $name = get_module_pref("mountname");
        $boughtbefore = get_module_pref("boughtbefore");
        $perm = get_module_pref("permanent");
        if ($perm) {
            output("You've got unlimited Mount name changes, so you can change your Mount's name for free.`n");
            $cost = 0;
        } else {
            if ($boughtbefore) {
                $cost = get_module_setting("extrapoints");
                output("`3You've previously named your mount `#%s the %s`3.  Because you've done a mount name in the past, you can change the name of your mount for %s points.`n", $name, $playermount['basename'], $cost);
            } else {
                $cost = get_module_setting("initialpoints");
                $ecost = get_module_setting("extrapoints");
                output("`3You can give your mount a name.  It takes %s donator points to do the first mount name, but you can rename your mount in the future for %s points each time.`n", $cost, $ecost);
            }
        }
        $previewname = httppost("name");
        $previewname = comment_sanitize($previewname);
        $previewname = substr($previewname, 0, 25);
        while (substr($previewname, strlen($previewname) - 1) == "`") {
            $previewname = substr($previewname, 0, strlen($previewname) - 1);
        }
        if ($previewname > "" && httppost("confirm") > "") {
            if ($pointsavailable >= $cost) {
                $showform = false;
                $session['user']['donationspent'] += $cost;
                set_module_pref("mountname", $previewname);
                set_module_pref("boughtbefore", true);
                $playermount['mountname'] = $previewname . ' `&the ' . $playermount['basename'] . "`0";
                output("`n`3Your mount is now named `#%s`3.`n", $playermount['mountname']);
                debuglog("Spent {$cost} donator points naming their mount {$playermount['mountname']}`0");
            } else {
                $showform = true;
                output("`nYou need `^%s`3 points to change your mount's name, but you only have `^%s`3.`n", $cost, $pointsavailable);
            }
        } else {
            $showform = true;
        }
        if ($previewname == "") {
            $previewname = $name;
        }
        if ($showform) {
            output_notl("`0");
            rawoutput("<form action='runmodule.php?module=namedmount&op=preview' method='POST'>");
            addnav("", "runmodule.php?module=namedmount&op=preview");
            if ($previewname > "" && $previewname != $name) {
                output("`n`3Your mount's name will be `#%s `#the %s`3.  Press Confirm if you like this.`n", $previewname, $playermount['basename']);
            }
            output("`n`3Mount name (25 chars)? ");
            rawoutput("<script language='JavaScript'>\r\n\t\t\tvar startname = \"{$previewname}\";\r\n\t\t\tfunction dropConfirm(val){\r\n\t\t\t\tvar item = document.getElementById('confirm');\r\n\t\t\t\tif (val == startname) {\r\n\t\t\t\t\titem.style.visibility='visible';\r\n\t\t\t\t\titem.style.display='inline';\r\n\t\t\t\t}else{\r\n\t\t\t\t\titem.style.visibility='hidden';\r\n\t\t\t\t\titem.style.display='none';\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t</script>");
            rawoutput("<input name='name' value=\"" . htmlentities($previewname, ENT_COMPAT, getsetting("charset", "ISO-8859-1")) . "\" onChange=\"dropConfirm(this.value);\" onKeyUp=\"dropConfirm(this.value)\">", true);
            output_notl("<input name='preview' type='submit' class='button' value='Preview'>", true);
            output_notl("<input name='confirm' id='confirm' type='submit' class='button' value='Confirm' style='" . ($previewname > "" && $previewname != $name ? "visibility: visible; display: inline;" : "visibility: hidden; display:none;") . "'>", true);
            output("`nYou can use the same color codes that you use in comments for your mount's name.  If you change mounts, your new mount will carry your old mount's name.");
            output_notl("</form>", true);
        }
        addnav("L?Return to the Lodge", "lodge.php");
        page_footer();
    }
}
function addcommentary()
{
    global $session, $emptypost, $afk, $dni;
    $section = httppost('section');
    $talkline = httppost('talkline');
    $schema = httppost('schema');
    $comment = trim(httppost('insertcommentary'));
    $counter = httppost('counter');
    $remove = URLDecode(httpget('removecomment'));
    $restore = URLDecode(httpget('restorecomment'));
    //debug(httpallpost());
    if (httpget("bulkdelete")) {
        $everything = httpallpost();
        foreach ($everything as $key => $val) {
            if (substr($key, 0, 14) == "deletecomment_") {
                $del = str_replace("deletecomment_", "", $key);
                removecommentary($del, "Mass deletion by " . $session['user']['name'], $session['user']['acctid']);
            }
        }
    }
    if ($remove > 0) {
        removecommentary($remove, "Moderated by " . $session['user']['name'], $session['user']['acctid']);
    }
    if ($restore > 0) {
        restorecommentary($restore, "Restored by " . $session['user']['name'], $session['user']['acctid']);
    }
    if (!$comment) {
        return false;
    }
    if ($session['user']['chatloc'] == "DNI") {
        $dni = true;
    }
    $colors = array("1" => "colDkBlue", "2" => "colDkGreen", "3" => "colDkCyan", "4" => "colDkRed", "5" => "colDkMagenta", "6" => "colDkYellow", "7" => "colDkWhite", "~" => "colBlack", "!" => "colLtBlue", "@" => "colLtGreen", "#" => "colLtCyan", "\$" => "colLtRed", "%" => "colLtMagenta", "^" => "colLtYellow", "&" => "colLtWhite", ")" => "colLtBlack", "e" => "colDkRust", "E" => "colLtRust", "g" => "colXLtGreen", "G" => "colXLtGreen", "j" => "colMdGrey", "k" => "colaquamarine", "K" => "coldarkseagreen", "l" => "colDkLinkBlue", "L" => "colLtLinkBlue", "m" => "colwheat", "M" => "coltan", "p" => "collightsalmon", "P" => "colsalmon", "q" => "colDkOrange", "Q" => "colLtOrange", "R" => "colRose", "T" => "colDkBrown", "t" => "colLtBrown", "V" => "colBlueViolet", "v" => "coliceviolet", "x" => "colburlywood", "X" => "colbeige", "y" => "colkhaki", "Y" => "coldarkkhaki");
    if (substr($comment, 0, 9) == "/chatcol ") {
        $ucol = substr($comment, 9, 1);
        if (!isset($colors[$ucol])) {
            output("`c`b`4Invalid default talk colour`b`nYou entered an invalid colour code, please try again.`0`c`n");
            return false;
        } else {
            $session['user']['prefs']['ucol'] = $ucol;
            output_notl("`c`bDefault talk colour changed`b`n`" . $ucol . "This is your new default commentary dialogue colour.  When you type in commentary areas, this colour will show up automatically.  If you're an Extra-Awesome Site Supporter, you can also change the colour of your character's dialogue during quests, monster fights and other in-game areas using the /talkcol switch, in the same way you just used the /chatcol switch.`0`c`n");
            return false;
        }
    } else {
        if (substr($comment, 0, 9) == "/talkcol ") {
            $ucol = substr($comment, 9, 1);
            if (!isset($colors[$ucol])) {
                output("`c`b`4Invalid default talk colour`b`nYou entered an invalid colour code, please try again.`0`c`n");
                return false;
            } else {
                $session['user']['prefs']['ugcol'] = $ucol;
                if ($session['user']['donation'] >= 2000) {
                    output_notl("`c`bDefault talk colour changed`b`n`" . $ucol . "This is your new default in-game dialogue colour.  This is the colour we'll use to represent your character's dialogue during quests, monster encounters, and other in-game things.  If you choose a colour commonly used by monsters or other characters, you might have problems figuring out who's talking - if that's the case, you can reset to the default with \"/talkcol #\".  You can also change your default colour for commentary areas by using the /chatcol switch, in the same way you just used /talkcol.`0`c`n");
                } else {
                    output("`c`bNot enough Supporter Points`b`nSorry, but due to the extra system load that the /talkcol switch uses, this feature is restricted to players with more than 2,000 Supporter Points.`0`c`n");
                }
                return false;
            }
        }
    }
    if ($comment == strtoupper($comment)) {
        //this is an all-uppercase entry.  Do not add this comment to the database; instead, check it for built-in stuff like AFK and GREM, then run it through the commentarycommand hook
        if ($comment == "AFK" || $comment == "BRB") {
            $session['user']['chatloc'] = "AFK";
            $afk = true;
            output("`0`n`c`bYou are Away From the Keyboard until you load another page.`b`c`n");
            return false;
        }
        if ($comment == "DNI") {
            if ($session['user']['chatloc'] == "DNI") {
                $session['user']['chatloc'] = $section;
                $dni = false;
                output("`0`n`c`bYou are no longer in Do Not Interrupt status.`b`c`n");
            } else {
                $session['user']['chatloc'] = "DNI";
                $dni = true;
                output("`0`n`c`bYou are in Do Not Interrupt status.  Type DNI again to leave.`b`nDNI status is used for whenever you're doing or saying something that means other players shouldn't try to interact with you.  For example, when two or more characters are chatting just outside of the main group of characters, and other characters shouldn't be able to hear them.`c`n");
            }
            return false;
        }
        if ($comment == "GREM") {
            //handle deleting the player's last comment
            $sql = "SELECT * FROM " . db_prefix("commentary") . " WHERE author='" . $session['user']['acctid'] . "' ORDER BY commentid DESC LIMIT 1";
            $result = db_query($sql);
            while ($row = db_fetch_assoc($result)) {
                $now = time();
                $then = strtotime($row['postdate']);
                $ago = $now - $then;
                if ($ago < 120) {
                    removecommentary($row['commentid'], "Typo Gremlin", $session['user']['acctid']);
                    output("`0`n`c`bA nearby Typo Gremlin notices the peculiar tastiness of your previous comment.  Within moments, a small horde of them have descended upon your words, and consumed them.`b`c`n");
                } else {
                    output("`0`n`c`bThe Typo Gremlins turn up their nose at your latest comment - it's just too old.  They have no taste for stale words.`b`c`n");
                }
            }
            return false;
        }
        $hookcommand = array('command' => $comment, 'section' => $section);
        $returnedhook = modulehook("commentarycommand", $hookcommand);
        if (!$returnedhook['skipcommand']) {
            //if for some reason you're going to involve a command that can be a mix of upper and lower case, set $args['skipcommand'] and $args['ignore'] to true and handle it in postcomment instead.
            if (!$returnedhook['processed']) {
                output("`c`b`JCommand Not Recognized`b`0`nWhen you type in ALL CAPS, the game doesn't think you're talking to other players; it thinks you're trying to perform an action within the game.  For example, typing `#GREM`0 will remove the last comment you posted, as long as you posted it less than two minutes ago.  Typing `#AFK`0 or `#BRB`0 will turn your online status bar grey, so that people know you're `#A`0way `#F`0rom the `#K`0eyboard (or, if you prefer, that you'll `#B`0e `#R`0ight `#B`0ack).  Typing `#DNI`0 will let other players know that you're busy talking to one particular player - maybe somewhere off-camera - and that you don't want to be interrupted right now.`nSome areas have special hidden commands or other easter eggs that you can hunt for.  This time around, you didn't trigger anything special.`c`0`n");
            }
            return false;
        }
    }
    if ($section || $talkline || $comment) {
        $tcom = color_sanitize($comment);
        if ($tcom == "" || $tcom == ":" || $tcom == "::" || $tcom == "/me") {
            $emptypost = 1;
        } else {
            $comment = comment_sanitize($comment);
            injectcommentary($section, $talkline, $comment);
        }
    }
}