Compare commits
No commits in common. "a20c443178e1fe661c69fe01c0874e7dc603af5f" and "56524da0c6ebc4c52187065f7f98368276fb451a" have entirely different histories.
a20c443178
...
56524da0c6
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
server/database/*.db
|
server/database/dragon.db
|
||||||
server/database/*.db-shm
|
server/database/dragon.db-shm
|
||||||
server/database/*.db-wal
|
server/database/dragon.db-wal
|
||||||
server/.installed
|
server/.installed
|
|
@ -22,36 +22,6 @@ body {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
|
||||||
margin-top: 1rem;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgba(0, 0, 0, 0.25);
|
|
||||||
padding: 0.5rem;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
div#content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 1rem;
|
|
||||||
|
|
||||||
aside#left {
|
|
||||||
flex-grow: 1;
|
|
||||||
max-width: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
aside#right {
|
|
||||||
flex-grow: 1;
|
|
||||||
max-width: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
|
@ -98,4 +68,4 @@ div.alert {
|
||||||
color: hsl(359deg, 68%, 11%);
|
color: hsl(359deg, 68%, 11%);
|
||||||
background-color: hsl(359deg, 68%, 71%);
|
background-color: hsl(359deg, 68%, 71%);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,3 @@ if ($route == 'gate') return GateModule::handle();
|
||||||
// 404
|
// 404
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
echo '404: ' . $route;
|
echo '404: ' . $route;
|
||||||
|
|
||||||
// cleanup
|
|
||||||
$app->cleanup();
|
|
||||||
|
|
|
@ -11,26 +11,19 @@ class App
|
||||||
public static Request $req;
|
public static Request $req;
|
||||||
public static Auth $auth;
|
public static Auth $auth;
|
||||||
public static array $s = []; // game settings
|
public static array $s = []; // game settings
|
||||||
public static array $flashes = []; // flash messages
|
|
||||||
|
|
||||||
public function __construct(string $dbPath)
|
public function __construct(string $dbPath)
|
||||||
{
|
{
|
||||||
self::$req = new Request(); // the current request
|
self::$req = new Request(); // the current request
|
||||||
self::$db = new Database($dbPath); // the database
|
self::$db = new Database($dbPath); // the database
|
||||||
self::$dbPath = $dbPath; // the database path
|
self::$dbPath = $dbPath; // the database path
|
||||||
self::$auth = new Auth();
|
|
||||||
|
|
||||||
// load game settings
|
// load game settings
|
||||||
$s = self::$db->q('SELECT * FROM settings WHERE id = 1;');
|
$s = self::$db->q('SELECT * FROM settings WHERE id = 1;');
|
||||||
self::$s = $s ? $s->fetch() : [];
|
self::$s = $s ? $s->fetch() : [];
|
||||||
|
|
||||||
if (INSTALLED) {
|
// init authentication
|
||||||
// load the player's auth
|
self::$auth = new Auth();
|
||||||
self::$auth->good();
|
|
||||||
}
|
|
||||||
|
|
||||||
// load flash messages
|
|
||||||
self::$flashes = $_SESSION['flash'] ?? [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function performDatabaseReset(): void
|
public static function performDatabaseReset(): void
|
||||||
|
@ -45,21 +38,4 @@ class App
|
||||||
{
|
{
|
||||||
return self::$auth->good();
|
return self::$auth->good();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function flash(string $key, mixed $value = null): mixed
|
|
||||||
{
|
|
||||||
// get a flash message
|
|
||||||
if ($value === null) return self::$flashes[$key] ?? null;
|
|
||||||
|
|
||||||
// set a flash message
|
|
||||||
$_SESSION['flash'][$key] = $value;
|
|
||||||
self::$flashes[$key] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function cleanup()
|
|
||||||
{
|
|
||||||
// clean up flash messages
|
|
||||||
$_SESSION['flash'] = [];
|
|
||||||
unset($_SESSION['flash']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Auth
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
$this->good();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function login(string $identifier, string $password, bool $remember = false): bool
|
public function login(string $identifier, string $password, bool $remember = false): bool
|
||||||
|
@ -37,25 +37,20 @@ class Auth
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function remember(int $id): array
|
private function remember(int $id): array|false
|
||||||
{
|
{
|
||||||
$data = ['player_id' => $id, 'token' => token()];
|
$data = ['player_id' => $id, 'token' => token()];
|
||||||
|
|
||||||
Session::createOrUpdate($data); // save the token in the database, overwriting the old one if it exists
|
Session::createOrUpdate($data);
|
||||||
setcookie(self::COOKIE_NAME, implode('::', $data), strtotime('+30 days'), '/', '', true, true);
|
setcookie(self::COOKIE_NAME, implode('::', $data), strtotime('+30 days'), '/', '', true, true);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logout(): void
|
private function logout(): void
|
||||||
{
|
{
|
||||||
if (isset($_SESSION['player_id'])) unset($_SESSION['player_id']);
|
if (isset($_SESSION['player_id'])) unset($_SESSION['player_id']);
|
||||||
if (isset($_COOKIE[self::COOKIE_NAME])) setcookie(self::COOKIE_NAME, '', time() - 86400, '/', '', true, true);
|
if (isset($_COOKIE[self::COOKIE_NAME])) setcookie(self::COOKIE_NAME, '', time() - 86400, '/', '', true, true);
|
||||||
if (ini_get("session.use_cookies")) {
|
|
||||||
$params = session_get_cookie_params();
|
|
||||||
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
|
|
||||||
}
|
|
||||||
session_destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function good(): bool
|
public function good(): bool
|
||||||
|
@ -82,4 +77,4 @@ class Auth
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -40,7 +40,7 @@ class Player
|
||||||
public static function validateCredentials(string $identifier, string $password, bool $fetch = false): int|false
|
public static function validateCredentials(string $identifier, string $password, bool $fetch = false): int|false
|
||||||
{
|
{
|
||||||
// get the player from their username or email
|
// get the player from their username or email
|
||||||
$player = App::$db->do("SELECT " . ($fetch ? '*' : 'id, password') . " FROM players WHERE LOWER(username) = :i OR LOWER(email) = :i LIMIT 1;", ['i' => strtolower($identifier)]);
|
$player = App::$db->do("SELECT " . ($fetch ? '*' : 'id, password') . " FROM players WHERE username = :i OR email = :i LIMIT 1;", ['i' => $identifier]);
|
||||||
if ($player == false) return false;
|
if ($player == false) return false;
|
||||||
$player = $player->fetch();
|
$player = $player->fetch();
|
||||||
|
|
||||||
|
@ -52,4 +52,4 @@ class Player
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,47 +9,11 @@ class GateModule
|
||||||
$s = App::$req->uri(1) ?? ''; // second segment
|
$s = App::$req->uri(1) ?? ''; // second segment
|
||||||
$m = App::$req->method; // request method
|
$m = App::$req->method; // request method
|
||||||
|
|
||||||
if (App::$auth->good() && in_array($s, self::GUEST)) redirect('/');
|
if ($s == '' || $s == 'login') return self::login();
|
||||||
|
|
||||||
if ($s == '' || $s == 'login') return self::login($m);
|
|
||||||
if ($s == 'logout' && $m == 'POST') return self::logout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function login(string $method)
|
public static function login()
|
||||||
{
|
{
|
||||||
// just display the login page
|
echo render('layout', ['title' => 'Login']);
|
||||||
if ($method == 'GET') {
|
|
||||||
echo render('layout', ['title' => 'Login', 'content' => 'gate/login']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle the login form
|
|
||||||
$id = trim($_POST['id'] ?? ''); // identifier; let a user log in with email or username
|
|
||||||
$pw = $_POST['pw'] ?? ''; // password
|
|
||||||
|
|
||||||
// fields are required
|
|
||||||
if (empty($id) || empty($pw)) {
|
|
||||||
App::flash('error', 'Please fill out all fields.');
|
|
||||||
redirect('/gate/login');
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the user, login if valid
|
|
||||||
$found = App::$auth->login($id, $pw, isset($_POST['remember']));
|
|
||||||
|
|
||||||
// Login is valid!
|
|
||||||
if ($found) {
|
|
||||||
App::flash('success', 'Welcome back!');
|
|
||||||
redirect('/');
|
|
||||||
} else {
|
|
||||||
App::flash('error', 'Player account not found.');
|
|
||||||
redirect('/gate/login');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private static function logout()
|
|
||||||
{
|
|
||||||
App::$auth->logout();
|
|
||||||
App::flash('success', 'You have been logged out.');
|
|
||||||
redirect('/');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,13 +4,8 @@ class HomeModule
|
||||||
{
|
{
|
||||||
public static function home()
|
public static function home()
|
||||||
{
|
{
|
||||||
foreach ($_SESSION['flash'] as $key => $value) {
|
|
||||||
echo '<div class="alert ' . $key . '">- ' . $value . '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (App::auth()) {
|
if (App::auth()) {
|
||||||
echo 'You are already logged in!<br>';
|
echo 'You are already logged in!<br>';
|
||||||
echo '<form action="/gate/logout" method="post"><button>Logout</button></form>';
|
|
||||||
} else {
|
} else {
|
||||||
echo 'You are not logged in!<br>';
|
echo 'You are not logged in!<br>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,18 +294,19 @@ class InstallModule
|
||||||
'level' => $_POST['level'] ?? 1
|
'level' => $_POST['level'] ?? 1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// login the admin
|
|
||||||
App::$auth->login($_POST['username'], $_POST['password']);
|
|
||||||
|
|
||||||
// Create the .installed file in the server folder
|
// Create the .installed file in the server folder
|
||||||
file_put_contents(SERVER.'/.installed', 'Installed on '.date('Y-m-d H:i:s'));
|
file_put_contents(SERVER.'/.installed', 'Installed on '.date('Y-m-d H:i:s'));
|
||||||
|
|
||||||
|
// login the admin
|
||||||
|
App::$auth->login($_POST['username'], $_POST['password']);
|
||||||
|
|
||||||
// Render the finished page!
|
// Render the finished page!
|
||||||
echo render('install/layout', ['title' => 'Finished!', 'step' => 'done', 'name' => $_POST['username'], 'complete' => $_POST['complete'] ?? false]);
|
echo render('install/layout', ['title' => 'Finished!', 'step' => 'done', 'name' => $_POST['username'], 'complete' => $_POST['complete'] ?? false]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function fourOhFour()
|
private static function fourOhFour()
|
||||||
{
|
{
|
||||||
echo render('install/layout', ['title' => 'Four Oh Four', 'step' => 'four']);
|
echo render('install/layout', ['title' => 'Four Oh Four', 'step' => 'four']);
|
||||||
}
|
}
|
||||||
}
|
}
|
0
server/templates/auth/login.php
Normal file
0
server/templates/auth/login.php
Normal file
|
@ -1,7 +0,0 @@
|
||||||
<form action="/gate/login" method="post">
|
|
||||||
<input type="text" name="id" placeholder="Email or Username">
|
|
||||||
<input type="password" name="pw" placeholder="Password">
|
|
||||||
<input type="checkbox" name="remember" id="remember">
|
|
||||||
<label for="remember">Remember me</label>
|
|
||||||
<button>Login</button>
|
|
||||||
</form>
|
|
|
@ -14,25 +14,21 @@
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<aside id="left">
|
<aside id="left">
|
||||||
<?php if (App::$auth->good()) {
|
left
|
||||||
echo render('partials/left', $data);
|
|
||||||
} ?>
|
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<?= render($content, $data) ?>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<aside id="right">
|
<aside id="right">
|
||||||
<?php if (App::$auth->good()) {
|
right
|
||||||
echo render('partials/right', $data);
|
|
||||||
} ?>
|
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<?= render('partials/footer', $data) ?>
|
<?= render('partials/footer', $data) ?>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,11 +1 @@
|
||||||
<div>
|
footer
|
||||||
© <?= date('Y') ?> <?= App::$s['game_dev'] ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<?= App::$db->q("SELECT COUNT(id) FROM players WHERE last_online > ?;", [time() - 300])->fetchColumn() ?> players online
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<?= App::$db->queries() ?> queries in <?= round(App::$db->time(), 2) ?> seconds
|
|
||||||
</div>
|
|
|
@ -1 +0,0 @@
|
||||||
Left
|
|
|
@ -1 +0,0 @@
|
||||||
Right
|
|
Loading…
Reference in New Issue
Block a user