function newdaybar_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "charstats":
            require_once "lib/datetime.php";
            $gt = gametimedetails();
            setcharstat("Time", "Game Time", gmdate("g:i a", $gt['gametime']));
            setcharstat("Time", "New day in:", date("H:i:s", secondstonextgameday()));
            break;
    }
    return $args;
}
}
addnav("Game Settings");
addnav("Standard settings", "configuration.php");
addnav("", $REQUEST_URI);
module_editor_navs('settings', 'configuration.php?op=modulesettings&module=');
if ($op == "") {
    $enum = "enumpretrans";
    require_once "lib/datetime.php";
    $details = gametimedetails();
    $offset = getsetting("gameoffsetseconds", 0);
    for ($i = 0; $i <= 86400 / getsetting("daysperday", 4); $i += 300) {
        $off = $details['realsecstotomorrow'] - ($offset - $i);
        if ($off < 0) {
            $off += 86400;
        }
        $x = strtotime("+" . $off . " secs");
        $str = sprintf_translate("In %s at %s (+%s)", reltime($x), date("h:i a", $x), date("H:i", $i));
        $enum .= ",{$i},{$str}";
    }
    rawoutput(tlbutton_clear());
    $setup = array("Game Setup,title", "loginbanner" => "Login Banner (under login prompt: 255 chars)", "maxonline" => "Max # of players online (0 for unlimited), int", "allowcreation" => "Allow creation of new characters,bool", "gameadminemail" => "Admin Email", "emailpetitions" => "Should submitted petitions be emailed to Admin Email address?,bool", "Enter languages here like this: `i(shortname 2 chars) comma (readable name of the language)`i and continue as long as you wish,note", "serverlanguages" => "Languages available on this server", "defaultlanguage" => "Default Language,enum," . getsetting("serverlanguages", "en,English,fr,Français,dk,Danish,de,Deutsch,es,Español,it,Italian"), "edittitles" => "Should DK titles be editable in user editor,bool", "motditems" => "How many items should be shown on the motdlist,int", "Main Page Display,title", "homeskinselect" => "Should the skin selection widget be shown?,bool", "homecurtime" => "Should the current realm time be shown?,bool", "homenewdaytime" => "Should the time till newday be shown?,bool", "homenewestplayer" => "Should the newest player be shown?,bool", "defaultskin" => "What skin should be the default?,theme", "impressum" => "Tell the world something about the person running this server. (e.g. name and address),textarea", "Beta Setup,title", "beta" => "Enable beta features for all players?,bool", "betaperplayer" => "Enable beta features per player?,bool", "Account Creation,title", "defaultsuperuser" => "Flags automatically granted to new players,bitfield," . ($session['user']['superuser'] | SU_ANYONE_CAN_SET) . " ," . SU_INFINITE_DAYS . ",Infinite Days," . SU_VIEW_SOURCE . ",View Source Code," . SU_DEVELOPER . ",Developer Super Powers (special inc list; god mode; auto defeat master; etc)," . SU_DEBUG_OUTPUT . ",Debug Output", "newplayerstartgold" => "Amount of gold to start a new character with,int", "maxrestartgold" => "Maximum amount of gold a player will get after a dragonkill,int", "maxrestartgems" => "Maximum number of gems a player will get after a dragonkill,int", "requireemail" => "Require users to enter their email address,bool", "requirevalidemail" => "Require users to validate their email address,bool", "blockdupeemail" => "One account per email address,bool", "spaceinname" => "Allow spaces in user names,bool", "allowoddadminrenames" => "Allow admins to enter 'illegal' names in the user editor,bool", "selfdelete" => "Allow player to delete their character,bool", "Commentary/Chat,title", "soap" => "Clean user posts (filters bad language and splits words over 45 chars long),bool", "maxcolors" => "Max # of color changes usable in one comment,range,5,40,1", "postinglimit" => "Limit posts to let one user post only up to 50% of the last posts (else turn it off),bool", "Place names and People names,title", "villagename" => "Name for the main village", "innname" => "Name of the inn", "barkeep" => "Name of the barkeep", "barmaid" => "Name of the barmaid", "bard" => "Name of the bard", "clanregistrar" => "Name of the clan registrar", "deathoverlord" => "Name of the death overlord", "Referral Settings,title", "refereraward" => "How many points will be awarded for a referral?,int", "referminlevel" => "What level does the referral need to reach to credit the referer?,int", "Random events,title", "forestchance" => "Chance for Something Special in the Forest,range,0,100,1", "villagechance" => "Chance for Something Special in any village,range,0,100,1", "innchance" => "Chance for Something Special in the Inn,range,0,100,1", "gravechance" => "Chance for Something Special in the Graveyard,range,0,100,1", "gardenchance" => "Chance for Something Special in the Gardens,range,0,100,1", "Paypal,title", "paypalemail" => "Email address of Admin's paypal account", "paypalcurrency" => "Currency type", "paypalcountry-code" => "What country's predominant language do you wish to have displayed in your PayPal screen?,enum\n\t\t,US,United States,DE,Germany,AI,Anguilla,AR,Argentina,AU,Australia,AT,Austria,BE,Belgium,BR,Brazil,CA,Canada\n\t\t,CL,Chile,C2,China,CR,Costa Rica,CY,Cyprus,CZ,Czech Republic,DK,Denmark,DO,Dominican Republic\n\t\t,EC,Ecuador,EE,Estonia,FI,Finland,FR,France,GR,Greece,HK,Hong Kong,HU,Hungary,IS,Iceland,IN,India\n\t\t,IE,Ireland,IL,Israel,IT,Italy,JM,Jamaica,JP,Japan,LV,Latvia,LT,Lithuania,LU,Luxembourg,MY,Malaysia\n\t\t,MT,Malta,MX,Mexico,NL,Netherlands,NZ,New Zealand,NO,Norway,PL,Poland,PT,Portugal,SG,Singapore,SK,Slovakia\n\t\t,SI,Slovenia,ZA,South Africa,KR,South Korea,ES,Spain,SE,Sweden,CH,Switzerland,TW,Taiwan,TH,Thailand,TR,Turkey\n\t\t,GB,United Kingdom,UY,Uruguay,VE,Venezuela", "paypaltext" => "What text should be displayed as item name in the donations screen(player name will be added after it)?", "(standard: 'Legend of the Green Dragon Site Donation from',note", "General Combat,title", "autofight" => "Allow fighting multiple rounds automatically,bool", "autofightfull" => "Allow fighting until fight is over,enum,0,Never,1,Always,2,Only when not allowed to flee", "Training,title", "automaster" => "Masters hunt down truant students,bool", "multimaster" => "Can players gain multiple levels (challenge multiple masters) per game day?,bool", "displaymasternews" => "Display news if somebody fought his master?,bool", "Clans,title", "allowclans" => "Enable Clan System?,bool", "goldtostartclan" => "Gold to start a clan,int", "gemstostartclan" => "Gems to start a clan,int", "officermoderate" => "Can clan officers who are also moderators moderate their own clan even if they cannot moderate all clans?,bool", "New Days,title", "daysperday" => "Game days per calendar day,range,1,6,1", "specialtybonus" => "Extra daily uses in specialty area,range,0,5,1", "newdaycron" => "Let the newday-runonce run via a cronjob,bool", "The directory is necessary! Do not forget to set the correct one in cron.php in your main game folder!!! ONLY experienced admins should use cron jobbing here,note", "`bAlso make sure you setup a cronjob on your machine using confixx/plesk/cpanel or any other admin panel pointing to the cron.php file in your main folder`b,note", "If you do not know what a Cronjob is... leave it turned off. If you want to know more... check out: <a href='http://wiki.dragonprime.net/index.php?title=Cronjob'>http://wiki.dragonprime.net/index.php?title=Cronjob</a>,note", "resurrectionturns" => "Modify (+ or -) the number of turns deducted after a resurrection as an absolute (number) or relative (number followed by %),text", "Forest,title", "turns" => "Forest Fights per day,range,5,30,1", "dropmingold" => "Forest Creatures drop at least 1/4 of max gold,bool", "suicide" => "Allow players to Seek Suicidally?,bool", "suicidedk" => "Minimum DKs before players can Seek Suicidally?,int", "forestgemchance" => "Player will find a gem one in X times,range,10,100,1", "disablebonuses" => "Should monsters which get buffed with extra HP/Att/Def get a gold+exp bonus?,bool", "forestexploss" => "What percentage of experience should be lost?,range,10,100,1", "Multiple Enemies,title", "multifightdk" => "Multiple monsters will attack players above which amount of dragonkills?,range,8,50,1", "multichance" => "The chance for an attack from multiple enemies is,range,0,100,1", "addexp" => "Additional experience (%) per enemy during multifights?,range,0,15", "instantexp" => "During multi-fights hand out experience instantly?,bool", "maxattacks" => "How many enemies will attack per round (max. value),range,1,10", "allowpackofmonsters" => "Allow multiple monsters of the same type to appear in a battle?,bool", "Random values for type of seeking is added to random base.,note", "multibasemin" => "The base number of multiple enemies at minimum is,range,1,100,2", "multibasemax" => "The base number of multiple enemies at maximum is,range,1,100,3", "multislummin" => "The number of multiple enemies at minimum for slumming is,range,0,100,0", "multislummax" => "The number of multiple enemies at maximum for slumming is,range,0,100,1", "multithrillmin" => "The number of multiple enemies at minimum for thrill seeking is,range,0,100,1", "multithrillmax" => "The number of multiple enemies at maximum for thrill seeking is,range,0,100,2", "multisuimin" => "The number of multiple enemies at minimum for suicide is,range,0,100,2", "multisuimax" => "The number of multiple enemies at maximum for suicide is,range,0,100,4", "Stables,title", "allowfeed" => "Does Merick have feed onhand for creatures,bool", "Companions/Mercenaries,title", "enablecompanions" => "Enable the usage of companions,bool", "companionsallowed" => "How many companions are allowed per player,int", "Modules my alter this value on a per player basis!,note", "companionslevelup" => "Are companions allowed to level up?,bool", "Bank Settings,title", "fightsforinterest" => "Max forest fights remaining to earn interest?,range,0,10,1", "maxinterest" => "Max Interest Rate (%),range,5,10,1", "mininterest" => "Min Interest Rate (%),range,0,5,1", "maxgoldforinterest" => "Over what amount of gold does the bank cease paying interest? (0 for unlimited),int", "borrowperlevel" => "Max player can borrow per level (val * level for max),range5,200,5", "allowgoldtransfer" => "Allow players to transfer gold,bool", "transferperlevel" => "Max player can receive from a transfer (val * level),range,5,100,5", "mintransferlev" => "Min level a player (0 DK's) needs to transfer gold,range,1,5,1", "transferreceive" => "Total transfers a player can receive in one day,range,0,5,1", "maxtransferout" => "Amount player can transfer to others (val * level),range,5,100,5", "innfee" => "Fee for express inn payment (x or x%),int", "Mail Settings,title", "mailsizelimit" => "Message size limit per message,int", "inboxlimit" => "Limit # of messages in inbox,int", "oldmail" => "Automatically delete old messages after (days),int", "superuseryommessage" => "Warning to give when attempting to YoM an admin?", "onlyunreadmails" => "Only unread mail count towards the inbox limit?,bool", "PvP,title", "pvp" => "Enable Slay Other Players,bool", "pvpday" => "Player Fights per day,range,1,10,1", "pvpimmunity" => "Days that new players are safe from PvP,range,1,5,1", "pvpminexp" => "Experience below which player is safe from PvP,int", "pvpattgain" => "Percent of victim experience attacker gains on win,floatrange,.25,20,.25", "pvpattlose" => "Percent of experience attacker loses on loss,floatrange,.25,20,.25", "pvpdefgain" => "Percent of attacker experience defender gains on win,floatrange,.25,20,.25", "pvpdeflose" => "Percent of experience defender loses on loss,floatrange,.25,20,.25", "Content Expiration,title", "expirecontent" => "Days to keep comments and news?  (0 = infinite),int", "expiretrashacct" => "Days to keep never logged-in accounts? (0 = infinite),int", "expirenewacct" => "Days to keep 1 level (0 dragon) accounts? (0 =infinite),int", "expireoldacct" => "Days to keep all other accounts? (0 = infinite),int", "LOGINTIMEOUT" => "Seconds of inactivity before auto-logoff,int", "High Load Optimization,title", "This has been moved to the dbconnect.php,note", "LoGDnet Setup,title", "(LoGDnet requires your PHP configuration to have file wrappers enabled!!),note", "logdnet" => "Register with LoGDnet?,bool", "serverurl" => "Server URL", "serverdesc" => "Server Description (75 chars max)", "logdnetserver" => "Master LoGDnet Server (default http://logdnet.logd.com/)", "curltimeout" => "How long we wait for responses from logdnet.logd.com (in seconds),range,1,10,1|2", "Game day Setup,title", "dayduration" => "Day Duration,viewonly", "curgametime" => "Current game time,viewonly", "curservertime" => "Current Server Time,viewonly", "lastnewday" => "Last new day,viewonly", "nextnewday" => "Next new day,viewonly", "gameoffsetseconds" => "Real time to offset new day,{$enum}", "Translation Setup,title", "enabletranslation" => "Enable the use of the translation engine,bool", "It is strongly recommended to leave this feature turned on.,note", "cachetranslations" => "Cache the translations (datacache must be turned on)?,bool", "permacollect" => "Permanently collect untranslated texts (overrides the next settings!),bool", "collecttexts" => "Are we currently collecting untranslated texts?,viewonly", "tl_maxallowed" => "Collect untranslated texts if you have fewer player than this logged in. (0 never collects),int", "charset" => "Which charset should be used for htmlentities?", "Error Notification,title", "Note: you MUST have data caching turned on if you want to use this feature.  Also the first error within any 24 hour period will not generate a notice; I'm sorry: that's really just how it is for technical reasons.,note", "show_notices" => "Show PHP Notice output?,bool", "notify_on_warn" => "Send notification on site warnings?,bool", "notify_on_error" => "Send notification on site errors?,bool", "notify_address" => "Address to notify", "notify_every" => "Only notify every how many minutes for each distinct error?,int", "Miscellaneous Settings,title", "allowspecialswitch" => "The Barkeeper may help you to switch your specialty?,bool", "maxlistsize" => "Maximum number of items to be shown in the warrior list,int");
    $secstonewday = secondstonextgameday($details);
    $useful_vals = array("dayduration" => round($details['dayduration'] / 60 / 60, 0) . " hours", "curgametime" => getgametime(), "curservertime" => date("Y-m-d h:i:s a"), "lastnewday" => date("h:i:s a", strtotime("-{$details['realsecssofartoday']} seconds")), "nextnewday" => date("h:i:s a", strtotime("+{$details['realsecstotomorrow']} seconds")) . " (" . date("H\\h i\\m s\\s", $secstonewday) . ")");
    loadsettings();
    $vals = $settings + $useful_vals;
    rawoutput("<form action='configuration.php?op=save' method='POST'>");
    addnav("", "configuration.php?op=save");
    showform($setup, $vals);
    rawoutput("</form>");
}
page_footer();
/**
 * Returns the current character stats or (if the character isn't logged in) the currently online players
 * Hooks provided:
 *		charstats
 *
 * @return array The current stats for this character or the list of online players
 */
function charstats()
{
    global $session, $playermount, $companions;
    wipe_charstats();
    $u =& $session['user'];
    if ($session['loggedin']) {
        $u['hitpoints'] = round($u['hitpoints'], 0);
        $u['experience'] = round($u['experience'], 0);
        $u['maxhitpoints'] = round($u['maxhitpoints'], 0);
        // $spirits=array(-6=>"Resurrected",-2=>"Very Low",-1=>"Low","0"=>"Normal",1=>"High",2=>"Very High");
        // if ($u['alive']){ }else{ $spirits[(int)$u['spirits']] = "DEAD"; }
        //calculate_buff_fields();
        reset($session['bufflist']);
        $atk = $u['attack'];
        $def = $u['defense'];
        $buffcount = 0;
        $buffs = "";
        while (list($key, $val) = each($session['bufflist'])) {
            if (isset($val['suspended']) && $val['suspended']) {
                continue;
            }
            if (isset($val['atkmod'])) {
                $atk *= $val['atkmod'];
            }
            if (isset($val['defmod'])) {
                $def *= $val['defmod'];
            }
            // Short circuit if the name is blank
            if ($val['name'] > "" || $session['user']['superuser'] & SU_DEBUG_OUTPUT) {
                tlschema($val['schema']);
                if ($val['name'] == "") {
                    $val['name'] = "DEBUG: {$key}";
                }
                if (is_array($val['name'])) {
                    $val['name'][0] = str_replace("`%", "`%%", $val['name'][0]);
                    $val['name'] = call_user_func_array("sprintf_translate", $val['name']);
                } else {
                    //in case it's a string
                    $val['name'] = translate_inline($val['name']);
                }
                if ($val['rounds'] >= 0) {
                    // We're about to sprintf, so, let's makes sure that
                    // `% is handled.
                    //$n = translate_inline(str_replace("`%","`%%",$val['name']));
                    $b = translate_inline("`#%s `7(%s rounds left)`n", "buffs");
                    $b = sprintf($b, $val['name'], $val['rounds']);
                    $buffs .= appoencode($b, true);
                } else {
                    $buffs .= appoencode("`#{$val['name']}`n", true);
                }
                tlschema();
                $buffcount++;
            }
        }
        if ($buffcount == 0) {
            $buffs .= appoencode(translate_inline("`^None`0"), true);
        }
        $atk = round($atk, 2);
        $def = round($def, 2);
        if ($atk < $u['attack']) {
            $atk = round($u['attack'], 1) . "`\$" . round($atk - $u['attack'], 1);
        } else {
            if ($atk > $u['attack']) {
                $atk = round($u['attack'], 1) . "`@+" . round($atk - $u['attack'], 1);
            } else {
                // They are equal, display in the 1 signifigant digit format.
                $atk = round($atk, 1);
            }
        }
        if ($def < $u['defense']) {
            $def = round($u['defense'], 1) . "`\$" . round($def - $u['defense'], 1);
        } else {
            if ($def > $u['defense']) {
                $def = round($u['defense'], 1) . "`@+" . round($def - $u['defense'], 1);
            } else {
                // They are equal, display in the 1 signifigant digit format.
                $def = round($def, 1);
            }
        }
        addcharstat("Vital Info");
        //health bar
        if ($u['alive']) {
            $cur = $u['hitpoints'];
            $realmax = $u['maxhitpoints'];
            $cur_adjustment = check_temp_stat("hitpoints", 1);
            $max_adjustment = check_temp_stat("maxhitpoints", 1);
        } else {
            $cur = $u['soulpoints'];
            $realmax = $u['level'] * 5 + 50;
            $cur_adjustment = check_temp_stat("soulpoints", 1);
            $max_adjustment = "";
        }
        if ($pct > 60) {
            $ccode = "`@";
        } elseif ($pct > 25) {
            $ccode = "`^";
        } else {
            $ccode = "`\$";
        }
        $hicode = "`&";
        if (!$u['alive']) {
            $ccode = "`7";
        }
        require_once "lib/bars.php";
        $hpbar = fadebar($cur, $realmax);
        $stat = "{$ccode} {$cur} {$cur_adjustment} `0/ {$realmax} {$max_adjustment}<br />" . $hpbar;
        if ($u['alive']) {
            addcharstat("Hitpoints", $stat);
            addcharstat("Attack", $atk . check_temp_stat("attack", 1));
            addcharstat("Defence", $def . check_temp_stat("defense", 1));
        } else {
            addcharstat("Adrenaline", $stat);
            addcharstat("Attack", 10 + round(($u['level'] - 1) * 1.5));
            addcharstat("Defence", 10 + round(($u['level'] - 1) * 1.5));
        }
        // addcharstat("Turns", $u['turns'].check_temp_stat("turns",1));
        // addcharstat("Attack", $atk.check_temp_stat("attack",1));
        // addcharstat("Defence", $def.check_temp_stat("defense",1));
        if (count($companions) > 0) {
            addcharstat("Companions");
            foreach ($companions as $name => $companion) {
                if ($companion['hitpoints'] > 0 || isset($companion['cannotdie']) && $companion['cannotdie'] == true) {
                    if ($companion['hitpoints'] < 0) {
                        $companion['hitpoints'] = 0;
                    }
                    if ($companion['hitpoints'] < $companion['maxhitpoints']) {
                        $color = "`\$";
                    } else {
                        $color = "`@";
                    }
                    if (isset($companion['suspended']) && $companion['suspended'] == true) {
                        $suspcode = "`7 *";
                    } else {
                        $suspcode = "";
                    }
                    addcharstat($companion['name'], $color . $companion['hitpoints'] . "`7/`&" . $companion['maxhitpoints'] . "{$suspcode}`0");
                }
            }
        }
        addcharstat("Personal Info");
        if ($u['alive']) {
            addcharstat("Requisition", number_format($u['gold'] . check_temp_stat("gold", 1)));
            addcharstat("Cigarettes", number_format($u['gems'] . check_temp_stat("gems", 1)));
        } else {
            addcharstat("Cage Fights", $u['gravefights'] . check_temp_stat("gravefights", 1));
            addcharstat("Favour", number_format($u['deathpower'] . check_temp_stat("deathpower", 1)));
        }
        if ($u['alive']) {
            addcharstat("Level", "`b" . $u['level'] . check_temp_stat("level", 1) . "`b");
            //exp bar
            require_once "lib/experience.php";
            $min = exp_for_next_level($u['level'] - 1, $u['dragonkills']);
            $req = exp_for_next_level($u['level'], $u['dragonkills']);
            $exp = round($session['user']['experience'], 0) . check_temp_stat("experience", 1);
            if ($exp < $min) {
                $min = $exp;
            }
            if ($req - $min > 0) {
                $nonpct = floor(($req - $exp) / ($req - $min) * 100);
            } else {
                $nonpct = 0;
            }
            $pct = 100 - $nonpct;
            if ($pct > 100) {
                $pct = 100;
                $nonpct = 0;
            }
            if ($pct < 0) {
                $pct = 0;
                $nonpct = 100;
            }
            if ($exp >= $req) {
                $color = "blue";
                if ($session['user']['level'] == 1 && $session['user']['dragonkills'] == 0) {
                    $expmsg = "<br />You have enough experience to level up!  Challenge your master in the Dojo!";
                }
            } else {
                $color = "white";
            }
            addcharstat("Experience", number_format($u['experience'] . check_temp_stat("experience", 1)) . "/{$req}<br /><table style='border: solid 1px #000000;' bgcolor='red'  cellpadding='0' cellspacing='0' width='70' height='5'><tr><td width='{$pct}%' bgcolor='{$color}'></td><td width='{$nonpct}%'></td></tr></table>{$expmsg}");
            addcharstat("Equipment Info");
            addcharstat("Weapon", $u['weapon']);
            addcharstat("Armor", $u['armor']);
            if ($u['hashorse']) {
                addcharstat("Creature", $playermount['mountname'] . "`0");
            }
        }
        require_once "lib/datetime.php";
        $gt = gametimedetails();
        addcharstat("Game State");
        addcharstat("Game Time", gmdate("g:i a", $gt['gametime']));
        addcharstat("New day in:", date("H:i:s", secondstonextgameday()));
        modulehook("charstats");
        $charstat = getcharstats($buffs);
        if (!is_array($session['bufflist'])) {
            $session['bufflist'] = array();
        }
        return $charstat;
    } else {
        $ret = "";
        if ($ret = datacache("charlisthomepage")) {
        } else {
            $onlinecount = 0;
            // If a module wants to do it's own display of the online chars,
            // let it.
            $list = modulehook("onlinecharlist", array());
            if (isset($list['handled']) && $list['handled']) {
                $onlinecount = $list['count'];
                $ret = $list['list'];
            } else {
                $sql = "SELECT name,alive,location,sex,level,laston,loggedin,lastip,uniqueid FROM " . db_prefix("accounts") . " WHERE locked=0 AND loggedin=1 AND laston>'" . date("Y-m-d H:i:s", strtotime("-" . getsetting("LOGINTIMEOUT", 900) . " seconds")) . "' ORDER BY level DESC";
                $result = db_query($sql);
                $ret .= appoencode(sprintf(translate_inline("`bOnline Characters (%s players):`b`n"), db_num_rows($result)));
                while ($row = db_fetch_assoc($result)) {
                    $ret .= appoencode("`^{$row['name']}`n");
                    $onlinecount++;
                }
                db_free_result($result);
                if ($onlinecount == 0) {
                    $ret .= appoencode(translate_inline("`iNone`i"));
                }
            }
            savesetting("OnlineCount", $onlinecount);
            savesetting("OnlineCountLast", strtotime("now"));
            updatedatacache("charlisthomepage", $ret);
        }
        return $ret;
    }
}
function homepage_dohook($hookname, $args)
{
    global $session;
    switch ($hookname) {
        case "onlinecharlist":
            $args['handled'] = 1;
            $args['list'] = "";
            $nav = "";
            $op = httpget('op');
            if (httpget('r')) {
                $referer = httpget('r');
            }
            //Output current game time
            $args['list'] .= appoencode(sprintf(translate_inline("`0`bCurrent game time:`b`n%s`n`n"), getgametime()));
            //Output time to new day
            $secstonewday = secondstonextgameday();
            $args['list'] .= appoencode(sprintf(translate_inline("`0`bNext Game Day in:`b`n`\$%s`0`n`n"), date("G\\" . translate_inline("h", "datetime") . ", i\\" . translate_inline("m", "datetime") . ", s\\" . translate_inline("s", "datetime"), $secstonewday)));
            //Output newest player
            if (getsetting("homenewestplayer", 1)) {
                $name = "";
                $newplayer = getsetting("newestplayer", "");
                if ($newplayer != 0) {
                    $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE acctid='{$newplayer}'";
                    $result = db_query_cached($sql, "newest", 120);
                    $row = db_fetch_assoc($result);
                    $name = $row['name'];
                } else {
                    $name = $newplayer;
                }
                if ($name != "") {
                    $args['list'] .= appoencode(sprintf(translate_inline("`0`bNewest Player:`b`n`&%s`0`n`n"), $name));
                }
            }
            //Output online characters list
            $sql = "SELECT name,alive,location,sex,level,laston,loggedin,lastip,uniqueid FROM " . db_prefix("accounts") . " WHERE locked=0 AND loggedin=1 AND laston>'" . date("Y-m-d H:i:s", strtotime("-" . getsetting("LOGINTIMEOUT", 900) . " seconds")) . "' ORDER BY level DESC";
            $result = db_query_cached($sql, "charlisthomepage", 300);
            $args['list'] .= appoencode(sprintf(translate_inline("`bOnline Characters (%s players):`b`n"), db_num_rows($result)));
            while ($row = db_fetch_assoc($result)) {
                $args['list'] .= appoencode("`^{$row['name']}`n");
                $onlinecount++;
            }
            db_free_result($result);
            if ($onlinecount == 0) {
                $args['list'] .= appoencode(translate_inline("`iNone`i"));
            }
            savesetting("OnlineCount", $onlinecount);
            savesetting("OnlineCountLast", strtotime("now"));
            updatedatacache("charlisthomepage", $args['list']);
            break;
        case "index":
            page_header("Welcome to Improbable Island");
            $r = httpget('r');
            //block all standard navs
            blocknav("create.php");
            blocknav("create.php?op=forgot");
            blocknav("news.php");
            blocknav("about.php");
            blocknav("about.php?op=setup");
            blocknav("list.php");
            blocknav("logdnet.php?op=list");
            //block navs with referral links, too
            blocknav("create.php?r=" . $r);
            blocknav("create.php?op=forgot&r=" . $r);
            blocknav("news.php?r=" . $r);
            blocknav("about.php?r=" . $r);
            blocknav("about.php?op=setup&r=" . $r);
            blocknav("list.php?r=" . $r);
            blocknav("logdnet.php?op=list&r=" . $r);
            if (httpget('op') == "timeout") {
                $nav .= translate_inline("Your session has timed out, you must log in again.");
            }
            if (!isset($_COOKIE['lgi'])) {
                $nav .= translate_inline("It appears that you may be blocking cookies from this site.  At least session cookies must be enabled in order to use this site.`n");
                $nav .= translate_inline("`b`#If you are not sure what cookies are, please <a href='http://en.wikipedia.org/wiki/WWW_browser_cookie'>read this article</a> about them, and how to enable them.`b`n");
            }
            rawoutput("<script language='JavaScript' src='lib/md5.js'></script>");
            rawoutput("<script language='JavaScript'>\r\n\t\t\t<!--\r\n\t\t\tfunction md5pass(){\r\n\t\t\t\t//encode passwords before submission to protect them even from network sniffing attacks.\r\n\t\t\t\tvar passbox = document.getElementById('password');\r\n\t\t\t\tif (passbox.value.substring(0, 5) != '!md5!') {\r\n\t\t\t\t\tpassbox.value = '!md5!' + hex_md5(passbox.value);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t//-->\r\n\t\t\t</script>");
            addnav("Return to the Island");
            $msg = $session['message'];
            $nav .= "{$msg}<form action='login.php' method='POST' onSubmit=\"md5pass();\">Character Name:<br /><input name='name' id=\"name\" accesskey='u' size='12'><br />Password:<br /><input name='password' id=\"password\" accesskey='p' size='12' type='password'\"><br /><input type='submit' value='Log in' class='button'></form>";
            addnav(array("%s", $nav), "", true);
            addnav("Recover a lost password", "create.php?op=forgot&or=1");
            addnav("Game Credits");
            addnav("Credits and License Info", "runmodule.php?module=homepage&op=gamecredits&r=" . $r);
            $skins = array();
            $handle = @opendir("templates");
            // Template directory open failed
            if ($handle) {
                addnav("Skin selection");
                while (false != ($file = @readdir($handle))) {
                    if (strpos($file, ".htm") > 0) {
                        array_push($skins, $file);
                    }
                }
                // No templates installed!
                if (count($skins) == 0) {
                    output("None available");
                    break;
                }
                natcasesort($skins);
                //sort them in natural order
                foreach ($skins as $skin) {
                    if ($skin == $_COOKIE['template']) {
                        addnav(array("%s (selected)", htmlentities(substr($skin, 0, strpos($skin, ".htm")), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))), "");
                    } else {
                        addnav(array("%s", htmlentities(substr($skin, 0, strpos($skin, ".htm")), ENT_COMPAT, getsetting("charset", "ISO-8859-1"))), "runmodule.php?module=homepage&op=changeskin&skin={$skin}&r={$r}");
                    }
                }
            }
            //Output The Story...
            output("`i`#How did I end up here?`0`i`n`nIt's a question that you must have asked yourself at one point in your life or another. Probably after pulling your head out of the toilet bowl, remembering the little rhyme about drinking wine on top of beer, and then feeling rather poorly again. You might have asked that question while standing naked in the pouring rain holding a coathanger in one hand and a rather large purple sex toy in the other, trying desperately to break into your own car while two policemen stroll up the street towards you. Perhaps you asked it while flushing the contents of your pockets and incinerating your hard drive, or after putting your life savings on \"red 36,\" or while washing the urine out of your clown suit.`n`nHowever, this time, you mean it literally.`n`nOr rather, you would, if you had gotten around to asking that question. You haven't, yet. To be truthful, you're rather reluctant to open your eyes.`n`nYou know that you're lying in grass. You know that you're naked. You know that you can hear birds singing, and the sun on your body, and a warm, gentle breeze. That's okay. That's manageable. You've woken up in less desirable circumstances before.`n`nThe unmistakable roar of a low-flying jet plane going overhead, and the muffled thumps of explosions in the distance... now, that's not so good. That's the sort of thing that you really should pay attention to.`n`nReluctantly, you open your eyes.`n`n`i`#How did I end up here?`0`i`n`nYou're lying on your back in the middle of a grassy clearing. As suspected, a quick glance down confirms that you're as naked as the day you were born. A bulky video camera, mounted in a tree directly above you, pans disinterestedly down your body. It lets out a little whirring noise, one that seems to say \"yeah, whatever. I've seen better.\"`n`nAbout twenty paces ahead, the clearing gradually gives way into dense jungle. You look around you and confirm that this is the case for all directions.`n`nExcept one. A crudely-built wooden fort stands ten paces to your right. The wooden stakes in the ground extend about forty feet in the air, and you can't quite tell how far they go along horizontal dimensions.`n`n`i`#Think. Think. Where am I?`i`n`n`#`iOkay. I know who I am. I know my name. I know my parents' names. I know my address. I even know what I did last night! That rules out long-term memory loss, so what the hell am I doing here?`i`0`n`nYou try to get up, to see just how big this wooden fort thing is, but a sharp pain in your head tells you in no uncertain terms to sit the hell back down again.`n`nAs you collapse, the gates open, and a woman walks out. She looks around herself, and in short order her piercing blue eyes lock on to yours.  She walks over to you, shaking her head.`n`nShe wears a black skirt below her knees, a red turtleneck sweater, and round, copper-framed glasses. Blonde hair tied back in a bun, combined with her clear disdain for your presence, give her a rather severe appearance. When she comes closer, you notice that she's wearing heavy black steel-toe boots, spattered with something reddish-brown.`n`nShe leans over you, stares at you for a moment, and sighs. Her first words to you come in a Southern British accent:`n`n\"`&I don't really have time for this, you know.`0\"`n`nSomething about her voice doesn't sound quite right. It resonates in the center of your skull, almost the way that voices do when you hear them through a pair of headphones.`n`nShe sits down heavily on the grass beside you. Is that `irust`i on her boots?`n`n\"`&Long story short,`0\" she says, making herself comfortable. \"`&Because like I say, I really `idon't`i have time for this.`0\" She points to the wooden fort. \"`&That's an outpost.`0\" She points to the jungle. \"`&That's the Jungle.`0\" She points to herself. \"`&I am `\$The Watcher.`0\" She points down at you. \"`&You are a plonker. No, really, I mean it. You're clearly depriving a village somewhere of an idiot. Sorry to belabour the point, but it's important that we get the Watcher-Plonker relationship established properly, straight away. Otherwise you might get ideas.`0\"`n`nYou stare up at her accusing finger. \"`#What?`0\"`n`nShe presses gently on your nose. \"`&Case in point. Don't ask questions, and don't piss me off today, and you'll be fine.`0\"`n`nYou frown. \"`#What do you mean, I'll be fine?  I can't even remember how I got here!`0\"`n`n`\$The Watcher`0 smiles. \"`&Oh, they must have drugged you up something awful, poor thing.`0\" She looks down at her watch. \"`&Okay, I'll give you a run-down but I've gotta make this really, really quick, now. Don't interrupt.`0\"`n`nShe takes a deep breath. Then she talks very quickly.`n`n\"`&You've been drafted into a war against a machine called the Improbability Drive. It lives somewhere in the jungle, over there. Improbability is leaking out of this bloody thing like radiation, so we've got to blow it up. The whole war is being televised, you've noticed the cameras already, so try not to do anything stupid while the world watches. Your head hurts because the guys who burst into your living room with sticks and a great big sack probably hit you a bit too hard, and you might have landed badly when they tossed you out of the plane. You survived the fall without a parachute because of the Improbability Bubble surrounding the island, which makes the air notably denser about forty feet above sea level. You're naked and unarmed because everything that penetrates the Improbability Bubble gets changed in rather amusing ways, and we didn't want to take that risk. There's blood on my boots because I came across some monsters on the way over here - yes, monsters, stop gawping, you'll get used to them - and you'll either pick up the rest as you go along, or you'll die in a very entertaining fashion.`0\" She smiles. \"`&Either way, it'll make for great television.`0\"`n`nYou open your mouth to ask `\$The Watcher`0 what the hell she's blithering on about, but your words are drowned out by the roar of a passing jet plane and an accompanying female scream.`n`n`\$The Watcher`0 looks up, just in time to see a naked woman make a very undignified landing in a tree, folding herself neatly over a branch. `\$The Watcher`0 grins. \"`&I love it when they land with their arses poking out like that. It makes me feel better about my job.`0\" She stares for a moment, head cocked to the side. \"`&And my arse, too, come to think of it.`0\"`n`nShe takes hold of your hand and yanks you to your feet. \"`&Go through the gate over there. The bloke guarding it is trained to recognise naked newbies like you, and sort out the forms and the implants.\"`n`n\"`#Wait a minute, \"implants?\" What?`0\" you ask, even more scared now than you were two seconds ago.`n`n\"`&What did I tell you about questions? There are other people waiting. Come on, off you go.`0\" She takes you by the shoulders, swivels you towards the gate, and gives you a firm slap on your behind.  You see no other choice but to start walking.`n`n\"`&You there!`0\" calls `\$The Watcher`0 behind you. \"`&Yes, you, with the cellulite! You're in a tree because you've just been thrown out of an aeroplane! You've got to blow up an insane, reality-warping machine before we'll let you go home! You're naked because it's funnier that way! You desperately need a bikini wax, and you can buy weapons in that outpost over there! Stop crying, you're on television!`0\"`n`nYou shudder, and keep walking.`n`nWithin a few paces, you're at the gate of the Outpost. A man with a huge, bushy blonde beard sits in a little hut, writing on a newspaper with a pencil.`n`nYou clear your throat. \"`#Um, excuse me...`0\"`n`nThe man holds up a hand, still looking at his newspaper. \"`6Four-letter word, starts with N, the clue is \"Clad only in skin and innocence.\" Any ideas?`0\"`n`nYou shrug. \"`#Nude?`0\"`n`nThe man leans forward, cupping a hand to his ear. \"`6What was that? You'll have to speak up, they're buggers around here with their loud bloody grenades at every hour of the day and night.`0\"`n`n\"`#Nude,`0\" you respond, a little louder.`n`n\"`6Of course! Newb!`0\" He chuckles heartily, and writes in his paper. \"`6Enn, oh, oh, bee. Newb. Thanks for that. Now, what can I do for you?`0\"`n`n\"`#I honestly have no idea.`0\"`n`n\"`6Ah, so you're a newb yourself?`0\"`n`n\"`#Apparently. At least, according to the blonde woman over there.`0\"`n`nThe hairy man smiles, not unkindly. \"`6Well, let's fill you in on things.  First of all, what should I call you?`0\"`n`n");
            rawoutput("<form action='runmodule.php?module=homepage&op=0&r={$r}' method='POST'\">\"<span class=\"colLtCyan\">You can call me <input name='name' id=\"name\" accesskey='u' size='12'>, I guess.</span>\"  It's as good a name as any.");
            rawoutput("<br /><div align=\"center\"><input type='submit' value='Carry On' class='button'></div><br /><br /></form>");
            addnav("", "runmodule.php?module=homepage&op=0&r=" . $r);
            break;
    }
    return $args;
}
require_once "lib/http.php";
if (!isset($session['loggedin'])) {
    $session['loggedin'] = false;
}
if ($session['loggedin']) {
    redirect("badnav.php");
}
tlschema("home");
$op = httpget('op');
page_header();
output("`cWelcome to Legend of the Green Dragon, a browser based role playing game, based on Seth Able's Legend of the Red Dragon.`n");
if (getsetting("homecurtime", 1)) {
    output("`@The current time in %s is `%%s`@.`0`n", getsetting("villagename", LOCATION_FIELDS), getgametime());
}
if (getsetting("homenewdaytime", 1)) {
    $secstonewday = secondstonextgameday();
    output("`@Next new game day in: `\$%s (real time)`0`n`n", date("G\\" . translate_inline("h", "datetime") . ", i\\" . translate_inline("m", "datetime") . ", s\\" . translate_inline("s", "datetime"), $secstonewday));
}
if (getsetting("homenewestplayer", 1)) {
    $name = "";
    $newplayer = getsetting("newestplayer", "");
    if ($newplayer != 0) {
        $sql = "SELECT name FROM " . db_prefix("accounts") . " WHERE acctid='{$newplayer}'";
        $result = db_query_cached($sql, "newest");
        $row = db_fetch_assoc($result);
        $name = $row['name'];
    } else {
        $name = $newplayer;
    }
    if ($name != "") {
        output("`QThe newest resident of the realm is: `&%s`0`n`n", $name);