Replace all display() calls with new Render\content call, which accounts for HTMX

This commit is contained in:
Sky Johnson 2024-12-19 12:53:51 -06:00
parent d45d3f74e5
commit d47e1c5744
14 changed files with 96 additions and 141 deletions

View File

@ -68,7 +68,7 @@ function index(): string
redirect('/fight');
}
return is_htmx() ? $page : display($page, '');
return Render\content($page);
}
/**

View File

@ -27,7 +27,7 @@ function move() {
$form = validate($_POST, ['direction' => ['in:north,west,east,south']]);
if (!$form['valid']) {
$errors = ul_from_validate_errors($form['errors']);
return is_htmx() ? $errors : display($errors, 'Move Error');
return \Render\content($errors);
}
// Current game state

View File

@ -120,22 +120,15 @@ function fight()
// Spell action
if (isset($_POST["spell"])) {
$pickedspell = $_POST["userspell"];
if ($pickedspell == 0) {
return display("You must select a spell first. Please go back and try again.", "Error");
die();
}
if ($pickedspell == 0) return \Render\content('You must select a spell first. Please go back and try again.');
$newspellrow = get_spell($pickedspell);
$spell = in_array($pickedspell, explode(',', user()->spells));
if (!$spell) {
return display("You have not yet learned this spell. Please go back and try again.", "Error");
die();
}
if (!$spell) return \Render\content('You have not yet learned this spell. Please go back and try again.');
if (user()->currentmp < $newspellrow["mp"]) {
return display("You do not have enough Magic Points to cast this spell. Please go back and try again.", "Error");
die();
return \Render\content('You do not have enough Magic Points to cast this spell. Please go back and try again.');
}
// Spell type handling (similar to original function)
@ -184,7 +177,7 @@ function fight()
// Finalize page and display it
$page = render('fight', ['page' => $page]);
return is_htmx() ? $page : display($page, "Fighting");
return \Render\content($page);
}
function victory()
@ -258,7 +251,7 @@ function victory()
user()->save();
page_title($title);
return is_htmx() ? $page : display($page, $title);
return \Render\content($page);
}
function drop()
@ -272,7 +265,7 @@ function drop()
if ($slot == 0) {
$page = 'Please go back and select an inventory slot to continue.';
return is_htmx() ? $page : display($page, '');
return \Render\content($page);
}
$slotstr = 'slot'.$slot.'id';
@ -329,7 +322,7 @@ function drop()
user()->save();
$page = 'The item has been equipped. You can now continue <a href="/" hx-get="/" hx-target="#middle">exploring</a>.';
return is_htmx() ? $page : display($page, "Item Drop");
return \Render\content($page);
}
$attributearray = array("maxhp"=>"Max HP",
@ -359,7 +352,7 @@ function drop()
$page .= "<form action=\"/drop\" method=\"post\"><select name=\"slot\"><option value=\"0\">Choose One</option><option value=\"1\">Slot 1: ".user()->slot1name."</option><option value=\"2\">Slot 2: ".user()->slot2name."</option><option value=\"3\">Slot 3: ".user()->slot3name."</option></select> <input type=\"submit\" name=\"submit\" value=\"Submit\" /></form>";
$page .= "You may also choose to just continue <a href=\"/\" hx-get=\"/\" hx-target=\"#middle\">exploring</a> and give up this item.";
return is_htmx() ? $page : display($page, "Item Drop");
return \Render\content($page);
}
@ -371,7 +364,7 @@ function dead()
to continue your journey.<br><br>
You may now continue back to <a href="/" hx-get="/" hx-target="#middle">town</a>, and we hope you fair better next time.
HTML;
return is_htmx() ? $page : display($page, 'You Died');
return \Render\content($page);
}
function handleMonsterTurn(&$userrow, $monsterrow)

View File

@ -56,7 +56,7 @@ function donothing($start = 0)
$page .= '</table></td></tr></table>';
page_title('Forum');
return is_htmx() ? $page : display($page);
return \Render\content($page);
}
function showthread($id, $start)
@ -72,7 +72,7 @@ function showthread($id, $start)
$page .= "<table width=\"100%\"><tr><td><b>Reply To This Thread:</b><br><form action=\"/forum/reply\" method=\"post\" hx-post=\"/forum/reply\" hx-target=\"#middle\"><input type=\"hidden\" name=\"parent\" value=\"$id\" /><input type=\"hidden\" name=\"title\" value=\"Re: ".$title["title"]."\" /><textarea name=\"content\" rows=\"7\" cols=\"40\"></textarea><br><input type=\"submit\" name=\"submit\" value=\"Submit\" /> <input type=\"reset\" name=\"reset\" value=\"Reset\" /></form></td></tr></table>";
page_title('Forum: '.$title['title']);
return is_htmx() ? $page : display($page);
return \Render\content($page);
}
function reply()
@ -112,5 +112,5 @@ function newthread()
$page = "<table width=\"100%\"><tr><td><b>Make A New Post:</b><br><br/ ><form action=\"/forum/new\" method=\"post\" hx-post=\"/forum/new\" hx-target=\"#middle\">Title:<br><input type=\"text\" name=\"title\" size=\"50\" maxlength=\"50\" /><br><br>Message:<br><textarea name=\"content\" rows=\"7\" cols=\"40\"></textarea><br><br><input type=\"submit\" name=\"submit\" value=\"Submit\" /> <input type=\"reset\" name=\"reset\" value=\"Reset\" /></form></td></tr></table>";
page_title('Form: New Thread');
return is_htmx() ? $page : display($page);
return \Render\content($page);
}

View File

@ -30,5 +30,5 @@ function healspells(int $id): string
}
page_title('Casting '.$spell['name']);
return is_htmx() ? $page : display($page, '');
return \Render\content($page);
}

View File

@ -79,9 +79,6 @@ function inn()
$town = get_town_by_xy(user()->longitude, user()->latitude);
if ($town === false) { exit('Cheat attempt detected.<br><br>Get a life, loser.'); }
$htmx = is_htmx();
page_title($town['name'] . ' Inn');
if (user()->gold < $town['innprice']) {
$page = <<<HTML
You do not have enough gold to stay at this Inn tonight. <br><br>
@ -107,7 +104,8 @@ function inn()
HTML;
}
return $htmx ? $page : display($page, $town['name'] . ' Inn');
page_title($town['name'] . ' Inn');
return \Render\content($page);
}
/**
@ -120,8 +118,6 @@ function shop()
$town = get_town_by_xy(user()->longitude, user()->latitude);
if ($town === false) exit('Cheat attempt detected.<br><br>Get a life, loser.');
$htmx = is_htmx();
page_title($town['name'] . ' Shop');
$page = <<<HTML
Buying weapons will increase your Attack Power. Buying armor and shields will increase your Defense Power.<br><br>
@ -161,7 +157,8 @@ function shop()
If you've changed your mind, you may also return back to <a hx-get="/" hx-target="#middle">town</a>.
HTML;
return $htmx ? $page : display($page, $town['name'] . ' Shop');
page_title($town['name'] . ' Shop');
return \Render\content($page);
}
/**
@ -192,7 +189,7 @@ function buy(int $id)
if (!isset($type_mapping[$item["type"]])) { // should never happen
$page = 'Error! Invalid item type...<br>'.var_dump($item);
return is_htmx() ? $page : display($page, '');
return \Render\content($page, '');
}
// Retrieve current equipped item or create a default
@ -276,7 +273,7 @@ function buy(int $id)
}
page_title('Buying '.$item['name']);
return is_htmx() ? $page : display($page, 'Buying '.$item['name']);
return \Render\content($page);
}
/**
@ -322,7 +319,7 @@ function maps()
HTML;
page_title('Maps');
return is_htmx() ? $page : display($page, '');
return \Render\content($page);
}
function buy_map(int $id): string
@ -357,7 +354,7 @@ function buy_map(int $id): string
}
page_title('Buying '.$town['name'].' Map');
return is_htmx() ? $page : display($page, '');
return \Render\content($page);
}
/**
@ -403,5 +400,5 @@ function travelto(int $id, bool $use_points = true): string
}
page_title('Travelling to '.$town['name']);
return is_htmx() ? $page : display($page, '');
return \Render\content($page);
}

View File

@ -10,7 +10,7 @@ function register_routes(Router $r): Router
$r->get('/logout', 'Users\logout');
$r->form('/register', 'Users\register');
$r->form('/lostpassword', 'Users\lostpassword');
$r->form('/changepassword', 'Users\changepassword');
$r->post('/changepassword', 'Users\changepassword');
$r->form('/verify', 'Users\verify');
$r->form('/settings', 'Users\settings');
return $r;
@ -38,7 +38,8 @@ function login()
redirect('/');
}
return display(render('login'), 'Log In', true, false, false);
page_title('Login');
return \Render\content(render('login'));
}
/**
@ -99,7 +100,8 @@ function register()
$page = render('register', ['controlrow' => $controlrow]);
}
return display($page, 'Register', true, false, false);
page_title('Register');
return \Render\content($page);
}
function verify()
@ -114,10 +116,10 @@ function verify()
db()->query("UPDATE users SET verify='g2g' WHERE username=?;", [$u]);
return display("Your account was verified successfully.<br><br>You may now continue to the <a href=\"/login\">Login Page</a> and start playing the game.<br><br>Thanks for playing!","Verify Email",false,false,false);
return \Render\content("Your account was verified successfully.<br><br>You may now continue to the <a href=\"/login\">Login Page</a> and start playing the game.<br><br>Thanks for playing!");
}
return display(render('verify'), "Verify Email", true, false, false);
return \Render\content(render('verify'));
}
function lostpassword()
@ -133,17 +135,19 @@ function lostpassword()
db()->query('UPDATE users SET password=? WHERE email=?;', [$hashed, $e]);
if (sendpassemail($e, $newpass)) {
return display("Your new password was emailed to the address you provided.<br><br>Once you receive it, you may <a href=\"/login\">Log In</a> and continue playing.<br><br>Thank you.","Lost Password",false,false,false);
return \Render\content("Your new password was emailed to the address you provided.<br><br>Once you receive it, you may <a href=\"/login\">Log In</a> and continue playing.<br><br>Thank you.");
} else {
return display("There was an error sending your new password.<br><br>Please check with the game administrator for more information.<br><br>We apologize for the inconvience.","Lost Password",false,false,false);
return \Render\content("There was an error sending your new password.<br><br>Please check with the game administrator for more information.<br><br>We apologize for the inconvience.");
}
}
return display(render('lostpassword'), "Lost Password", true, false, false);
return \Render\content(render('lostpassword'));
}
function changepassword()
{
global $auth;
if (isset($_POST["submit"])) {
$u = trim($_POST['username'] ?? '');
$p = $_POST['password'] ?? '';
@ -167,12 +171,10 @@ function changepassword()
$realnewpass = password_hash($np, PASSWORD_ARGON2ID);
db()->query('UPDATE users SET password=? WHERE username=?;', [$realnewpass, $u]);
set_cookie('dkgame', '', -3600);
$auth->logout();
return 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\">log back in</a> to continue playing.","Change Password",false,false,false);
return \Render\content("Your password was changed successfully.<br><br>You have been logged out of the game to avoid errors.<br><br>Please <a href=\"/login\">log back in</a> to continue playing.");
}
return display(render('changepassword'), "Change Password", true, false, false);
}
function settings()
@ -188,10 +190,10 @@ function settings()
user()->save();
$alert = '<div class="alert">Settings updated</div>';
return display($alert . render('settings'), "Account Settings");
return \Render\content($alert . render('settings'));
}
return display(render('settings'), "Account Settings");
return \Render\content(render('settings'));
}
function sendpassemail($emailaddress, $password)

View File

@ -31,7 +31,8 @@ if (!file_exists('../.installed') && $uri[0] !== 'install') {
$controlrow = get_control_row();
if (!$controlrow["gameopen"]) {
display("The game is currently closed for maintanence. Please check back later.", "Game Closed");
echo Render\content('The game is currently closed for maintanence. Please check back later.');
exit;
}
$auth = new Auth;

View File

@ -31,22 +31,13 @@ function redirect(string $location): void
}
/**
* Return the path to a view file.
*/
function template(string $name): string
{
return "../templates/$name.php";
}
/**
* Render a view with the given data. Looks for `$path_to_base_view` through `template()`. Can be used redundantly
* within the template.
* Render a view with the given data. Can be used redundantly within the template.
*/
function render(string $path_to_base_view, array $data = []): string|false
{
ob_start();
extract($data);
require template($path_to_base_view);
require "../templates/$name.php";
return ob_get_clean();
}
@ -102,56 +93,11 @@ function display_admin($content, $title)
}
/**
* Finalize page and output to browser.
* Determine what game skin to use. If a user is logged in then it uses their setting, otherwise defaults to 0 (retro).
*/
function display($content, $title = '', bool $topnav = true, bool $leftnav = true, bool $rightnav = true): string
function game_skin(): int
{
global $controlrow;
$game_skin = user() !== false ? user()->game_skin : 0;
return render('layouts/primary', [
"dkgamename" => $controlrow["gamename"],
"content" => $content,
"game_skin" => $game_skin,
"topnav" => $topnav ? Render\header_links() : ''
]);
}
function checkcookies()
{
$row = false;
if (isset($_COOKIE["dkgame"])) {
// COOKIE FORMAT:
// {ID} {USERNAME} {PASSWORDHASH} {REMEMBERME}
$theuser = explode(" ",$_COOKIE["dkgame"]);
$query = db()->query('SELECT * FROM users WHERE id = ? AND username = ? AND password = ? LIMIT 1;', [$theuser[0], $theuser[1], $theuser[2]]);
if ($query === false) {
set_cookie('dkgame', '', -3600);
die("Invalid cookie data. Please log in again.");
}
$row = $query->fetchArray(SQLITE3_ASSOC);
set_cookie('dkgame', implode(" ", $theuser), (int) $theuser[3] === 1 ? time() + 31536000 : 0);
db()->query('UPDATE users SET onlinetime = CURRENT_TIMESTAMP WHERE id = ?;', [$theuser[0]]);
}
return $row;
}
/**
* Set a cookie with secure and HTTP-only flags.
*/
function set_cookie($name, $value, $expires)
{
setcookie($name, $value, [
'expires' => $expires,
'path' => '/',
'domain' => '', // Defaults to the current domain
'secure' => true, // Ensure the cookie is only sent over HTTPS
'httponly' => true, // Prevent access to cookie via JavaScript
'samesite' => 'Strict' // Enforce SameSite=Strict
]);
return user() !== false ? user()->game_skin : 0;
}
/**

View File

@ -7,18 +7,20 @@ namespace Render;
to HTMX/AJAX for more fluid gameplay.
*/
function header_links(): string
/**
* Prepare content for final render. If the request is HTMX-based, will return just the content passed to it. Otherwise
* it will render() onto layouts/primary with some additional bits.
*/
function content(string $content): string
{
if (user() !== false) {
$links = "<a href='/logout'><img src='/img/button_logout.gif' alt='Log Out' title='Log Out'></a>";
} else {
$links = <<<HTML
<a href='/login'><img src='/img/button_login.gif' alt='Log In' title='Log In'></a>
<a href='/register'><img src='/img/button_register.gif' alt='Register' title='Register'></a>
HTML;
}
if (is_htmx()) return $content;
return $links .= "<a href='/help'><img src='/img/button_help.gif' alt='Help' title='Help'></a>";
global $controlrow;
return render('layouts/primary', [
"dkgamename" => $controlrow["gamename"],
"content" => $content
]);
}
function debug_db_info(): string {

View File

@ -1,10 +0,0 @@
<form action="/changepassword" method="post">
<table width="100%">
<tr><td colspan="2">Use the form below to change your password. All fields are required. New passwords must be 10 alphanumeric characters or less.</td></tr>
<tr><td width="20%">Username:</td><td><input type="text" name="username" size="30" maxlength="30" /></td></tr>
<tr><td>Old Password:</td><td><input type="password" name="password" /></td></tr>
<tr><td>New Password:</td><td><input type="password" name="new_password" /></td></tr>
<tr><td>Verify New Password:</td><td><input type="password" name="new_password2" /><br><br><br></td></tr>
<tr><td colspan="2"><input type="submit" name="submit" value="Submit"> <input type="reset" name="reset" value="Reset"></td></tr>
</table>
</form>

View File

@ -20,11 +20,19 @@
}
</script>
</head>
<body class="skin-<?= $game_skin ?>">
<body class="skin-<?= game_skin() ?>">
<div id="game-container">
<header>
<a href="/"><img id="logo" src="/img/logo.gif" alt="<?= $dkgamename ?>" title="<?= $dkgamename ?>"></a>
<nav><?= $topnav ?></nav>
<nav>
<?php if (user() !== false): ?>
<a href='/logout'><img src='/img/button_logout.gif' alt='Log Out' title='Log Out'></a>
<?php else: ?>
<a href='/login'><img src='/img/button_login.gif' alt='Log In' title='Log In'></a>
<a href='/register'><img src='/img/button_register.gif' alt='Register' title='Register'></a>
<?php endif; ?>
<a href="/help" hx-boost='/help'><img src='/img/button_help.gif' alt='Help' title='Help'></a>
</nav>
</header>
<main>

View File

@ -50,10 +50,9 @@
<a href="/" hx-get="/" hx-target="#middle">Home</a><br>
<a href="/forum" hx-get="/forum" hx-target="#middle">Forum</a><br>
<a href="/settings">Settings</a><br>
<a href="/changepassword">Change Password</a><br>
<a href="/logout">Log Out</a><br>
<?php if (user()->authlevel === 1): ?>
<a href="/admin">Admin</a><br>
<?php endif; ?>
<a href="/help">Help</a>
<a href="/help">Help</a><br>
<a href="/logout">Log Out</a>
</section>

View File

@ -1,12 +1,29 @@
<h1>Account Settings</h1>
<p>Here you can change some basic settings for your account.</p>
<form action="/settings" method="post">
<label for="game_skin">Game Skin</label>
<select id="game_skin" name="game_skin">
<option value="0">Default</option>
<option value="1">Snowstorm</option>
</select>
<section>
<h2>Game Skin</h2>
<form action="/settings" method="post">
<select name="game_skin">
<option value="0">Default</option>
<option value="1">Snowstorm</option>
</select>
<button type="submit">Save</button>
</form>
</section>
<section>
<h2>Change Password</h2>
<form action="/changepassword" method="post">
<table width="100%">
<tr><td colspan="2">Use the form below to change your password. All fields are required. New passwords must be 10 alphanumeric characters or less.</td></tr>
<tr><td>Old Password:</td><td><input type="password" name="password"></td></tr>
<tr><td>New Password:</td><td><input type="password" name="new_password"></td></tr>
<tr><td>Verify New Password:</td><td><input type="password" name="confirm_new_password"><br><br><br></td></tr>
<tr><td colspan="2"><input type="submit" name="submit" value="Submit"></td></tr>
</table>
</form>
</section>
<button type="submit">Save</button>
</form>