Compare commits
7 Commits
df99415ece
...
5ea0de2ae1
Author | SHA1 | Date | |
---|---|---|---|
5ea0de2ae1 | |||
82a2e42cb9 | |||
61ae46714d | |||
2b53868f52 | |||
67cacf7882 | |||
ba4719f97a | |||
042bca2364 |
|
@ -62,26 +62,30 @@ function donothing()
|
|||
function primary()
|
||||
{
|
||||
if (isset($_POST["submit"])) {
|
||||
$errors = [];
|
||||
$form = validate($_POST, [
|
||||
'gamename' => ['alphanum-spaces', 'length:1-20'],
|
||||
'gamesize' => ['int', 'min:5'],
|
||||
'class1name' => ['alpha-spaces', 'length:1-18'],
|
||||
'class2name' => ['alpha-spaces', 'length:1-18'],
|
||||
'class3name' => ['alpha-spaces', 'length:1-18'],
|
||||
'gameopen' => ['bool'],
|
||||
'verifyemail' => ['bool'],
|
||||
'shownews' => ['bool'],
|
||||
'showonline' => ['bool'],
|
||||
'showbabble' => ['bool']
|
||||
]);
|
||||
|
||||
$gn = trim($_POST['gamename'] ?? 'Dragon Knight');
|
||||
$gs = (int) trim($_POST['gamesize'] ?? 250);
|
||||
$c1n = trim($_POST['class1name'] ?? 'Mage');
|
||||
$c2n = trim($_POST['class2name'] ?? 'Warrior');
|
||||
$c3n = trim($_POST['class3name'] ?? 'Paladin');
|
||||
if ($form['valid']) {
|
||||
$form = $form['data'];
|
||||
if (($form['gamesize'] % 5) != 0) exit('Map size must be divisible by five.');
|
||||
|
||||
if (empty($gn)) $errors[] = "Game name is required.";
|
||||
if (!is_int($gs) || !($gs > 0) || ($gs % 5) != 0) $errors[] = "Map size must be a number greater than 0 and divisible by five.";
|
||||
if (empty($c1n) || empty($c2n) || empty($c3n)) $errors[] = "Class names are required.";
|
||||
|
||||
if (count($errors) === 0) {
|
||||
db()->query('UPDATE control SET gamename=?, gamesize=?, class1name=?, class2name=?, class3name=?, gameopen=?, verifyemail=?, gameurl=?, adminemail=?, shownews=?, showonline=?, showbabble=? WHERE id=1;', [
|
||||
$gn, $gs, $c1n, $c2n, $c3n, $_POST['gameopen'] ?? 1, $_POST['verifyemail'] ?? 1, $_POST['gameurl'] ?? '', $_POST['adminemail'] ?? '', $_POST['shownews'] ?? 1, $_POST['showonline'] ?? 1, $_POST['showbabble'] ?? 1
|
||||
$form['gamename'], $form['gamesize'], $form['class1name'], $form['class1name'], $form['class1name'], $form['gameopen'], $form['verifyemail'], $form['gameurl'], $form['adminemail'], $form['shownews'], $form['showonline'], $form['showbabble']
|
||||
]);
|
||||
|
||||
admindisplay("Settings updated.", "Main Settings");
|
||||
} else {
|
||||
$errorlist = implode('<br>', $errors);
|
||||
$errorlist = ul_from_validate_errors($form['errors']);
|
||||
admindisplay("<b>Errors:</b><br><div style=\"color:red;\">$errorlist</div><br>Please go back and try again.", "Main Settings");
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +99,7 @@ function primary()
|
|||
<table width="90%">
|
||||
<tr><td width="20%"><span class="highlight">Game Open:</span></td><td><select name="gameopen"><option value="1" {{open1select}}>Open</option><option value="0" {{open0select}}>Closed</option></select><br><span class="small">Close the game if you are upgrading or working on settings and don't want to cause odd errors for end-users. Closing the game will completely halt all activity.</span></td></tr>
|
||||
<tr><td width="20%">Game Name:</td><td><input type="text" name="gamename" value="{{gamename}}" /><br><span class="small">Default is "Dragon Knight". Change this if you want to change to call your game something different.</span></td></tr>
|
||||
<tr><td width="20%">Game URL:</td><td><input type="text" name="gameurl" value="{{gameurl}}" /><br><span class="small">Please specify the full URL to your game installation ("http://www.server.com/dkpath/index.php"). This gets used in the registration email sent to users. If you leave this field blank or incorrect, users may not be able to register correctly.</span></td></tr>
|
||||
<tr><td width="20%">Game URL:</td><td><input type="text" name="gameurl" value="{{gameurl}}" /><br><span class="small">Please specify the full URL to your game installation ("https://www.dragonknight.com/"). This gets used in the registration email sent to users. If you leave this field blank or incorrect, users may not be able to register correctly.</span></td></tr>
|
||||
<tr><td width="20%">Admin Email:</td><td><input type="text" name="adminemail" value="{{adminemail}}" /><br><span class="small">Please specify your email address. This gets used when the game has to send an email to users.</span></td></tr>
|
||||
<tr><td width="20%">Map Size:</td><td><input type="text" name="gamesize" value="{{gamesize}}" /><br><span class="small">Default is 250. This is the size of each map quadrant. Note that monster levels increase every 5 spaces, so you should ensure that you have at least (map size / 5) monster levels total, otherwise there will be parts of the map without any monsters, or some monsters won't ever get used. Ex: with a map size of 250, you should have 50 monster levels total.</span></td></tr>
|
||||
<tr><td width="20%">Email Verification:</td><td><select name="verifyemail"><option value="0" {{selectverify0}}>Disabled</option><option value="1" {{selectverify1}}>Enabled</option></select><br><span class="small">Make users verify their email address for added security.</span></td></tr>
|
||||
|
|
181
public/css/dk.css
Normal file
|
@ -0,0 +1,181 @@
|
|||
:root {
|
||||
--font-size: 12px;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: var(--font-size);
|
||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-image: url('/img/background.jpg');
|
||||
}
|
||||
|
||||
div#game-container {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: solid 2px black;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
main {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
main > section {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
main > section > section:not(:last-child) {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
main section#left {
|
||||
width: 180px;
|
||||
border-right: solid 2px black;
|
||||
}
|
||||
|
||||
main section#middle {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
main section#right {
|
||||
width: 180px;
|
||||
border-left: solid 2px black;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
border: solid 1px black;
|
||||
background-color: #eeeeee;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
table {
|
||||
border-style: none;
|
||||
padding: 0px;
|
||||
font-size: var(--font-size);
|
||||
}
|
||||
|
||||
td {
|
||||
border-style: none;
|
||||
padding: 3px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td.top {
|
||||
border-bottom: solid 2px black;
|
||||
}
|
||||
|
||||
td.left {
|
||||
width: 180px;
|
||||
border-right: solid 2px black;
|
||||
}
|
||||
|
||||
td.right {
|
||||
width: 180px;
|
||||
border-left: solid 2px black;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #663300;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #330000;
|
||||
}
|
||||
|
||||
.small {
|
||||
font: 10px verdana;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.light {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.title {
|
||||
border: solid 1px black;
|
||||
background-color: #eeeeee;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
font-size: 1.2rem;
|
||||
font-family: 'Times New Roman', Times, serif;
|
||||
}
|
||||
|
||||
.copyright {
|
||||
border: solid 1px black;
|
||||
background-color: #eeeeee;
|
||||
font: 10px verdana;
|
||||
}
|
||||
|
||||
.move-compass {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-image: url('/img/compass.webp');
|
||||
margin: 0.5rem auto;
|
||||
}
|
||||
|
||||
.move-compass div.mid {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.move-compass button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: transparent; /* Hide the text */
|
||||
background-size: cover; /* Ensure the background image fills the button */
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.move-compass button:hover {
|
||||
background-color: rgba(225, 16, 16, 0.5);
|
||||
}
|
||||
|
||||
.move-compass button.north {
|
||||
width: 128px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.move-compass button.west {
|
||||
width: 63px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.move-compass button.east {
|
||||
width: 63px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.move-compass button.south {
|
||||
width: 128px;
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
div.town-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
div.town-content div.options, div.town-content div.news {
|
||||
grid-column: span 2;
|
||||
}
|
|
@ -85,13 +85,22 @@ function reply()
|
|||
{
|
||||
global $userrow;
|
||||
|
||||
$p = $_POST['parent'] ?? 0;
|
||||
$t = trim($_POST['title'] ?? '');
|
||||
$c = trim($_POST['content'] ?? '');
|
||||
$form = validate($_POST, [
|
||||
'title' => ['length:2-30', 'alphanum-spaces'],
|
||||
'content' => []
|
||||
]);
|
||||
|
||||
db()->query('INSERT INTO forum (author, title, content, parent) VALUES (?, ?, ?, ?);', [$userrow['username'], $t, $c, $p]);
|
||||
db()->query('UPDATE forum SET newpostdate=CURRENT_TIMESTAMP, replies=replies + 1 WHERE id=?;', [$p]);
|
||||
redirect("forum.php?do=thread:$p:0");
|
||||
if (!$form['valid']) {
|
||||
exit(ul_from_validate_errors($form['errors']));
|
||||
}
|
||||
|
||||
$form = $form['data'];
|
||||
|
||||
db()->query('INSERT INTO forum (author, title, content, parent) VALUES (?, ?, ?, ?);', [
|
||||
$userrow['username'], $form['title'], $form['content'], $form['parent']
|
||||
]);
|
||||
db()->query('UPDATE forum SET newpostdate=CURRENT_TIMESTAMP, replies=replies + 1 WHERE id=?;', [$form['parent']]);
|
||||
redirect("forum.php?do=thread:{$form['parent']}:0");
|
||||
}
|
||||
|
||||
function newthread()
|
||||
|
@ -99,10 +108,19 @@ function newthread()
|
|||
global $userrow;
|
||||
|
||||
if (isset($_POST["submit"])) {
|
||||
extract($_POST);
|
||||
$t = trim($_POST['title'] ?? '');
|
||||
$c = trim($_POST['content'] ?? '');
|
||||
db()->query('INSERT INTO forum (author, title, content) VALUES (?, ?, ?);', [$userrow['username'], $t, $c]);
|
||||
$form = validate($_POST, [
|
||||
'title' => ['length:2-30', 'alphanum-spaces'],
|
||||
'content' => []
|
||||
]);
|
||||
|
||||
if (!$form['valid']) {
|
||||
exit(ul_from_validate_errors($form['errors']));
|
||||
}
|
||||
|
||||
$form = $form['data'];
|
||||
db()->query('INSERT INTO forum (author, title, content) VALUES (?, ?, ?);', [
|
||||
$userrow['username'], $form['title'], $form['content']
|
||||
]);
|
||||
redirect('forum.php');
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ if (!in_array($page, ['main', 'items', 'levels', 'monsters', 'spells'])) $page =
|
|||
<title><?= $controlrow["gamename"] ?> Help</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url('images/background.jpg');
|
||||
background-image: url('/img/background.jpg');
|
||||
color: black;
|
||||
font: 11px verdana;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ if (!in_array($page, ['main', 'items', 'levels', 'monsters', 'spells'])) $page =
|
|||
<body>
|
||||
<a name="top"></a>
|
||||
<h1><?= $controlrow["gamename"] ?> Help</h1>
|
||||
[ <a href="/index.php">Return to the game</a> ]
|
||||
[ <a href="/">Return to the game</a> ]
|
||||
|
||||
<br><br><hr>
|
||||
|
||||
|
@ -300,7 +300,7 @@ if (!in_array($page, ['main', 'items', 'levels', 'monsters', 'spells'])) $page =
|
|||
</ul>
|
||||
Apologies and lots of happy naked love to anyone I forgot. <br><br>
|
||||
And of course, thanks to <b>you</b> for playing my game! <br><br>
|
||||
<a href="/index.php?do=ninja">NINJA!</a> <br><br>
|
||||
<a href="/ninja">NINJA!</a> <br><br>
|
||||
[ <a href="#top">Top</a> ]
|
||||
|
||||
<br><br><hr><br>
|
||||
|
@ -342,7 +342,7 @@ if (!in_array($page, ['main', 'items', 'levels', 'monsters', 'spells'])) $page =
|
|||
$bigspecial = '<span class="light">None</span>';
|
||||
}
|
||||
|
||||
echo "<tr><td width=\"5%\"><img src=\"images/icon_$image.gif\" alt=\"$image\"></td><td width=\"30%\">".$item["name"]."</td><td width=\"20%\">".$item["buycost"]." Gold</td><td width=\"20%\">".$item["attribute"]." $power Power</td><td width=\"25%\">$bigspecial</td></tr>\n";
|
||||
echo "<tr><td width=\"5%\"><img src=\"/img/icon_$image.gif\" alt=\"$image\"></td><td width=\"30%\">".$item["name"]."</td><td width=\"20%\">".$item["buycost"]." Gold</td><td width=\"20%\">".$item["attribute"]." $power Power</td><td width=\"25%\">$bigspecial</td></tr>\n";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
|
|
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 94 B After Width: | Height: | Size: 94 B |
Before Width: | Height: | Size: 94 B After Width: | Height: | Size: 94 B |
Before Width: | Height: | Size: 94 B After Width: | Height: | Size: 94 B |
Before Width: | Height: | Size: 527 B After Width: | Height: | Size: 527 B |
Before Width: | Height: | Size: 575 B After Width: | Height: | Size: 575 B |
Before Width: | Height: | Size: 561 B After Width: | Height: | Size: 561 B |
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 402 B |
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 486 B After Width: | Height: | Size: 486 B |
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 500 B After Width: | Height: | Size: 500 B |
Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 523 B |
Before Width: | Height: | Size: 565 B After Width: | Height: | Size: 565 B |
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 469 B |
Before Width: | Height: | Size: 461 B After Width: | Height: | Size: 461 B |
BIN
public/img/compass.webp
Normal file
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 147 B |
Before Width: | Height: | Size: 121 B After Width: | Height: | Size: 121 B |
Before Width: | Height: | Size: 112 B After Width: | Height: | Size: 112 B |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1005 B After Width: | Height: | Size: 1005 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
123
public/index.php
|
@ -3,6 +3,7 @@
|
|||
// index.php :: Primary program script, evil alien overlord, you decide.
|
||||
|
||||
require_once '../src/lib.php';
|
||||
require_once '../src/router.php';
|
||||
|
||||
if (!file_exists('../.installed')) redirect('install.php');
|
||||
|
||||
|
@ -41,31 +42,64 @@ require_once '../src/explore.php';
|
|||
require_once '../src/fight.php';
|
||||
require_once '../src/heal.php';
|
||||
|
||||
$do = explode(':', $_GET['do'] ?? '');
|
||||
match ($do[0]) {
|
||||
'inn' => inn(),
|
||||
'buy' => buy(),
|
||||
'buy2' => buy2($do[1]),
|
||||
'buy3' => buy3($do[1]),
|
||||
// 'sell' => sell(),
|
||||
'maps' => maps(),
|
||||
'maps2' => maps2($do[1]),
|
||||
'maps3' => maps3($do[1]),
|
||||
'gotown' => travelto($do[1]),
|
||||
'move' => move(),
|
||||
'fight' => fight(),
|
||||
'victory' => victory(),
|
||||
'drop' => drop(),
|
||||
'dead' => dead(),
|
||||
'verify' => header("Location: users.php?do=verify"),
|
||||
'spell' => healspells($do[1]),
|
||||
'showchar' => showchar(),
|
||||
'onlinechar' => onlinechar($do[1]),
|
||||
'showmap' => showmap(),
|
||||
'babblebox' => babblebox(),
|
||||
'ninja' => ninja(),
|
||||
default => donothing()
|
||||
};
|
||||
$r = new Router;
|
||||
|
||||
$r->get('/', function() {
|
||||
global $userrow;
|
||||
|
||||
if ($userrow["currentaction"] == "In Town") {
|
||||
$page = dotown();
|
||||
$title = "In Town";
|
||||
} elseif ($userrow["currentaction"] == "Exploring") {
|
||||
$page = doexplore();
|
||||
$title = "Exploring";
|
||||
} elseif ($userrow["currentaction"] == "Fighting") {
|
||||
redirect('/fight');
|
||||
}
|
||||
|
||||
display($page, $title);
|
||||
});
|
||||
|
||||
$r->get('/ninja', function() {
|
||||
exit('NINJA! 🥷');
|
||||
});
|
||||
|
||||
$r->get('/inn', 'inn');
|
||||
$r->post('/inn', 'inn');
|
||||
$r->get('/buy', 'buy');
|
||||
$r->get('/buy2/:id', 'buy2');
|
||||
$r->post('/buy3/:id', 'buy3');
|
||||
// $r->get('/sell', 'sell');
|
||||
$r->get('/maps', 'maps');
|
||||
$r->get('/maps2/:id', 'maps2');
|
||||
$r->post('/maps3/:id', 'maps3');
|
||||
$r->get('/gotown/:id', 'travelto');
|
||||
|
||||
$r->post('/move', 'move');
|
||||
|
||||
$r->get('/fight', 'fight');
|
||||
$r->post('/fight', 'fight');
|
||||
$r->get('/victory', 'victory');
|
||||
$r->get('/drop', 'drop');
|
||||
$r->post('/drop', 'drop');
|
||||
$r->get('/dead', 'dead');
|
||||
|
||||
$r->get('/verify', function() {
|
||||
redirect('users.php?do=verify');
|
||||
});
|
||||
$r->get('/spell/:id', 'healspells');
|
||||
$r->get('/showchar', 'showchar');
|
||||
$r->get('/onlinechar/:id', 'onlinechar');
|
||||
$r->get('/showmap', 'showmap');
|
||||
$r->get('/babblebox', 'babblebox');
|
||||
$r->post('/babblebox', 'babblebox');
|
||||
|
||||
// [code, handler, params, middleware]
|
||||
$l = $r->lookup($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
|
||||
|
||||
if ($l['code'] !== 200) exit($l['code']);
|
||||
if (!empty($l['middleware'])) foreach ($l['middleware'] as $middleware) $middleware();
|
||||
$l['handler'](...$l['params'] ?? []);
|
||||
|
||||
function donothing()
|
||||
{
|
||||
|
@ -78,7 +112,7 @@ function donothing()
|
|||
$page = doexplore();
|
||||
$title = "Exploring";
|
||||
} elseif ($userrow["currentaction"] == "Fighting") {
|
||||
redirect('index.php?do=fight');
|
||||
redirect('/fight');
|
||||
}
|
||||
|
||||
display($page, $title);
|
||||
|
@ -101,9 +135,8 @@ function dotown()
|
|||
// News box. Grab latest news entry and display it. Something a little more graceful coming soon maybe.
|
||||
if ($controlrow["shownews"] == 1) {
|
||||
$newsrow = db()->query('SELECT * FROM news ORDER BY id DESC LIMIT 1;')->fetchArray(SQLITE3_ASSOC);
|
||||
$townrow["news"] = "<table width=\"95%\"><tr><td class=\"title\">Latest News</td></tr><tr><td>\n";
|
||||
$townrow["news"] = '<div class="title">Latest News</div>';
|
||||
$townrow["news"] .= "<span class=\"light\">[".prettydate($newsrow["postdate"])."]</span><br>".nl2br($newsrow["content"]);
|
||||
$townrow["news"] .= "</td></tr></table>\n";
|
||||
}
|
||||
|
||||
// Who's Online. Currently just members. Guests maybe later.
|
||||
|
@ -115,25 +148,21 @@ function dotown()
|
|||
|
||||
while ($onlinerow = $onlinequery->fetchArray(SQLITE3_ASSOC)) {
|
||||
$online_count++;
|
||||
$online_rows[] = "<a href=\"index.php?do=onlinechar:".$onlinerow["id"]."\">".$onlinerow["username"]."</a>";
|
||||
$online_rows[] = "<a href=\"/onlinechar/{$onlinerow["id"]}\">".$onlinerow["username"]."</a>";
|
||||
}
|
||||
|
||||
$townrow["whosonline"] = "<table width=\"95%\"><tr><td class=\"title\">Who's Online</td></tr><tr><td>\n";
|
||||
$townrow["whosonline"] = '<div class="title">Who\'s Online</div>';
|
||||
$townrow["whosonline"] .= "There are <b>$online_count</b> user(s) online within the last 10 minutes: ";
|
||||
$townrow["whosonline"] .= rtrim(implode(', ', $online_rows), ', ');
|
||||
$townrow["whosonline"] .= "</td></tr></table>\n";
|
||||
}
|
||||
|
||||
if ($controlrow["showbabble"] == 1) {
|
||||
$townrow["babblebox"] = <<<HTML
|
||||
<table width="95%">
|
||||
<tr><td class="title">Babble Box</td></tr>
|
||||
<tr><td>
|
||||
<iframe src="index.php?do=babblebox" name="sbox" width="100%" height="250" frameborder="0" id="bbox">
|
||||
Your browser does not support inline frames! The Babble Box will not be available until you upgrade to a newer <a href="http://www.mozilla.org" target="_new">browser</a>.
|
||||
</iframe>
|
||||
</td></tr>
|
||||
</table>
|
||||
<div class="title">Babble Box</div>
|
||||
<iframe src="/babblebox" name="sbox" width="100%" height="250" frameborder="0" id="bbox">
|
||||
Your browser does not support inline frames! The Babble Box will not be available until you upgrade to
|
||||
a newer <a href="http://www.mozilla.org" target="_new">browser</a>.
|
||||
</iframe>
|
||||
HTML;
|
||||
}
|
||||
|
||||
|
@ -148,7 +177,7 @@ function doexplore()
|
|||
{
|
||||
return <<<HTML
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/title_exploring.gif" alt="Exploring" /></td></tr>
|
||||
<tr><td class="title"><img src="/img/title_exploring.gif" alt="Exploring" /></td></tr>
|
||||
<tr><td>
|
||||
You are exploring the map, and nothing has happened. Continue exploring using the direction buttons or the Travel To menus.
|
||||
</td></tr>
|
||||
|
@ -227,7 +256,7 @@ function onlinechar($id)
|
|||
|
||||
function showmap()
|
||||
{
|
||||
$array = ["content" => "<center><img src=\"images/map.gif\" alt=\"Map\" /></center>", "title" => "Map"];
|
||||
$array = ["content" => "<center><img src=\"/img/map.gif\" alt=\"Map\" /></center>", "title" => "Map"];
|
||||
echo parsetemplate("<html>\n" . gettemplate("minimal"), $array);
|
||||
}
|
||||
|
||||
|
@ -240,18 +269,16 @@ function babblebox()
|
|||
if (!empty($safecontent)) {
|
||||
db()->query('INSERT INTO babble (posttime, author, babble) VALUES (CURRENT_TIMESTAMP, ?, ?);', [$userrow['username'], $safecontent]);
|
||||
}
|
||||
redirect('index.php?do=babblebox');
|
||||
redirect('/babblebox');
|
||||
}
|
||||
|
||||
$babblebox = ["content" => ""];
|
||||
$bg = 1;
|
||||
$query = db()->query('SELECT * FROM babble ORDER BY id DESC LIMIT 20;');
|
||||
$babblebox['content'] = '';
|
||||
$query = db()->query('SELECT * FROM babble ORDER BY id DESC LIMIT 40;');
|
||||
while ($babblerow = $query->fetchArray(SQLITE3_ASSOC)) {
|
||||
if ($bg == 1) { $new = "<div style=\"width:98%; background-color:#eeeeee;\">[<b>".$babblerow["author"]."</b>] ".$babblerow["babble"]."</div>\n"; $bg = 2; }
|
||||
else { $new = "<div style=\"width:98%; background-color:#ffffff;\">[<b>".$babblerow["author"]."</b>] ".stripslashes($babblerow["babble"])."</div>\n"; $bg = 1; }
|
||||
$new = "<div class=\"message\">[<b>{$babblerow["author"]}</b>] {$babblerow["babble"]}</div>\n";
|
||||
$babblebox["content"] = $new . $babblebox["content"];
|
||||
}
|
||||
$babblebox["content"] .= "<center><form action=\"index.php?do=babblebox\" method=\"post\"><input type=\"text\" name=\"babble\" size=\"15\" maxlength=\"120\" /><br><input type=\"submit\" name=\"submit\" value=\"Babble\" /> <input type=\"reset\" name=\"reset\" value=\"Clear\" /></form></center>";
|
||||
$babblebox["content"] .= '<form action="/babblebox" method="post" style="margin-top: 1rem;"><input type="text" name="babble" maxlength="255" style="width: 100%;"><br><input type="submit" name="submit" value="Babble"><input type="reset" name="reset" value="Clear"></form>';
|
||||
|
||||
echo parsetemplate("<html>\n" . gettemplate("babblebox"), $babblebox);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require_once '../src/lib.php';
|
||||
|
||||
if (file_exists('../.installed')) redirect('index.php');
|
||||
if (file_exists('../.installed')) redirect('/');
|
||||
|
||||
$page = $_GET['page'] ?? 1;
|
||||
match ((int) $page) {
|
||||
|
@ -657,11 +657,11 @@ function third()
|
|||
Now you must create an administrator account so you can use the control panel. Fill out the form below to create your account. You will be able to customize the class names through the control panel once your admin account is created.<br><br>
|
||||
<form action="install.php?page=4" method="post">
|
||||
<table width="50%">
|
||||
<tr><td width="20%" style="vertical-align:top;">Username:</td><td><input type="text" name="username" size="30" maxlength="30" /><br><br><br></td></tr>
|
||||
<tr><td style="vertical-align:top;">Password:</td><td><input type="password" name="password1" size="30" maxlength="30" /></td></tr>
|
||||
<tr><td style="vertical-align:top;">Verify Password:</td><td><input type="password" name="password2" size="30" maxlength="30" /><br><br><br></td></tr>
|
||||
<tr><td style="vertical-align:top;">Email Address:</td><td><input type="text" name="email1" size="30" maxlength="100" /></td></tr>
|
||||
<tr><td style="vertical-align:top;">Verify Email:</td><td><input type="text" name="email2" size="30" maxlength="100" /><br><br><br></td></tr>
|
||||
<tr><td width="20%" style="vertical-align:top;">Username:</td><td><input type="text" name="username" /><br><br><br></td></tr>
|
||||
<tr><td style="vertical-align:top;">Password:</td><td><input type="password" name="password" /></td></tr>
|
||||
<tr><td style="vertical-align:top;">Verify Password:</td><td><input type="password" name="confirm_password" /><br><br><br></td></tr>
|
||||
<tr><td style="vertical-align:top;">Email Address:</td><td><input type="text" name="email" /></td></tr>
|
||||
<tr><td style="vertical-align:top;">Verify Email:</td><td><input type="text" name="confirm_email" /><br><br><br></td></tr>
|
||||
<tr><td style="vertical-align:top;">Character Class:</td><td><select name="charclass"><option value="1">Mage</option><option value="2">Warrior</option><option value="3">Paladin</option></select></td></tr>
|
||||
<tr><td colspan="2"><input type="submit" name="submit" value="Submit" /> <input type="reset" name="reset" value="Reset" /></td></tr>
|
||||
</table>
|
||||
|
@ -676,48 +676,22 @@ function third()
|
|||
*/
|
||||
function fourth()
|
||||
{
|
||||
$u = trim($_POST['username'] ??= '');
|
||||
$e = trim($_POST['email1'] ??= '');
|
||||
$ec = trim($_POST['email2'] ??= '');
|
||||
$p = $_POST['password1'] ??= '';
|
||||
$pc = $_POST['password2'] ??= '';
|
||||
$form = validate($_POST, [
|
||||
'username' => ['length:3-18', 'alpha-spaces'],
|
||||
'email' => ['email'],
|
||||
'confirm_email' => ['confirm'],
|
||||
'password' => ['length:6-255'],
|
||||
'confirm_password' => ['confirm']
|
||||
]);
|
||||
|
||||
$errors = [];
|
||||
|
||||
if (empty($u) || strlen($u) < 3 || strlen($u) > 18 || !ctype_alnum(str_replace(' ', '', $u))) {
|
||||
$errors[] = 'Username is required and must be between 3 and 18 characters long and contain only
|
||||
alphanumeric characters and spaces.';
|
||||
}
|
||||
|
||||
if (empty($e) || strlen($e) > 255 || !filter_var($e, FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = 'Email is required must be a valid email address.';
|
||||
}
|
||||
|
||||
if ($e !== $ec) {
|
||||
$errors[] = 'Verify Email must match.';
|
||||
}
|
||||
|
||||
if (empty($p) || strlen($p) < 6) {
|
||||
$errors[] = 'Password is required and must be at least 6 characters long.';
|
||||
}
|
||||
|
||||
if ($pc !== $p) {
|
||||
$errors[] = 'Verify Password must match.';
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
echo "<ul>";
|
||||
foreach ($errors as $error) echo "<li>$error</li>";
|
||||
echo "</ul>";
|
||||
exit;
|
||||
}
|
||||
if (!$form['valid']) exit(ul_from_validate_errors($form['errors']));
|
||||
|
||||
$form = $form['data'];
|
||||
if (db()->query(
|
||||
"INSERT INTO users (username, password, email, verify, charclass, authlevel) VALUES (?, ?, ?, 1, ?, 1)",
|
||||
[$u, password_hash($p, PASSWORD_ARGON2ID), $e, $_POST['charclass']]
|
||||
[$form['username'], password_hash($form['password'], PASSWORD_ARGON2ID), $form['email'], $form['charclass']]
|
||||
) === false) {
|
||||
echo "Failed to create user.";
|
||||
exit;
|
||||
exit("Failed to create user.");
|
||||
}
|
||||
|
||||
file_put_contents('../.installed', date('Y-m-d H:i:s'));
|
||||
|
@ -731,7 +705,7 @@ function fourth()
|
|||
<b>Dragon Knight Installation: Page Four</b><br><br>
|
||||
Your admin account was created successfully. Installation is complete.<br><br>
|
||||
Be sure to delete install.php from your Dragon Knight directory for security purposes.<br><br>
|
||||
You are now ready to <a href="index.php">play the game</a>. Note that you must log in through the public section before being allowed into the control panel. Once logged in, an "Admin" link will appear in the Functions box of the left sidebar panel.<br><br/>
|
||||
You are now ready to <a href="/">play the game</a>. Note that you must log in through the public section before being allowed into the control panel. Once logged in, an "Admin" link will appear in the Functions box of the left sidebar panel.<br><br/>
|
||||
Thank you for using Dragon Knight!<br><br>-----<br><br>
|
||||
<b>Optional:</b> Dragon Knight is a free product, and does not require registration of any sort. However, there is an
|
||||
optional "call home" function in the installer, which notifies the author of your game installation. The ONLY information
|
||||
|
@ -749,7 +723,7 @@ function fourth()
|
|||
function fifth()
|
||||
{
|
||||
if (mail("sky@sharkk.net", "Dragon Knight Call Home", $_SERVER["SERVER_NAME"].$_SERVER["PHP_SELF"]) !== true) {
|
||||
exit('Dragon Knight was unable to send your URL. Please go back and try again, or just continue on to <a href=\"index.php\">the game</a>.');
|
||||
exit('Dragon Knight was unable to send your URL. Please go back and try again, or just continue on to <a href=\"/\">the game</a>.');
|
||||
}
|
||||
|
||||
echo <<<HTML
|
||||
|
@ -760,7 +734,7 @@ function fifth()
|
|||
<body>
|
||||
<b>Dragon Knight Installation: Page Five</b><br><br>
|
||||
Thank you for submitting your URL!<br><br>
|
||||
You are now ready to <a href="index.php">play the game</a>. Note that you must log in through the public section before being allowed into the control panel. Once logged in, an "Admin" link will appear in the Functions box of the left sidebar panel.
|
||||
You are now ready to <a href="/">play the game</a>. Note that you must log in through the public section before being allowed into the control panel. Once logged in, an "Admin" link will appear in the Functions box of the left sidebar panel.
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
|
|
|
@ -13,23 +13,33 @@ match ($_GET['do'] ?? 'login') {
|
|||
|
||||
function login()
|
||||
{
|
||||
if (checkcookies() !== false) redirect('index.php');
|
||||
if (checkcookies() !== false) redirect('/');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$u = trim($_POST['username'] ?? '');
|
||||
$form = validate($_POST, [
|
||||
'username' => ['length:3-18', 'alpha-spaces'],
|
||||
'password' => ['length:6-255'],
|
||||
'remember' => ['bool']
|
||||
]);
|
||||
|
||||
$query = db()->query('SELECT id, username, password FROM users WHERE username = ? LIMIT 1;', [$u]);
|
||||
if ($query === false) die("Invalid username or password. Please go back and try again.");
|
||||
$row = $query->fetchArray(SQLITE3_ASSOC);
|
||||
if (!password_verify($_POST['password'] ?? '', $row['password'])) die("Invalid username or password. Please go back and try again.");
|
||||
if (!$form['valid']) {
|
||||
exit(ul_from_validate_errors($form['errors']));
|
||||
}
|
||||
|
||||
$expiretime = isset($_POST["rememberme"]) ? time() + 31536000 : 0;
|
||||
$rememberme = isset($_POST["rememberme"]) ? 1 : 0;
|
||||
$form = $form['data'];
|
||||
|
||||
$query = db()->query('SELECT id, username, password FROM users WHERE username = ? COLLATE NOCASE LIMIT 1;', [$form['username']]);
|
||||
$row = $query ? $query->fetchArray(SQLITE3_ASSOC) : false;
|
||||
|
||||
if ($row === false || !password_verify($_POST['password'] ?? '', $row['password']))
|
||||
die("Invalid username or password. Please go back and try again.");
|
||||
|
||||
$expiretime = $form['remember'] ? time() + 31536000 : 0;
|
||||
$rememberme = $form['remember'] ? 1 : 0;
|
||||
$cookie = implode(' ', [$row['id'], $row['username'], $row['password'], $rememberme]);
|
||||
|
||||
set_cookie("dkgame", $cookie, $expiretime);
|
||||
header("Location: index.php");
|
||||
exit;
|
||||
redirect('/');
|
||||
}
|
||||
|
||||
$page = gettemplate("login");
|
||||
|
@ -41,6 +51,5 @@ function login()
|
|||
function logout()
|
||||
{
|
||||
set_cookie("dkgame", "", -3600);
|
||||
header("Location: login.php?do=login");
|
||||
die();
|
||||
redirect('login.php?do=login');
|
||||
}
|
||||
|
|
|
@ -24,61 +24,28 @@ function register()
|
|||
global $controlrow;
|
||||
|
||||
if (isset($_POST["submit"])) {
|
||||
$u = trim($_POST['username'] ?? '');
|
||||
$e = trim($_POST['email1'] ?? '');
|
||||
$e2 = trim($_POST['email2'] ?? '');
|
||||
$p = $_POST['password1'] ?? '';
|
||||
$p2 = $_POST['password2'] ?? '';
|
||||
$form = validate($_POST, [
|
||||
'username' => ['length:3-18', 'alpha-spaces', 'unique:users,username'],
|
||||
'email' => ['email', 'unique:users,email'],
|
||||
'confirm_email' => ['confirm'],
|
||||
'password' => ['length:6-255'],
|
||||
'confirm_password' => ['confirm'],
|
||||
'charclass' => ['in:1,2,3']
|
||||
]);
|
||||
|
||||
$errors = [];
|
||||
|
||||
// Process username.
|
||||
if (empty($u) || strlen($u) < 3 || strlen($u) > 18 || !ctype_alnum(str_replace(' ', '', $u))) {
|
||||
$errors[] = 'Username is required and must be between 3 and 18 characters long and contain only
|
||||
alphanumeric characters and spaces.';
|
||||
}
|
||||
|
||||
if (db()->exists('users', 'username', $u)) {
|
||||
$errors[] = 'Username already taken. Try another.';
|
||||
}
|
||||
|
||||
// Process email address.
|
||||
if (empty($e) || strlen($e) > 255 || !filter_var($e, FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[] = 'Email is required must be a valid email address.';
|
||||
}
|
||||
|
||||
if ($e !== $e2) {
|
||||
$errors[] = 'Verify Email must match.';
|
||||
}
|
||||
|
||||
if (db()->exists('users', 'email', $e)) {
|
||||
$errors[] = 'Email already taken. Forgot your password?';
|
||||
}
|
||||
|
||||
// Process password.
|
||||
if (empty($p) || strlen($p) < 6) {
|
||||
$errors[] = 'Password is required and must be at least 6 characters long.';
|
||||
}
|
||||
|
||||
if ($p2 !== $p) {
|
||||
$errors[] = 'Verify Password must match.';
|
||||
}
|
||||
|
||||
$password = password_hash($p, PASSWORD_ARGON2ID);
|
||||
|
||||
if (count($errors) !== 0) {
|
||||
$err = "<ul>";
|
||||
foreach ($errors as $error) $err .= "<li>$error</li>";
|
||||
$err .= "</ul>";
|
||||
if (!$form['valid']) {
|
||||
$err = ul_from_validate_errors($form['errors']);
|
||||
$page = "The following error(s) occurred when your account was being made:<br><span style=\"color:red;\">$err</span><br>Please go back and try again.";
|
||||
} else {
|
||||
$form = $form['data'];
|
||||
$password = password_hash($form['password'], PASSWORD_ARGON2ID);
|
||||
$token = ($controlrow['verifyemail'] == true) ? token(8) : 'g2g';
|
||||
db()->query('INSERT INTO users (verify, username, password, email, charclass) VALUES (?, ?, ?, ?, ?)', [
|
||||
$token, $u, $password, $e, $_POST['charclass'] ?? 1
|
||||
$token, $form['username'], $password, $form['email'], $form['charclass']
|
||||
]);
|
||||
|
||||
if ($controlrow['verifyemail'] == true) {
|
||||
if (sendregmail($e, $token)) {
|
||||
if (sendregmail($form['email'], $token)) {
|
||||
$page = "Your account was created successfully.<br><br>You should receive an Account Verification email shortly. You will need the verification code contained in that email before you are allowed to log in. Once you have received the email, please visit the <a href=\"users.php?do=verify\">Verification Page</a> to enter your code and start playing.";
|
||||
} else {
|
||||
$page = "Your account was created successfully.<br><br>However, there was a problem sending your verification email. Please check with the game administrator to help resolve this problem.";
|
||||
|
@ -97,7 +64,6 @@ function register()
|
|||
$page = parsetemplate(gettemplate("register"), $controlrow);
|
||||
}
|
||||
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"images/button_login.gif\" alt=\"Log In\" border=\"0\" /></a><a href=\"users.php?do=register\"><img src=\"images/button_register.gif\" alt=\"Register\" border=\"0\" /></a><a href=\"help.php\"><img src=\"images/button_help.gif\" alt=\"Help\" border=\"0\" /></a>";
|
||||
display($page, "Register", false, false, false);
|
||||
}
|
||||
|
||||
|
@ -116,7 +82,7 @@ function verify()
|
|||
display("Your account was verified successfully.<br><br>You may now continue to the <a href=\"login.php?do=login\">Login Page</a> and start playing the game.<br><br>Thanks for playing!","Verify Email",false,false,false);
|
||||
}
|
||||
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"images/button_login.gif\" alt=\"Log In\" border=\"0\" /></a><a href=\"users.php?do=register\"><img src=\"images/button_register.gif\" alt=\"Register\" border=\"0\" /></a><a href=\"help.php\"><img src=\"images/button_help.gif\" alt=\"Help\" border=\"0\" /></a>";
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"/img/button_login.gif\" alt=\"Log In\" border=\"0\" /></a><a href=\"users.php?do=register\"><img src=\"/img/button_register.gif\" alt=\"Register\" border=\"0\" /></a><a href=\"help.php\"><img src=\"/img/button_help.gif\" alt=\"Help\" border=\"0\" /></a>";
|
||||
display(gettemplate("verify"), "Verify Email", false, false, false);
|
||||
}
|
||||
|
||||
|
@ -139,7 +105,7 @@ function lostpassword()
|
|||
}
|
||||
}
|
||||
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"images/button_login.gif\" alt=\"Log In\" border=\"0\" /></a><a href=\"users.php?do=register\"><img src=\"images/button_register.gif\" alt=\"Register\" border=\"0\" /></a><a href=\"help.php\"><img src=\"images/button_help.gif\" alt=\"Help\" border=\"0\" /></a>";
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"/img/button_login.gif\" alt=\"Log In\" border=\"0\" /></a><a href=\"users.php?do=register\"><img src=\"/img/button_register.gif\" alt=\"Register\" border=\"0\" /></a><a href=\"help.php\"><img src=\"/img/button_help.gif\" alt=\"Help\" border=\"0\" /></a>";
|
||||
display(gettemplate("lostpassword"), "Lost Password", false, false, false);
|
||||
|
||||
}
|
||||
|
@ -174,7 +140,7 @@ function changepassword()
|
|||
display("Your password was changed successfully.<br><br>You have been logged out of the game to avoid errors.<br><br>Please <a href=\"login.php?do=login\">log back in</a> to continue playing.","Change Password",false,false,false);
|
||||
}
|
||||
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"images/button_login.gif\" alt=\"Log In\" border=\"0\" /></a><a href=\"users.php?do=register\"><img src=\"images/button_register.gif\" alt=\"Register\" border=\"0\" /></a><a href=\"help.php\"><img src=\"images/button_help.gif\" alt=\"Help\" border=\"0\" /></a>";
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"/img/button_login.gif\" alt=\"Log In\" border=\"0\" /></a><a href=\"users.php?do=register\"><img src=\"/img/button_register.gif\" alt=\"Register\" border=\"0\" /></a><a href=\"help.php\"><img src=\"/img/button_help.gif\" alt=\"Help\" border=\"0\" /></a>";
|
||||
display(gettemplate("changepassword"), "Change Password", false, false, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,14 +6,21 @@ function move()
|
|||
{
|
||||
global $userrow, $controlrow;
|
||||
|
||||
if ($userrow["currentaction"] == "Fighting") { header("Location: index.php?do=fight"); die(); }
|
||||
if ($userrow["currentaction"] == "Fighting") { redirect('/fight'); }
|
||||
|
||||
$latitude = $userrow["latitude"];
|
||||
$longitude = $userrow["longitude"];
|
||||
if (isset($_POST["north"])) { $latitude++; if ($latitude > $controlrow["gamesize"]) { $latitude = $controlrow["gamesize"]; } }
|
||||
if (isset($_POST["south"])) { $latitude--; if ($latitude < ($controlrow["gamesize"]*-1)) { $latitude = ($controlrow["gamesize"]*-1); } }
|
||||
if (isset($_POST["east"])) { $longitude++; if ($longitude > $controlrow["gamesize"]) { $longitude = $controlrow["gamesize"]; } }
|
||||
if (isset($_POST["west"])) { $longitude--; if ($longitude < ($controlrow["gamesize"]*-1)) { $longitude = ($controlrow["gamesize"]*-1); } }
|
||||
|
||||
$form = validate($_POST, [
|
||||
'direction' => ['in:north,west,east,south']
|
||||
]);
|
||||
if (!$form['valid']) display(ul_from_validate_errors($form['errors']), 'Move Error');
|
||||
$d = $form['data']['direction'];
|
||||
|
||||
if ($d === 'north') { $latitude++; if ($latitude > $controlrow["gamesize"]) { $latitude = $controlrow["gamesize"]; } }
|
||||
if ($d === 'south') { $latitude--; if ($latitude < ($controlrow["gamesize"]*-1)) { $latitude = ($controlrow["gamesize"]*-1); } }
|
||||
if ($d === 'east') { $longitude++; if ($longitude > $controlrow["gamesize"]) { $longitude = $controlrow["gamesize"]; } }
|
||||
if ($d === 'west') { $longitude--; if ($longitude < ($controlrow["gamesize"]*-1)) { $longitude = ($controlrow["gamesize"]*-1); } }
|
||||
|
||||
$town = get_town_by_xy($longitude, $latitude);
|
||||
if ($town !== false) {
|
||||
|
@ -26,5 +33,5 @@ function move()
|
|||
$action = $chancetofight === 1 ? "currentaction='Fighting', currentfight='1'," : "currentaction='Exploring',";
|
||||
|
||||
db()->query("UPDATE users SET $action latitude = ?, longitude = ?, dropcode = 0 WHERE id = ?;", [$latitude, $longitude, $userrow['id']]);
|
||||
header("Location: index.php");
|
||||
redirect('/');
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ function fight()
|
|||
$pagearray["monsterturn"] = handleMonsterTurn($userrow, $monsterrow);
|
||||
|
||||
db()->query("UPDATE users SET currentaction='Exploring' WHERE id=?;", [$userrow['id']]);
|
||||
redirect('index.php');
|
||||
redirect('/');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ function fight()
|
|||
// Check for monster defeat
|
||||
if ($userrow["currentmonsterhp"] <= 0) {
|
||||
db()->query('UPDATE users SET currentmonsterhp=0 WHERE id=?;', [$userrow['id']]);
|
||||
redirect('index.php?do=victory');
|
||||
redirect('/victory');
|
||||
}
|
||||
|
||||
// Monster's turn
|
||||
|
@ -134,7 +134,7 @@ function fight()
|
|||
db()->query('UPDATE users SET currentmonsterhp=0, currenthp=?, currentmp=? WHERE id=?;', [
|
||||
$userrow['currenthp'], $userrow['currentmp'], $userrow['id']
|
||||
]);
|
||||
redirect('index.php?do=victory');
|
||||
redirect('/victory');
|
||||
}
|
||||
|
||||
// Monster's turn
|
||||
|
@ -152,7 +152,7 @@ function fight()
|
|||
if ($playerisdead != 1) {
|
||||
$pagearray["command"] = <<<HTML
|
||||
Command?<br><br>
|
||||
<form action="index.php?do=fight" method="post">
|
||||
<form action="/fight" method="post">
|
||||
<input type="submit" name="fight" value="Fight" /><br><br>
|
||||
<select name="userspell"><option value="0">Choose One</option>$magiclist</select> <input type="submit" name="spell" value="Spell" /><br><br>
|
||||
<input type="submit" name="run" value="Run" /><br><br>
|
||||
|
@ -183,7 +183,7 @@ function fight()
|
|||
$userrow['id']
|
||||
]);
|
||||
} else {
|
||||
$pagearray["command"] = "<b>You have died.</b><br><br>As a consequence, you've lost half of your gold. However, you have been given back a portion of your hit points to continue your journey.<br><br>You may now continue back to <a href=\"index.php\">town</a>, and we hope you fair better next time.";
|
||||
$pagearray["command"] = "<b>You have died.</b><br><br>As a consequence, you've lost half of your gold. However, you have been given back a portion of your hit points to continue your journey.<br><br>You may now continue back to <a href=\"/\">town</a>, and we hope you fair better next time.";
|
||||
}
|
||||
|
||||
// Finalize page and display it
|
||||
|
@ -194,8 +194,8 @@ function victory()
|
|||
{
|
||||
global $userrow;
|
||||
|
||||
if ($userrow["currentmonsterhp"] != 0) { header("Location: index.php?do=fight"); die(); }
|
||||
if ($userrow["currentfight"] == 0) { header("Location: index.php"); die(); }
|
||||
if ($userrow["currentmonsterhp"] != 0) redirect('/fight');
|
||||
if ($userrow["currentfight"] == 0) redirect('/');
|
||||
|
||||
$monsterrow = get_monster($userrow['currentmonster']);
|
||||
|
||||
|
@ -235,7 +235,7 @@ function victory()
|
|||
$spelltext = "You have learned a new spell.<br>";
|
||||
} else { $spelltext = ""; $newspell=""; }
|
||||
|
||||
$page = "Congratulations. You have defeated the ".$monsterrow["name"].".<br>You gain $exp experience. $warnexp <br>You gain $gold gold. $warngold <br><br><b>You have gained a level!</b><br><br>You gain ".$levelrow[$userrow["charclass"]."_hp"]." hit points.<br>You gain ".$levelrow[$userrow["charclass"]."_mp"]." magic points.<br>You gain ".$levelrow[$userrow["charclass"]."_tp"]." travel points.<br>You gain ".$levelrow[$userrow["charclass"]."_strength"]." strength.<br>You gain ".$levelrow[$userrow["charclass"]."_dexterity"]." dexterity.<br>$spelltext<br>You can now continue <a href=\"index.php\">exploring</a>.";
|
||||
$page = "Congratulations. You have defeated the ".$monsterrow["name"].".<br>You gain $exp experience. $warnexp <br>You gain $gold gold. $warngold <br><br><b>You have gained a level!</b><br><br>You gain ".$levelrow[$userrow["charclass"]."_hp"]." hit points.<br>You gain ".$levelrow[$userrow["charclass"]."_mp"]." magic points.<br>You gain ".$levelrow[$userrow["charclass"]."_tp"]." travel points.<br>You gain ".$levelrow[$userrow["charclass"]."_strength"]." strength.<br>You gain ".$levelrow[$userrow["charclass"]."_dexterity"]." dexterity.<br>$spelltext<br>You can now continue <a href=\"/\">exploring</a>.";
|
||||
$title = "Courage and Wit have served thee well!";
|
||||
$dropcode = "";
|
||||
} else {
|
||||
|
@ -253,10 +253,10 @@ function victory()
|
|||
if (rand(1, 30) === 1) {
|
||||
$droprow = db()->query('SELECT * FROM drops WHERE mlevel <= ? ORDER BY RANDOM() LIMIT 1;', [$monsterrow['level']])->fetchArray(SQLITE3_ASSOC);
|
||||
$dropcode = "dropcode='".$droprow["id"]."',";
|
||||
$page .= "This monster has dropped an item. <a href=\"index.php?do=drop\">Click here</a> to reveal and equip the item, or you may also move on and continue <a href=\"index.php\">exploring</a>.";
|
||||
$page .= "This monster has dropped an item. <a href=\"/drop\">Click here</a> to reveal and equip the item, or you may also move on and continue <a href=\"/\">exploring</a>.";
|
||||
} else {
|
||||
$dropcode = "";
|
||||
$page .= "You can now continue <a href=\"index.php\">exploring</a>.";
|
||||
$page .= "You can now continue <a href=\"/\">exploring</a>.";
|
||||
}
|
||||
|
||||
$title = "Victory!";
|
||||
|
@ -274,7 +274,7 @@ function drop()
|
|||
{
|
||||
global $userrow;
|
||||
|
||||
if ($userrow["dropcode"] == 0) redirect('index.php');
|
||||
if ($userrow["dropcode"] == 0) redirect('/');
|
||||
|
||||
$droprow = get_drop($userrow['dropcode']);
|
||||
|
||||
|
@ -330,7 +330,7 @@ function drop()
|
|||
]);
|
||||
}
|
||||
|
||||
display("The item has been equipped. You can now continue <a href=\"index.php\">exploring</a>.", "Item Drop");
|
||||
display("The item has been equipped. You can now continue <a href=\"/\">exploring</a>.", "Item Drop");
|
||||
}
|
||||
|
||||
$attributearray = array("maxhp"=>"Max HP",
|
||||
|
@ -357,8 +357,8 @@ function drop()
|
|||
}
|
||||
|
||||
$page .= "<br>Select an inventory slot from the list below to equip this item. If the inventory slot is already full, the old item will be discarded.";
|
||||
$page .= "<form action=\"index.php?do=drop\" method=\"post\"><select name=\"slot\"><option value=\"0\">Choose One</option><option value=\"1\">Slot 1: ".$userrow["slot1name"]."</option><option value=\"2\">Slot 2: ".$userrow["slot2name"]."</option><option value=\"3\">Slot 3: ".$userrow["slot3name"]."</option></select> <input type=\"submit\" name=\"submit\" value=\"Submit\" /></form>";
|
||||
$page .= "You may also choose to just continue <a href=\"index.php\">exploring</a> and give up this item.";
|
||||
$page .= "<form action=\"/drop\" method=\"post\"><select name=\"slot\"><option value=\"0\">Choose One</option><option value=\"1\">Slot 1: ".$userrow["slot1name"]."</option><option value=\"2\">Slot 2: ".$userrow["slot2name"]."</option><option value=\"3\">Slot 3: ".$userrow["slot3name"]."</option></select> <input type=\"submit\" name=\"submit\" value=\"Submit\" /></form>";
|
||||
$page .= "You may also choose to just continue <a href=\"/\">exploring</a> and give up this item.";
|
||||
|
||||
display($page, "Item Drop");
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ function dead()
|
|||
<b>You have died.</b><br><br>
|
||||
As a consequence, you've lost half of your gold. However, you have been given back a portion of your hit points
|
||||
to continue your journey.<br><br>
|
||||
You may now continue back to <a href="index.php">town</a>, and we hope you fair better next time.
|
||||
You may now continue back to <a href="/">town</a>, and we hope you fair better next time.
|
||||
HTML;
|
||||
display($page, 'You Died');
|
||||
}
|
||||
|
|
|
@ -24,5 +24,5 @@ function healspells($id)
|
|||
|
||||
db()->query('UPDATE users SET currenthp=?, currentmp=? WHERE id=?;', [$newhp, $newmp, $userrow['id']]);
|
||||
|
||||
display("You have cast the ".$spellrow["name"]." spell, and gained ".$spellrow["attribute"]." Hit Points. You can now continue <a href=\"index.php\">exploring</a>.", "Healing Spell");
|
||||
display("You have cast the ".$spellrow["name"]." spell, and gained ".$spellrow["attribute"]." Hit Points. You can now continue <a href=\"/\">exploring</a>.", "Healing Spell");
|
||||
}
|
||||
|
|
213
src/lib.php
|
@ -2,8 +2,8 @@
|
|||
|
||||
require_once __DIR__ . '/database.php';
|
||||
|
||||
define('VERSION', '1.1.11');
|
||||
define('BUILD', '');
|
||||
define('VERSION', '1.2.3');
|
||||
define('BUILD', 'Reawaken');
|
||||
define('START', microtime(true));
|
||||
|
||||
/**
|
||||
|
@ -106,9 +106,9 @@ function display($content, $title, $topnav=true, $leftnav=true, $rightnav=true,
|
|||
if ($rightnav == true) { $rightnav = gettemplate("rightnav"); } else { $rightnav = ""; }
|
||||
if ($leftnav == true) { $leftnav = gettemplate("leftnav"); } else { $leftnav = ""; }
|
||||
if ($topnav == true) {
|
||||
$topnav = "<a href=\"login.php?do=logout\"><img src=\"images/button_logout.gif\" alt=\"Log Out\" title=\"Log Out\" border=\"0\" /></a> <a href=\"help.php\"><img src=\"images/button_help.gif\" alt=\"Help\" title=\"Help\" border=\"0\" /></a>";
|
||||
$topnav = "<a href=\"login.php?do=logout\"><img src=\"/img/button_logout.gif\" alt=\"Log Out\" title=\"Log Out\" border=\"0\" /></a> <a href=\"help.php\"><img src=\"/img/button_help.gif\" alt=\"Help\" title=\"Help\" border=\"0\" /></a>";
|
||||
} else {
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"images/button_login.gif\" alt=\"Log In\" title=\"Log In\" border=\"0\" /></a> <a href=\"users.php?do=register\"><img src=\"images/button_register.gif\" alt=\"Register\" title=\"Register\" border=\"0\" /></a> <a href=\"help.php\"><img src=\"images/button_help.gif\" alt=\"Help\" title=\"Help\" border=\"0\" /></a>";
|
||||
$topnav = "<a href=\"login.php?do=login\"><img src=\"/img/button_login.gif\" alt=\"Log In\" title=\"Log In\" border=\"0\" /></a> <a href=\"users.php?do=register\"><img src=\"/img/button_register.gif\" alt=\"Register\" title=\"Register\" border=\"0\" /></a> <a href=\"help.php\"><img src=\"/img/button_help.gif\" alt=\"Help\" title=\"Help\" border=\"0\" /></a>";
|
||||
}
|
||||
|
||||
if (isset($userrow)) {
|
||||
|
@ -142,19 +142,19 @@ function display($content, $title, $topnav=true, $leftnav=true, $rightnav=true,
|
|||
$stattp = ceil($userrow["currenttp"] / $userrow["maxtp"] * 100);
|
||||
$stattable = "<table width=\"100\"><tr><td width=\"33%\">\n";
|
||||
$stattable .= "<table cellspacing=\"0\" cellpadding=\"0\"><tr><td style=\"padding:0px; width:15px; height:100px; border:solid 1px black; vertical-align:bottom;\">\n";
|
||||
if ($stathp >= 66) { $stattable .= "<div style=\"padding:0px; height:".$stathp."px; border-top:solid 1px black; background-image:url(images/bars_green.gif);\"><img src=\"images/bars_green.gif\" alt=\"\" /></div>"; }
|
||||
if ($stathp < 66 && $stathp >= 33) { $stattable .= "<div style=\"padding:0px; height:".$stathp."px; border-top:solid 1px black; background-image:url(images/bars_yellow.gif);\"><img src=\"images/bars_yellow.gif\" alt=\"\" /></div>"; }
|
||||
if ($stathp < 33) { $stattable .= "<div style=\"padding:0px; height:".$stathp."px; border-top:solid 1px black; background-image:url(images/bars_red.gif);\"><img src=\"images/bars_red.gif\" alt=\"\" /></div>"; }
|
||||
if ($stathp >= 66) { $stattable .= "<div style=\"padding:0px; height:".$stathp."px; border-top:solid 1px black; background-image:url(/img/bars_green.gif);\"><img src=\"/img/bars_green.gif\" alt=\"\" /></div>"; }
|
||||
if ($stathp < 66 && $stathp >= 33) { $stattable .= "<div style=\"padding:0px; height:".$stathp."px; border-top:solid 1px black; background-image:url(/img/bars_yellow.gif);\"><img src=\"/img/bars_yellow.gif\" alt=\"\" /></div>"; }
|
||||
if ($stathp < 33) { $stattable .= "<div style=\"padding:0px; height:".$stathp."px; border-top:solid 1px black; background-image:url(/img/bars_red.gif);\"><img src=\"/img/bars_red.gif\" alt=\"\" /></div>"; }
|
||||
$stattable .= "</td></tr></table></td><td width=\"33%\">\n";
|
||||
$stattable .= "<table cellspacing=\"0\" cellpadding=\"0\"><tr><td style=\"padding:0px; width:15px; height:100px; border:solid 1px black; vertical-align:bottom;\">\n";
|
||||
if ($statmp >= 66) { $stattable .= "<div style=\"padding:0px; height:".$statmp."px; border-top:solid 1px black; background-image:url(images/bars_green.gif);\"><img src=\"images/bars_green.gif\" alt=\"\" /></div>"; }
|
||||
if ($statmp < 66 && $statmp >= 33) { $stattable .= "<div style=\"padding:0px; height:".$statmp."px; border-top:solid 1px black; background-image:url(images/bars_yellow.gif);\"><img src=\"images/bars_yellow.gif\" alt=\"\" /></div>"; }
|
||||
if ($statmp < 33) { $stattable .= "<div style=\"padding:0px; height:".$statmp."px; border-top:solid 1px black; background-image:url(images/bars_red.gif);\"><img src=\"images/bars_red.gif\" alt=\"\" /></div>"; }
|
||||
if ($statmp >= 66) { $stattable .= "<div style=\"padding:0px; height:".$statmp."px; border-top:solid 1px black; background-image:url(/img/bars_green.gif);\"><img src=\"/img/bars_green.gif\" alt=\"\" /></div>"; }
|
||||
if ($statmp < 66 && $statmp >= 33) { $stattable .= "<div style=\"padding:0px; height:".$statmp."px; border-top:solid 1px black; background-image:url(/img/bars_yellow.gif);\"><img src=\"/img/bars_yellow.gif\" alt=\"\" /></div>"; }
|
||||
if ($statmp < 33) { $stattable .= "<div style=\"padding:0px; height:".$statmp."px; border-top:solid 1px black; background-image:url(/img/bars_red.gif);\"><img src=\"/img/bars_red.gif\" alt=\"\" /></div>"; }
|
||||
$stattable .= "</td></tr></table></td><td width=\"33%\">\n";
|
||||
$stattable .= "<table cellspacing=\"0\" cellpadding=\"0\"><tr><td style=\"padding:0px; width:15px; height:100px; border:solid 1px black; vertical-align:bottom;\">\n";
|
||||
if ($stattp >= 66) { $stattable .= "<div style=\"padding:0px; height:".$stattp."px; border-top:solid 1px black; background-image:url(images/bars_green.gif);\"><img src=\"images/bars_green.gif\" alt=\"\" /></div>"; }
|
||||
if ($stattp < 66 && $stattp >= 33) { $stattable .= "<div style=\"padding:0px; height:".$stattp."px; border-top:solid 1px black; background-image:url(images/bars_yellow.gif);\"><img src=\"images/bars_yellow.gif\" alt=\"\" /></div>"; }
|
||||
if ($stattp < 33) { $stattable .= "<div style=\"padding:0px; height:".$stattp."px; border-top:solid 1px black; background-image:url(images/bars_red.gif);\"><img src=\"images/bars_red.gif\" alt=\"\" /></div>"; }
|
||||
if ($stattp >= 66) { $stattable .= "<div style=\"padding:0px; height:".$stattp."px; border-top:solid 1px black; background-image:url(/img/bars_green.gif);\"><img src=\"/img/bars_green.gif\" alt=\"\" /></div>"; }
|
||||
if ($stattp < 66 && $stattp >= 33) { $stattable .= "<div style=\"padding:0px; height:".$stattp."px; border-top:solid 1px black; background-image:url(/img/bars_yellow.gif);\"><img src=\"/img/bars_yellow.gif\" alt=\"\" /></div>"; }
|
||||
if ($stattp < 33) { $stattable .= "<div style=\"padding:0px; height:".$stattp."px; border-top:solid 1px black; background-image:url(/img/bars_red.gif);\"><img src=\"/img/bars_red.gif\" alt=\"\" /></div>"; }
|
||||
$stattable .= "</td></tr></table></td>\n";
|
||||
$stattable .= "</tr><tr><td>HP</td><td>MP</td><td>TP</td></tr></table>\n";
|
||||
$userrow["statbars"] = $stattable;
|
||||
|
@ -172,7 +172,7 @@ function display($content, $title, $topnav=true, $leftnav=true, $rightnav=true,
|
|||
if ($b == $spellrow["id"] && $spellrow["type"] == 1) { $spell = true; }
|
||||
}
|
||||
if ($spell == true) {
|
||||
$userrow["magiclist"] .= "<a href=\"index.php?do=spell:".$spellrow["id"]."\">".$spellrow["name"]."</a><br>";
|
||||
$userrow["magiclist"] .= "<a href=\"/spell/{$spellrow["id"]}\">".$spellrow["name"]."</a><br>";
|
||||
}
|
||||
}
|
||||
if ($userrow["magiclist"] == "") { $userrow["magiclist"] = "None"; }
|
||||
|
@ -187,7 +187,7 @@ function display($content, $title, $topnav=true, $leftnav=true, $rightnav=true,
|
|||
if ($b == $townrow2["id"]) { $town = true; }
|
||||
}
|
||||
if ($town == true) {
|
||||
$userrow["townslist"] .= "<a href=\"index.php?do=gotown:".$townrow2["id"]."\">".$townrow2["name"]."</a><br>\n";
|
||||
$userrow["townslist"] .= "<a href=\"/gotown/{$townrow2["id"]}\">".$townrow2["name"]."</a><br>\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -343,3 +343,186 @@ function token($length = 32): string
|
|||
{
|
||||
return bin2hex(random_bytes($length));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate any given array of data against rules. Returns [valid, data, error]. Data contains the trimmed
|
||||
* values from the input array. Note: all fields with rules are assumed to be required, unless the optional
|
||||
* rule is used.
|
||||
*
|
||||
* Example: ['required', 'no-trim', 'length:5-20', 'alphanum-spaces']
|
||||
*/
|
||||
function validate(array $input_data, array $rules): array
|
||||
{
|
||||
$data = [];
|
||||
$errors = [];
|
||||
|
||||
foreach ($rules as $field => $field_rules) {
|
||||
$value = $input_data[$field] ?? null;
|
||||
$field_name = ucfirst(str_replace('_', ' ', $field));
|
||||
$is_required = true;
|
||||
$default_value = null;
|
||||
|
||||
if (in_array('optional', $field_rules)) {
|
||||
$is_required = false;
|
||||
}
|
||||
|
||||
foreach ($field_rules as $rule) {
|
||||
if (strpos($rule, 'default:') === 0) {
|
||||
$default_value = substr($rule, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (($value === null || $value === '') && $default_value !== null) {
|
||||
$value = $default_value;
|
||||
}
|
||||
|
||||
if (($value === null || $value === '') && !$is_required) continue;
|
||||
|
||||
if ($is_required && ($value === null || $value === '')) {
|
||||
$errors[$field][] = "{$field_name} is required.";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!in_array('no-trim', $field_rules)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
|
||||
$data[$field] = $value;
|
||||
|
||||
foreach ($field_rules as $rule) {
|
||||
// Parse rule and arguments
|
||||
if (strpos($rule, ':') !== false) {
|
||||
list($rule_name, $rule_args) = explode(':', $rule, 2);
|
||||
} else {
|
||||
$rule_name = $rule;
|
||||
$rule_args = null;
|
||||
}
|
||||
|
||||
if ($rule_name === 'optional') continue;
|
||||
|
||||
switch ($rule_name) {
|
||||
case 'bool':
|
||||
if (!isset($input_data[$field]) || empty($value)) {
|
||||
$value = false;
|
||||
} else {
|
||||
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||
|
||||
if ($value === null) {
|
||||
$errors[$field][] = "{$field_name} must be a valid boolean value.";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'length':
|
||||
list($min, $max) = explode('-', $rule_args);
|
||||
$len = strlen((string)$value);
|
||||
if ($len < $min || $len > $max) {
|
||||
$errors[$field][] = "{$field_name} must be between {$min} and {$max} characters.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'alphanum':
|
||||
if (!preg_match('/^[a-zA-Z0-9]+$/', $value)) {
|
||||
$errors[$field][] = "{$field_name} must contain only letters and numbers.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'alpha':
|
||||
if (!preg_match('/^[a-zA-Z]+$/', $value)) {
|
||||
$errors[$field][] = "{$field_name} must contain only letters and numbers.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'alphanum-spaces':
|
||||
if (!preg_match('/^[a-zA-Z0-9\s_]+$/', $value)) {
|
||||
$errors[$field][] = "{$field_name} must contain only letters, numbers, spaces, and underscores.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'alpha-spaces':
|
||||
if (!preg_match('/^[a-zA-Z\s_]+$/', $value)) {
|
||||
$errors[$field][] = "{$field_name} must contain only letters, numbers, spaces, and underscores.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'email':
|
||||
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
||||
$errors[$field][] = "{$field_name} must be a valid email address.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'int':
|
||||
if (!filter_var($value, FILTER_VALIDATE_INT)) {
|
||||
$errors[$field][] = "{$field_name} must be an integer.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'min':
|
||||
if ($value < $rule_args) {
|
||||
$errors[$field][] = "{$field_name} must be at least {$rule_args}.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'max':
|
||||
if ($value > $rule_args) {
|
||||
$errors[$field][] = "{$field_name} must be no more than {$rule_args}.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'regex':
|
||||
if (!preg_match($rule_args, $value)) {
|
||||
$errors[$field][] = "{$field_name} does not match the required pattern.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'in':
|
||||
$options = explode(',', $rule_args);
|
||||
if (!in_array($value, $options)) {
|
||||
$errors[$field][] = "{$field_name} must be one of: " . implode(', ', $options);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'confirm':
|
||||
$field_to_confirm = substr($field, 8);
|
||||
$confirm_value = $data[$field_to_confirm] ?? '';
|
||||
$confirm_field_name = ucfirst(str_replace('_', ' ', $field_to_confirm));
|
||||
if ($value !== $confirm_value) {
|
||||
$errors[$field][] = "{$field_name} must match {$confirm_field_name}.";
|
||||
}
|
||||
break;
|
||||
|
||||
case 'unique':
|
||||
list($table, $column) = explode(',', $rule_args, 2);
|
||||
if (db()->exists($table, $column, $value)) {
|
||||
$errors[$field][] = "{$field_name} must be unique.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($input_data as $field => $value) {
|
||||
if (!isset($data[$field])) $data[$field] = trim($value);
|
||||
}
|
||||
|
||||
return [
|
||||
'valid' => empty($errors),
|
||||
'data' => $data,
|
||||
'errors' => $errors
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a ul list from `validate()`'s errors.
|
||||
*/
|
||||
function ul_from_validate_errors(array $errors): string
|
||||
{
|
||||
$string = '<ul>';
|
||||
foreach ($errors as $field => $errors) {
|
||||
$string .= '<li>';
|
||||
foreach ($errors as $error) $string .= $error;
|
||||
$string .= '</li>';
|
||||
}
|
||||
return $string . '</ul>';
|
||||
}
|
||||
|
|
183
src/router.php
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* A radix-trie based URI router. Seperates URIs into chunks, then turns those chunks into an efficiently parsed
|
||||
* trie. Supports URI variables!
|
||||
*/
|
||||
class Router
|
||||
{
|
||||
/**
|
||||
* List of valid HTTP verbs.
|
||||
*/
|
||||
private const VALID_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
|
||||
|
||||
/**
|
||||
* The tree of currently registered routes.
|
||||
*/
|
||||
private array $routes = [];
|
||||
|
||||
/**
|
||||
* Store the last inserted node so we can register middleware and attributes to it.
|
||||
*/
|
||||
private array $last_inserted_node;
|
||||
|
||||
/**
|
||||
* Add a route to the route tree. The route must be a URI path, and contain dynamic segments
|
||||
* using a colon prefix. (:id, :slug, etc)
|
||||
*
|
||||
* Example:
|
||||
* `$r->add($routes, 'GET', '/posts/:id', function($id) { echo "Viewing post $id"; });`
|
||||
*/
|
||||
public function add(string $method, string $route, callable $handler): Router
|
||||
{
|
||||
$this->validateMethod($method);
|
||||
$this->validateRoute($route);
|
||||
|
||||
// Expand the route into segments and make dynamic segments into a common placeholder
|
||||
$segments = array_map(function($segment) {
|
||||
return str_starts_with($segment, ':') ? ':x' : $segment;
|
||||
}, explode('/', trim($route, '/')));
|
||||
|
||||
// Push each segment into the routes array as a node, except if this is the root node
|
||||
$node = &$this->routes;
|
||||
foreach ($segments as $segment) {
|
||||
// skip an empty segment, which allows us to register handlers for the root node
|
||||
if ($segment === '') continue;
|
||||
$node = &$node[$segment]; // build the node tree as we go
|
||||
}
|
||||
|
||||
// Add the handler to the last node
|
||||
$node[$method] = ['handler' => $handler, 'middleware' => []];
|
||||
|
||||
// Store a reference to the node so we can add middleware to it.
|
||||
$this->last_inserted_node = &$node[$method];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a lookup in the route tree for a given method and URI. Returns an array with a result code,
|
||||
* a handler if found, and any dynamic parameters. Codes are 200 for success, 404 for not found, and
|
||||
* 405 for method not allowed.
|
||||
*
|
||||
* @return array ['code', 'handler', 'params']
|
||||
*/
|
||||
public function lookup(string $method, string $uri): array
|
||||
{
|
||||
// node is a reference to our current location in the node tree
|
||||
$node = $this->routes;
|
||||
|
||||
// params will hold any dynamic segments we find
|
||||
$params = [];
|
||||
|
||||
// if the URI is just a slash, we can return the handler for the root node
|
||||
if ($uri === '/') {
|
||||
return isset($node[$method])
|
||||
? ['code' => 200, 'handler' => $node[$method]['handler']]
|
||||
: ['code' => 405];
|
||||
}
|
||||
|
||||
// We'll split up the URI into segments and traverse the node tree
|
||||
foreach (explode('/', trim($uri, '/')) as $segment) {
|
||||
// if there is a node for this segment, move to it
|
||||
if (isset($node[$segment])) {
|
||||
$node = $node[$segment];
|
||||
continue;
|
||||
}
|
||||
|
||||
// if there is a dynamic segment, move to it and store the value
|
||||
if (isset($node[':x'])) {
|
||||
$params[] = $segment;
|
||||
$node = $node[':x'];
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we can't find a node for this segment, return 404
|
||||
return ['code' => 404];
|
||||
}
|
||||
|
||||
// if we found a handler for the method, return it and any params. if not, return a 405
|
||||
return isset($node[$method])
|
||||
? ['code' => 200, 'handler' => $node[$method]['handler'], 'params' => $params ?? [], 'middleware' => $node[$method]['middleware']]
|
||||
: ['code' => 405];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a middleware function to the last inserted node's stack.
|
||||
*/
|
||||
public function middleware(callable $middleware): Router
|
||||
{
|
||||
$this->last_inserted_node['middleware'][] = $middleware;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand to register a GET route.
|
||||
*/
|
||||
public function get(string $route, callable $handler): Router
|
||||
{
|
||||
return $this->add('GET', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand to register a POST route.
|
||||
*/
|
||||
public function post(string $route, callable $handler): Router
|
||||
{
|
||||
return $this->add('POST', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand to register a PUT route.
|
||||
*/
|
||||
public function put(string $route, callable $handler): Router
|
||||
{
|
||||
return $this->add('PUT', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand to register a DELETE route.
|
||||
*/
|
||||
public function delete(string $route, callable $handler): Router
|
||||
{
|
||||
return $this->add('DELETE', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand to register a PATCH route.
|
||||
*/
|
||||
public function patch(string $route, callable $handler): Router
|
||||
{
|
||||
return $this->add('PATCH', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given method against valid HTTP verbs.
|
||||
*/
|
||||
private function validateMethod(string $method): void
|
||||
{
|
||||
if (!in_array($method, self::VALID_METHODS)) {
|
||||
throw new InvalidArgumentException("Invalid HTTP method: $method");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a new route follows expected formatting.
|
||||
*/
|
||||
private function validateRoute(string $route): void
|
||||
{
|
||||
if ($route === '') {
|
||||
throw new InvalidArgumentException("Route cannot be empty");
|
||||
}
|
||||
|
||||
// Ensure route starts with a slash
|
||||
if (!str_starts_with($route, '/')) {
|
||||
throw new InvalidArgumentException("Route must start with a '/'");
|
||||
}
|
||||
|
||||
// Optional: Check for consecutive dynamic segments or invalid characters
|
||||
if (preg_match('/(:x.*){2,}/', $route)) {
|
||||
throw new InvalidArgumentException("Invalid route pattern: consecutive dynamic segments");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@ function inn()
|
|||
if ($townrow === false) { display("Cheat attempt detected.<br><br>Get a life, loser.", "Error"); }
|
||||
|
||||
if ($userrow["gold"] < $townrow["innprice"]) {
|
||||
display("You do not have enough gold to stay at this Inn tonight.<br><br>You may return to <a href=\"index.php\">town</a>, or use the direction buttons on the left to start exploring.", "Inn");
|
||||
display("You do not have enough gold to stay at this Inn tonight.<br><br>You may return to <a href=\"/\">town</a>, or use the direction buttons on the left to start exploring.", "Inn");
|
||||
}
|
||||
|
||||
if (isset($_POST["submit"])) {
|
||||
|
@ -23,16 +23,16 @@ function inn()
|
|||
[$newgold, $userrow['maxhp'], $userrow['maxmp'], $userrow['maxtp'], $userrow['id']
|
||||
]);
|
||||
$title = "Inn";
|
||||
$page = "You wake up feeling refreshed and ready for action.<br><br>You may return to <a href=\"index.php\">town</a>, or use the direction buttons on the left to start exploring.";
|
||||
$page = "You wake up feeling refreshed and ready for action.<br><br>You may return to <a href=\"/\">town</a>, or use the direction buttons on the left to start exploring.";
|
||||
} elseif (isset($_POST["cancel"])) {
|
||||
redirect('index.php');
|
||||
redirect('/');
|
||||
} else {
|
||||
$title = "Inn";
|
||||
$page = <<<HTML
|
||||
Resting at the inn will refill your current HP, MP, and TP to their maximum levels.<br><br>
|
||||
A night's sleep at this Inn will cost you <b>{$townrow["innprice"]} gold</b>. Is that ok?<br><br>
|
||||
<form action="index.php?do=inn" method="post">
|
||||
<input type="submit" name="submit" value="Yes" /> <input type="submit" name="cancel" value="No" />
|
||||
<form action="/inn" method="post">
|
||||
<input type="submit" name="submit" value="Yes"> <input type="submit" name="cancel" value="No">
|
||||
</form>
|
||||
HTML;
|
||||
}
|
||||
|
@ -57,19 +57,19 @@ function buy()
|
|||
$attrib = ($itemsrow["type"] == 1) ? "Attack Power:" : "Defense Power:";
|
||||
$page .= "<tr><td width=\"4%\">";
|
||||
$page .= match ($itemsrow["type"]) {
|
||||
1 => '<img src="images/icon_weapon.gif" alt="weapon" /></td>',
|
||||
2 => '<img src="images/icon_armor.gif" alt="armor" /></td>',
|
||||
3 => '<img src="images/icon_shield.gif" alt="shield" /></td>'
|
||||
1 => '<img src="/img/icon_weapon.gif" alt="weapon" /></td>',
|
||||
2 => '<img src="/img/icon_armor.gif" alt="armor" /></td>',
|
||||
3 => '<img src="/img/icon_shield.gif" alt="shield" /></td>'
|
||||
};
|
||||
if ($userrow["weaponid"] == $itemsrow["id"] || $userrow["armorid"] == $itemsrow["id"] || $userrow["shieldid"] == $itemsrow["id"]) {
|
||||
$page .= "<td width=\"32%\"><span class=\"light\">".$itemsrow["name"]."</span></td><td width=\"32%\"><span class=\"light\">$attrib ".$itemsrow["attribute"]."</span></td><td width=\"32%\"><span class=\"light\">Already purchased</span></td></tr>\n";
|
||||
} else {
|
||||
if ($itemsrow["special"] != "X") { $specialdot = "<span class=\"highlight\">*</span>"; } else { $specialdot = ""; }
|
||||
$page .= "<td width=\"32%\"><b><a href=\"index.php?do=buy2:".$itemsrow["id"]."\">".$itemsrow["name"]."</a>$specialdot</b></td><td width=\"32%\">$attrib <b>".$itemsrow["attribute"]."</b></td><td width=\"32%\">Price: <b>".$itemsrow["buycost"]." gold</b></td></tr>\n";
|
||||
$page .= "<td width=\"32%\"><b><a href=\"/buy2/{$itemsrow["id"]}\">".$itemsrow["name"]."</a>$specialdot</b></td><td width=\"32%\">$attrib <b>".$itemsrow["attribute"]."</b></td><td width=\"32%\">Price: <b>".$itemsrow["buycost"]." gold</b></td></tr>\n";
|
||||
}
|
||||
}
|
||||
$page .= "</table><br>\n";
|
||||
$page .= "If you've changed your mind, you may also return back to <a href=\"index.php\">town</a>.\n";
|
||||
$page .= "If you've changed your mind, you may also return back to <a href=\"/\">town</a>.\n";
|
||||
$title = "Buy Items";
|
||||
|
||||
display($page, $title);
|
||||
|
@ -90,7 +90,7 @@ function buy2($id)
|
|||
$item = get_item($id);
|
||||
|
||||
if ($userrow["gold"] < $item["buycost"]) {
|
||||
display("You do not have enough gold to buy this item.<br><br>You may return to <a href=\"index.php\">town</a>, <a href=\"index.php?do=buy\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Items");
|
||||
display("You do not have enough gold to buy this item.<br><br>You may return to <a href=\"/\">town</a>, <a href=\"/buy\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Items");
|
||||
}
|
||||
|
||||
$type_to_row_mapping = [1 => 'weaponid', 2 => 'armorid', 3 => 'shieldid'];
|
||||
|
@ -98,9 +98,9 @@ function buy2($id)
|
|||
|
||||
if ($current_equipped_id != 0) {
|
||||
$item2 = get_item($current_equipped_id);
|
||||
$page = "If you are buying the ".$item["name"].", then I will buy your ".$item2["name"]." for ".ceil($item2["buycost"] / 2)." gold. Is that ok?<br><br><form action=\"index.php?do=buy3:$id\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Yes\" /> <input type=\"submit\" name=\"cancel\" value=\"No\" /></form>";
|
||||
$page = "If you are buying the ".$item["name"].", then I will buy your ".$item2["name"]." for ".ceil($item2["buycost"] / 2)." gold. Is that ok?<br><br><form action=\"/buy3/$id\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Yes\" /> <input type=\"submit\" name=\"cancel\" value=\"No\" /></form>";
|
||||
} else {
|
||||
$page = "You are buying the ".$item["name"].", is that ok?<br><br><form action=\"index.php?do=buy3:$id\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Yes\" /> <input type=\"submit\" name=\"cancel\" value=\"No\" /></form>";
|
||||
$page = "You are buying the ".$item["name"].", is that ok?<br><br><form action=\"/buy3/$id\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Yes\" /> <input type=\"submit\" name=\"cancel\" value=\"No\" /></form>";
|
||||
}
|
||||
|
||||
display($page, "Buy Items");
|
||||
|
@ -112,7 +112,7 @@ function buy2($id)
|
|||
function buy3($id)
|
||||
{
|
||||
|
||||
if (isset($_POST["cancel"])) redirect('index.php');
|
||||
if (isset($_POST["cancel"])) redirect('/');
|
||||
|
||||
global $userrow;
|
||||
|
||||
|
@ -124,7 +124,7 @@ function buy3($id)
|
|||
$item = get_item($id);
|
||||
|
||||
if ($userrow["gold"] < $item["buycost"]) {
|
||||
display("You do not have enough gold to buy this item.<br><br>You may return to <a href=\"index.php\">town</a>, <a href=\"index.php?do=buy\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Items");
|
||||
display("You do not have enough gold to buy this item.<br><br>You may return to <a href=\"/\">town</a>, <a href=\"/buy\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Items");
|
||||
}
|
||||
|
||||
$type_mapping = [
|
||||
|
@ -212,7 +212,7 @@ function buy3($id)
|
|||
$stmt = db()->query("UPDATE users SET " . implode(", ", $updateFields) . " WHERE id = ?;", $updateValues);
|
||||
if ($stmt === false) exit("Failed to purchase and equip $id. Go back and try again.");
|
||||
|
||||
display("Thank you for purchasing this item.<br><br>You may return to <a href=\"index.php\">town</a>, <a href=\"index.php?do=buy\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Items");
|
||||
display("Thank you for purchasing this item.<br><br>You may return to <a href=\"/\">town</a>, <a href=\"/buy\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Items");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -237,14 +237,14 @@ function maps()
|
|||
foreach($mappedtowns as $b) if ($b == $townrow["id"]) $mapped = true;
|
||||
|
||||
if ($mapped == false) {
|
||||
$page .= "<tr><td width=\"25%\"><a href=\"index.php?do=maps2:".$townrow["id"]."\">".$townrow["name"]."</a></td><td width=\"25%\">Price: ".$townrow["mapprice"]." gold</td><td width=\"50%\" colspan=\"2\">Buy map to reveal details.</td></tr>\n";
|
||||
$page .= "<tr><td width=\"25%\"><a href=\"/maps2/{$townrow["id"]}\">".$townrow["name"]."</a></td><td width=\"25%\">Price: ".$townrow["mapprice"]." gold</td><td width=\"50%\" colspan=\"2\">Buy map to reveal details.</td></tr>\n";
|
||||
} else {
|
||||
$page .= "<tr><td width=\"25%\"><span class=\"light\">".$townrow["name"]."</span></td><td width=\"25%\"><span class=\"light\">Already mapped.</span></td><td width=\"35%\"><span class=\"light\">Location: $latitude $longitude</span></td><td width=\"15%\"><span class=\"light\">TP: ".$townrow["travelpoints"]."</span></td></tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$page .= "</table><br>\n";
|
||||
$page .= "If you've changed your mind, you may also return back to <a href=\"index.php\">town</a>.\n";
|
||||
$page .= "If you've changed your mind, you may also return back to <a href=\"/\">town</a>.\n";
|
||||
|
||||
display($page, "Buy Maps");
|
||||
}
|
||||
|
@ -259,10 +259,10 @@ function maps2($id)
|
|||
$townrow = get_town_by_id($id);
|
||||
|
||||
if ($userrow["gold"] < $townrow["mapprice"]) {
|
||||
display("You do not have enough gold to buy this map.<br><br>You may return to <a href=\"index.php\">town</a>, <a href=\"index.php?do=maps\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Maps");
|
||||
display("You do not have enough gold to buy this map.<br><br>You may return to <a href=\"/\">town</a>, <a href=\"/maps\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Maps");
|
||||
}
|
||||
|
||||
$page = "You are buying the ".$townrow["name"]." map. Is that ok?<br><br><form action=\"index.php?do=maps3:$id\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Yes\" /> <input type=\"submit\" name=\"cancel\" value=\"No\" /></form>";
|
||||
$page = "You are buying the ".$townrow["name"]." map. Is that ok?<br><br><form action=\"/maps3/$id\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Yes\" /> <input type=\"submit\" name=\"cancel\" value=\"No\" /></form>";
|
||||
|
||||
display($page, "Buy Maps");
|
||||
}
|
||||
|
@ -272,14 +272,14 @@ function maps2($id)
|
|||
*/
|
||||
function maps3($id)
|
||||
{
|
||||
if (isset($_POST["cancel"])) redirect('index.php');
|
||||
if (isset($_POST["cancel"])) redirect('/');
|
||||
|
||||
global $userrow;
|
||||
|
||||
$townrow = get_town_by_id($id);
|
||||
|
||||
if ($userrow["gold"] < $townrow["mapprice"]) {
|
||||
display("You do not have enough gold to buy this map.<br><br>You may return to <a href=\"index.php\">town</a>, <a href=\"index.php?do=maps\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Maps");
|
||||
display("You do not have enough gold to buy this map.<br><br>You may return to <a href=\"/\">town</a>, <a href=\"/maps\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Maps");
|
||||
}
|
||||
|
||||
$mappedtowns = $userrow["towns"].",$id";
|
||||
|
@ -287,7 +287,7 @@ function maps3($id)
|
|||
|
||||
db()->query('UPDATE users SET towns=?, gold=? WHERE id=?;', [$mappedtowns, $newgold, $userrow['id']]);
|
||||
|
||||
display("Thank you for purchasing this map.<br><br>You may return to <a href=\"index.php\">town</a>, <a href=\"index.php?do=maps\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Maps");
|
||||
display("Thank you for purchasing this map.<br><br>You may return to <a href=\"/\">town</a>, <a href=\"/maps\">store</a>, or use the direction buttons on the left to start exploring.", "Buy Maps");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,7 +297,7 @@ function travelto($id, bool $usepoints = true)
|
|||
{
|
||||
global $userrow;
|
||||
|
||||
if ($userrow["currentaction"] == "Fighting") redirect('index.php?do=fight');
|
||||
if ($userrow["currentaction"] == "Fighting") redirect('/fight');
|
||||
|
||||
$townrow = get_town_by_id($id);
|
||||
|
||||
|
@ -310,7 +310,7 @@ function travelto($id, bool $usepoints = true)
|
|||
}
|
||||
|
||||
if (($userrow["latitude"] == $townrow["latitude"]) && ($userrow["longitude"] == $townrow["longitude"])) {
|
||||
display("You are already in this town. <a href=\"index.php\">Click here</a> to return to the main town screen.", "Travel To");
|
||||
display("You are already in this town. <a href=\"/\">Click here</a> to return to the main town screen.", "Travel To");
|
||||
}
|
||||
|
||||
$newtp = ($usepoints) ? $userrow["currenttp"] - $townrow["travelpoints"] : $userrow["currenttp"];
|
||||
|
@ -332,6 +332,6 @@ function travelto($id, bool $usepoints = true)
|
|||
$newtp, $newlat, $newlon, $newid
|
||||
]);
|
||||
|
||||
$page = "You have travelled to ".$townrow["name"].". You may now <a href=\"index.php\">enter this town</a>.";
|
||||
$page = "You have travelled to ".$townrow["name"].". You may now <a href=\"/\">enter this town</a>.";
|
||||
display($page, "Travel To");
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ a:hover {
|
|||
<b><u>DK Administration</u></b><br><br>
|
||||
<b>Links:</b><br>
|
||||
<a href="admin.php">Admin Home</a><br>
|
||||
<a href="index.php">Game Home</a><br><br>
|
||||
<a href="/">Game Home</a><br><br>
|
||||
<b>Primary Data:</b><br>
|
||||
<a href="admin.php?do=main">Main Settings</a><br>
|
||||
<a href="admin.php?do=news">Add News Post</a><br>
|
||||
|
|
|
@ -1,34 +1,44 @@
|
|||
<?php
|
||||
$template = <<<THEVERYENDOFYOU
|
||||
$template = <<<HTML
|
||||
<head>
|
||||
<title>shoutbox</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url(images/background.jpg);
|
||||
color: black;
|
||||
font: 11px verdana;
|
||||
margins: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
div {
|
||||
padding: 2px;
|
||||
border: solid 1px black;
|
||||
margin: 2px;
|
||||
text-align: left;
|
||||
}
|
||||
a {
|
||||
color: #663300;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
a:hover {
|
||||
color: #330000;
|
||||
}
|
||||
</style>
|
||||
<title>Babblebox</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url(/img/background.jpg);
|
||||
color: black;
|
||||
font: 11px verdana;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 2px;
|
||||
border: solid 1px black;
|
||||
margin: 2px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #663300;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #330000;
|
||||
}
|
||||
|
||||
div.message {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
div.message:nth-child(even) {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="window.scrollTo(0,99999)">
|
||||
{{content}}
|
||||
{{content}}
|
||||
</body>
|
||||
</html>
|
||||
THEVERYENDOFYOU;
|
||||
?>
|
||||
HTML;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
$template = <<<THEVERYENDOFYOU
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/title_fighting.gif" alt="Fighting" /></td></tr>
|
||||
<tr><td class="title"><img src="/img/title_fighting.gif" alt="Fighting" /></td></tr>
|
||||
<tr><td>
|
||||
You are fighting a <b>{{monstername}}</b><br><br>
|
||||
{{monsterhp}}
|
||||
|
|
|
@ -1,44 +1,35 @@
|
|||
<?php
|
||||
$template = <<<HTML
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_location.gif" alt="Location" title="Location" /></td></tr>
|
||||
<tr><td>
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_location.gif" alt="Location" title="Location"></div>
|
||||
Currently: {{currentaction}}<br>
|
||||
Latitude: {{latitude}}<br>
|
||||
Longitude: {{longitude}}<br>
|
||||
<a href="javascript:openmappopup()">View Map</a><br><br>
|
||||
<form action="index.php?do=move" method="post">
|
||||
<center>
|
||||
<input name="north" type="submit" value="North" /><br>
|
||||
<input name="west" type="submit" value="West" /><input name="east" type="submit" value="East" /><br>
|
||||
<input name="south" type="submit" value="South" />
|
||||
</center>
|
||||
<a href="javascript:openmappopup()">View Map</a><br>
|
||||
<form action="/move" method="post" class="move-compass">
|
||||
<button type="submit" name="direction" value="north" class="north">North</button>
|
||||
<div class="mid">
|
||||
<button type="submit" name="direction" value="west" class="west">West</button>
|
||||
<button type="submit" name="direction" value="east" class="east">East</button>
|
||||
</div>
|
||||
<button type="submit" name="direction" value="south" class="south">South</button>
|
||||
</form>
|
||||
</td></tr>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<br>
|
||||
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_towns.gif" alt="Towns" title="Towns" /></td></tr>
|
||||
<tr><td>
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_towns.gif" alt="Towns" title="Towns"></div>
|
||||
{{currenttown}}
|
||||
Travel To:<br>
|
||||
{{townslist}}
|
||||
</td></tr>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<br>
|
||||
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_functions.gif" alt="Functions" title="Functions" /></td></tr>
|
||||
<tr><td>
|
||||
<a href="/index.php">Home</a><br>
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_functions.gif" alt="Functions" title="Functions"></div>
|
||||
<a href="/">Home</a><br>
|
||||
{{forumslink}}
|
||||
{{adminlink}}
|
||||
<a href="users.php?do=changepassword">Change Password</a><br>
|
||||
<a href="login.php?do=logout">Log Out</a><br>
|
||||
<a href="help.php">Help</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
</section>
|
||||
HTML;
|
||||
|
|
|
@ -1,13 +1,35 @@
|
|||
<?php
|
||||
$template = <<<THEVERYENDOFYOU
|
||||
<form action="login.php?do=login" method="post">
|
||||
<table width="75%">
|
||||
<tr><td width="30%">Username:</td><td><input type="text" size="30" name="username" /></td></tr>
|
||||
<tr><td>Password:</td><td><input type="password" size="30" name="password" /></td></tr>
|
||||
<tr><td>Remember me?</td><td><input type="checkbox" name="rememberme" value="yes" /> Yes</td></tr>
|
||||
<tr><td colspan="2"><input type="submit" name="submit" value="Log In" /></td></tr>
|
||||
<tr><td colspan="2">Checking the "Remember Me" option will store your login information in a cookie so you don't have to enter it next time you get online.<br><br>Want to play? You gotta <a href="users.php?do=register">register your own character.</a><br><br>You may also <a href="users.php?do=changepassword">change your password</a>, or <a href="users.php?do=lostpassword">request a new one</a> if you've lost yours.</td></tr>
|
||||
</table>
|
||||
</form>
|
||||
THEVERYENDOFYOU;
|
||||
?>
|
||||
|
||||
$template = <<<HTML
|
||||
<form action="login.php?do=login" method="post">
|
||||
<table width="75%">
|
||||
<tr>
|
||||
<td width="30%">Username:</td>
|
||||
<td><input type="text" name="username"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Password:</td>
|
||||
<td><input type="password" name="password"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Remember me?</td>
|
||||
<td>
|
||||
<input type="hidden" name="remember" value="0">
|
||||
<input type="checkbox" name="remember" value="1">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><input type="submit" name="submit" value="Log In"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
Checking the "Remember Me" option will store your login information in a cookie so you don't have
|
||||
to enter it next time you get online.<br><br>Want to play? You gotta
|
||||
<a href="users.php?do=register">register your own character.</a><br><br>You may also
|
||||
<a href="users.php?do=changepassword">change your password</a>, or
|
||||
<a href="users.php?do=lostpassword">request a new one</a> if you've lost yours.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
HTML;
|
||||
|
|
|
@ -4,7 +4,7 @@ $template = <<<THEVERYENDOFYOU
|
|||
<title>{{title}}</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url(images/background.jpg);
|
||||
background-image: url(/img/background.jpg);
|
||||
color: black;
|
||||
font: 11px verdana;
|
||||
}
|
||||
|
@ -65,4 +65,4 @@ a:hover {
|
|||
</center></body>
|
||||
</html>
|
||||
THEVERYENDOFYOU;
|
||||
?>
|
||||
?>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
$template = <<<HTML
|
||||
Here is the character profile for <b>{{username}}</b>.<br><br>
|
||||
When you're finished, you may <a href="index.php">return to town</a>.<br><br>
|
||||
When you're finished, you may <a href="/">return to town</a>.<br><br>
|
||||
<table width="200">
|
||||
<tr><td class="title"><img src="images/button_character.gif" alt="Character" title="Character" /></td></tr>
|
||||
<tr><td class="title"><img src="/img/button_character.gif" alt="Character" title="Character" /></td></tr>
|
||||
<tr><td>
|
||||
<b>{{username}}</b><br><br>
|
||||
|
||||
|
@ -24,12 +24,12 @@ $template = <<<HTML
|
|||
</table><br>
|
||||
|
||||
<table width="200">
|
||||
<tr><td class="title"><img src="images/button_inventory.gif" alt="Inventory" title="Inventory" /></td></tr>
|
||||
<tr><td class="title"><img src="/img/button_inventory.gif" alt="Inventory" title="Inventory" /></td></tr>
|
||||
<tr><td>
|
||||
<table width="100%">
|
||||
<tr><td><img src="images/icon_weapon.gif" alt="Weapon" title="Weapon" /></td><td width="100%">Weapon: {{weaponname}}</td></tr>
|
||||
<tr><td><img src="images/icon_armor.gif" alt="Armor" title="Armor" /></td><td width="100%">Armor: {{armorname}}</td></tr>
|
||||
<tr><td><img src="images/icon_shield.gif" alt="Shield" title="Shield" /></td><td width="100%">Shield: {{shieldname}}</td></tr>
|
||||
<tr><td><img src="/img/icon_weapon.gif" alt="Weapon" title="Weapon" /></td><td width="100%">Weapon: {{weaponname}}</td></tr>
|
||||
<tr><td><img src="/img/icon_armor.gif" alt="Armor" title="Armor" /></td><td width="100%">Armor: {{armorname}}</td></tr>
|
||||
<tr><td><img src="/img/icon_shield.gif" alt="Shield" title="Shield" /></td><td width="100%">Shield: {{shieldname}}</td></tr>
|
||||
</table>
|
||||
Slot 1: {{slot1name}}<br>
|
||||
Slot 2: {{slot2name}}<br>
|
||||
|
|
|
@ -1,90 +1,44 @@
|
|||
<?php
|
||||
$template = <<<THEVERYENDOFYOU
|
||||
$template = <<<HTML
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{title}}</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url(images/background.jpg);
|
||||
color: black;
|
||||
font: 11px verdana;
|
||||
}
|
||||
table {
|
||||
border-style: none;
|
||||
padding: 0px;
|
||||
font: 11px verdana;
|
||||
}
|
||||
td {
|
||||
border-style: none;
|
||||
padding: 3px;
|
||||
vertical-align: top;
|
||||
}
|
||||
td.top {
|
||||
border-bottom: solid 2px black;
|
||||
}
|
||||
td.left {
|
||||
width: 180px;
|
||||
border-right: solid 2px black;
|
||||
}
|
||||
td.right {
|
||||
width: 180px;
|
||||
border-left: solid 2px black;
|
||||
}
|
||||
a {
|
||||
color: #663300;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
a:hover {
|
||||
color: #330000;
|
||||
}
|
||||
.small {
|
||||
font: 10px verdana;
|
||||
}
|
||||
.highlight {
|
||||
color: red;
|
||||
}
|
||||
.light {
|
||||
color: #999999;
|
||||
}
|
||||
.title {
|
||||
border: solid 1px black;
|
||||
background-color: #eeeeee;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
margin: 3px;
|
||||
}
|
||||
.copyright {
|
||||
border: solid 1px black;
|
||||
background-color: #eeeeee;
|
||||
font: 10px verdana;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function opencharpopup(){
|
||||
var popurl="index.php?do=showchar"
|
||||
winpops=window.open(popurl,"","width=210,height=500,scrollbars")
|
||||
}
|
||||
function openmappopup(){
|
||||
var popurl="index.php?do=showmap"
|
||||
winpops=window.open(popurl,"","width=520,height=520,scrollbars")
|
||||
}
|
||||
</script>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{title}}</title>
|
||||
<link rel="stylesheet" href="/css/dk.css">
|
||||
|
||||
<script>
|
||||
function opencharpopup(){
|
||||
var popurl="/showchar"
|
||||
winpops=window.open(popurl,"","width=210,height=500,scrollbars")
|
||||
}
|
||||
function openmappopup(){
|
||||
var popurl="/showmap"
|
||||
winpops=window.open(popurl,"","width=520,height=520,scrollbars")
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body><center>
|
||||
<table cellspacing="0" width="90%"><tr>
|
||||
<td class="top" colspan="3">
|
||||
<table width="100%"><tr><td><img src="images/logo.gif" alt="{{dkgamename}}" title="{{dkgamename}}" border="0" /></td><td style="text-align:right; vertical-align:middle;">{{topnav}}</td></tr></table>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="left">{{leftnav}}</td>
|
||||
<td class="middle">{{content}}</td>
|
||||
<td class="right">{{rightnav}}</td>
|
||||
</tr>
|
||||
</table><br>
|
||||
<table class="copyright" width="90%"><tr>
|
||||
<td width="25%" align="center">Powered by <a href="http://dragon.se7enet.com/dev.php" target="_new">Dragon Knight</a></td><td width="25%" align="center">© 2003-2006 by renderse7en</td><td width="25%" align="center">{{totaltime}} Seconds, {{numqueries}} Queries</td><td width="25%" align="center">Version {{version}} {{build}}</td>
|
||||
</tr></table>
|
||||
</center></body>
|
||||
<body>
|
||||
<div id="game-container">
|
||||
<header>
|
||||
<img id="logo" src="/img/logo.gif" alt="{{dkgamename}}" title="{{dkgamename}}">
|
||||
<nav>{{topnav}}</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section id="left">{{leftnav}}</section>
|
||||
<section id="middle">{{content}}</section>
|
||||
<section id="right">{{rightnav}}</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<div>Powered by <a href="http://dragon.se7enet.com/dev.php" target="_new">Dragon Knight</a></div>
|
||||
<div>© 2024 Sharkk</div>
|
||||
<div>{{totaltime}} Seconds, {{numqueries}} Queries</div>
|
||||
<div>Version {{version}} {{build}}</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
THEVERYENDOFYOU;
|
||||
?>
|
||||
HTML;
|
||||
|
|
|
@ -1,39 +1,30 @@
|
|||
<?php
|
||||
$template = <<<THEVERYENDOFYOU
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_character.gif" alt="Character" title="Character" /></td></tr>
|
||||
<tr><td>
|
||||
<b>{{username}}</b><br>
|
||||
Level: {{level}}<br>
|
||||
Exp: {{experience}}<br>
|
||||
Gold: {{gold}}<br>
|
||||
HP: {{currenthp}}<br>
|
||||
MP: {{currentmp}}<br>
|
||||
TP: {{currenttp}}<br>
|
||||
{{statbars}}<br>
|
||||
<a href="javascript:opencharpopup()">Extended Stats</a>
|
||||
</td></tr>
|
||||
</table><br>
|
||||
$template = <<<HTML
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_character.gif" alt="Character" title="Character"></div>
|
||||
<b>{{username}}</b><br>
|
||||
Level: {{level}}<br>
|
||||
Exp: {{experience}}<br>
|
||||
Gold: {{gold}}<br>
|
||||
HP: {{currenthp}}<br>
|
||||
MP: {{currentmp}}<br>
|
||||
TP: {{currenttp}}<br>
|
||||
{{statbars}}<br>
|
||||
<a href="javascript:opencharpopup()">Extended Stats</a>
|
||||
</section>
|
||||
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_inventory.gif" alt="Inventory" title="Inventory" /></td></tr>
|
||||
<tr><td>
|
||||
<table width="100%">
|
||||
<tr><td><img src="images/icon_weapon.gif" alt="Weapon" title="Weapon" /></td><td width="100%">Weapon: {{weaponname}}</td></tr>
|
||||
<tr><td><img src="images/icon_armor.gif" alt="Armor" title="Armor" /></td><td width="100%">Armor: {{armorname}}</td></tr>
|
||||
<tr><td><img src="images/icon_shield.gif" alt="Shield" title="Shield" /></td><td width="100%">Shield: {{shieldname}}</td></tr>
|
||||
</table>
|
||||
Slot 1: {{slot1name}}<br>
|
||||
Slot 2: {{slot2name}}<br>
|
||||
Slot 3: {{slot3name}}
|
||||
</td></tr>
|
||||
</table><br>
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_inventory.gif" alt="Inventory" title="Inventory"></div>
|
||||
<img src="/img/icon_weapon.gif" alt="Weapon" title="Weapon"> Weapon: {{weaponname}}<br>
|
||||
<img src="/img/icon_armor.gif" alt="Armor" title="Armor"> Armor: {{armorname}}<br>
|
||||
<img src="/img/icon_shield.gif" alt="Shield" title="Shield"> Shield: {{shieldname}}<br>
|
||||
Slot 1: {{slot1name}}<br>
|
||||
Slot 2: {{slot2name}}<br>
|
||||
Slot 3: {{slot3name}}
|
||||
</section>
|
||||
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_fastspells.gif" alt="Fast Spells" title="Fast Spells" /></td></tr>
|
||||
<tr><td>
|
||||
{{magiclist}}
|
||||
</td></tr>
|
||||
</table><br>
|
||||
THEVERYENDOFYOU;
|
||||
?>
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_fastspells.gif" alt="Fast Spells" title="Fast Spells"></div>
|
||||
{{magiclist}}
|
||||
</section>
|
||||
HTML;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
$template = <<<THEVERYENDOFYOU
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_character.gif" alt="Character" title="Character" /></td></tr>
|
||||
<tr><td class="title"><img src="/img/button_character.gif" alt="Character" title="Character" /></td></tr>
|
||||
<tr><td>
|
||||
<b>{{username}}</b><br><br>
|
||||
|
||||
|
@ -23,12 +23,12 @@ Defense Power: {{defensepower}}<br>
|
|||
</table><br>
|
||||
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_inventory.gif" alt="Inventory" title="Inventory" /></td></tr>
|
||||
<tr><td class="title"><img src="/img/button_inventory.gif" alt="Inventory" title="Inventory" /></td></tr>
|
||||
<tr><td>
|
||||
<table width="100%">
|
||||
<tr><td><img src="images/icon_weapon.gif" alt="Weapon" title="Weapon" /></td><td width="100%">Weapon: {{weaponname}}</td></tr>
|
||||
<tr><td><img src="images/icon_armor.gif" alt="Armor" title="Armor" /></td><td width="100%">Armor: {{armorname}}</td></tr>
|
||||
<tr><td><img src="images/icon_shield.gif" alt="Shield" title="Shield" /></td><td width="100%">Shield: {{shieldname}}</td></tr>
|
||||
<tr><td><img src="/img/icon_weapon.gif" alt="Weapon" title="Weapon" /></td><td width="100%">Weapon: {{weaponname}}</td></tr>
|
||||
<tr><td><img src="/img/icon_armor.gif" alt="Armor" title="Armor" /></td><td width="100%">Armor: {{armorname}}</td></tr>
|
||||
<tr><td><img src="/img/icon_shield.gif" alt="Shield" title="Shield" /></td><td width="100%">Shield: {{shieldname}}</td></tr>
|
||||
</table>
|
||||
Slot 1: {{slot1name}}<br>
|
||||
Slot 2: {{slot2name}}<br>
|
||||
|
@ -37,7 +37,7 @@ Slot 3: {{slot3name}}
|
|||
</table><br>
|
||||
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/button_spells.gif" alt="Spells" title="Spells" /></td></tr>
|
||||
<tr><td class="title"><img src="/img/button_spells.gif" alt="Spells" title="Spells" /></td></tr>
|
||||
<tr><td>
|
||||
{{magiclist}}
|
||||
</td></tr>
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
<?php
|
||||
$template = <<<THEVERYENDOFYOU
|
||||
<table width="100%">
|
||||
<tr><td class="title"><img src="images/town_{{id}}.gif" alt="Welcome to {{name}}" title="Welcome to {{name}}" /></td></tr>
|
||||
<tr><td>
|
||||
<b>Town Options:</b><br>
|
||||
<ul>
|
||||
<li /><a href="index.php?do=inn">Rest at the Inn</a>
|
||||
<li /><a href="index.php?do=buy">Buy Weapons/Armor</a>
|
||||
<li /><a href="index.php?do=maps">Buy Maps</a>
|
||||
</ul>
|
||||
</td></tr>
|
||||
<tr><td><center>
|
||||
{{news}}
|
||||
<br>
|
||||
<table width="95%">
|
||||
<tr><td width="50%">
|
||||
{{whosonline}}
|
||||
</td><td>
|
||||
{{babblebox}}
|
||||
</td></tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
THEVERYENDOFYOU;
|
||||
?>
|
||||
$template = <<<HTML
|
||||
<div class="town-content">
|
||||
<div class="options">
|
||||
<div class="title"><img src="/img/town_{{id}}.gif" alt="Welcome to {{name}}" title="Welcome to {{name}}"></div>
|
||||
<b>Town Options:</b><br>
|
||||
<ul>
|
||||
<li><a href="/inn">Rest at the Inn</a></li>
|
||||
<li><a href="/buy">Buy Weapons/Armor</a></li>
|
||||
<li><a href="/maps">Buy Maps</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="news">
|
||||
{{news}}
|
||||
</div>
|
||||
|
||||
<div class="whos-online">
|
||||
{{whosonline}}
|
||||
</div>
|
||||
|
||||
<div class="babblebox">
|
||||
{{babblebox}}
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
|
|