big model changes
This commit is contained in:
parent
3291c1caa6
commit
169e617989
|
@ -7,15 +7,13 @@ require_once '../src/bootstrap.php';
|
|||
$r = new Router;
|
||||
|
||||
$r->get('/', function() {
|
||||
global $userrow;
|
||||
|
||||
if ($userrow["currentaction"] == "In Town") {
|
||||
if (user()->currentaction === "In Town") {
|
||||
$page = dotown();
|
||||
$title = "In Town";
|
||||
} elseif ($userrow["currentaction"] == "Exploring") {
|
||||
} elseif (user()->currentaction === "Exploring") {
|
||||
$page = doexplore();
|
||||
$title = "Exploring";
|
||||
} elseif ($userrow["currentaction"] == "Fighting") {
|
||||
} elseif (user()->currentaction === "Fighting") {
|
||||
redirect('/fight');
|
||||
}
|
||||
|
||||
|
@ -51,15 +49,13 @@ $l['handler'](...$l['params'] ?? []);
|
|||
|
||||
function donothing()
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
if ($userrow["currentaction"] == "In Town") {
|
||||
if (user()->currentaction == "In Town") {
|
||||
$page = dotown();
|
||||
$title = "In Town";
|
||||
} elseif ($userrow["currentaction"] == "Exploring") {
|
||||
} elseif (user()->currentaction == "Exploring") {
|
||||
$page = doexplore();
|
||||
$title = "Exploring";
|
||||
} elseif ($userrow["currentaction"] == "Fighting") {
|
||||
} elseif (user()->currentaction == "Fighting") {
|
||||
redirect('/fight');
|
||||
}
|
||||
|
||||
|
@ -71,9 +67,9 @@ function donothing()
|
|||
*/
|
||||
function dotown()
|
||||
{
|
||||
global $userrow, $controlrow;
|
||||
global $controlrow;
|
||||
|
||||
$townrow = get_town_by_xy($userrow['longitude'], $userrow['latitude']);
|
||||
$townrow = get_town_by_xy(user()->longitude, user()->latitude);
|
||||
if ($townrow === false) display("There is an error with your user account, or with the town data. Please try again.","Error");
|
||||
|
||||
$townrow["news"] = "";
|
||||
|
@ -119,6 +115,11 @@ function dotown()
|
|||
HTML;
|
||||
}
|
||||
|
||||
$u = User::find(1);
|
||||
$u->gold += 100;
|
||||
$u->save();
|
||||
var_dump($u->gold);
|
||||
|
||||
return render('towns', ['town' => $townrow]);
|
||||
}
|
||||
|
||||
|
@ -145,7 +146,7 @@ function show_character_info(int $id = 0): void
|
|||
{
|
||||
global $controlrow, $userrow;
|
||||
|
||||
$userrow = ($id === 0) ? $userrow : get_user_by_id($id);
|
||||
$userrow = ($id === 0) ? $userrow : get_user($id);
|
||||
if ($userrow === false) exit('Failed to show info for user ID '.$id);
|
||||
|
||||
$levelrow = db()->query("SELECT `{$userrow["charclass"]}_exp` FROM levels WHERE id=? LIMIT 1;", [$userrow['level'] + 1])->fetchArray(SQLITE3_ASSOC);
|
||||
|
@ -171,12 +172,10 @@ function show_character_info(int $id = 0): void
|
|||
|
||||
function showmap()
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
$pos = sprintf(
|
||||
'<div style="position: absolute; width: 5px; height: 5px; border-radius: 1000px; border: solid 1px black; background-color: red; left: %dpx; top: %dpx;"></div>',
|
||||
round(258 + $userrow['longitude'] * (500 / 500) - 3),
|
||||
round(258 - $userrow['latitude'] * (500 / 500) - 3)
|
||||
round(258 + user()->longitude * (500 / 500) - 3),
|
||||
round(258 - user()->latitude * (500 / 500) - 3)
|
||||
);
|
||||
|
||||
echo render('minimal', [
|
||||
|
@ -191,13 +190,11 @@ function showmap()
|
|||
*/
|
||||
function babblebox()
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$safecontent = make_safe($_POST["babble"]);
|
||||
if (!empty($safecontent)) {
|
||||
db()->query('INSERT INTO babble (posttime, author, babble) VALUES (CURRENT_TIMESTAMP, ?, ?);',
|
||||
[$userrow['username'], $safecontent]);
|
||||
[user()->username, $safecontent]);
|
||||
}
|
||||
redirect('/babblebox');
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ use Router;
|
|||
|
||||
function register_routes(Router $r): Router
|
||||
{
|
||||
global $userrow;
|
||||
if (isset($userrow) && $userrow !== false && $userrow['authlevel'] === 1) {
|
||||
if (user('authlevel') === 1) {
|
||||
$r->get('/admin', 'Admin\donothing');
|
||||
|
||||
$r->form('/admin/main', 'Admin\primary');
|
||||
|
|
|
@ -2,35 +2,55 @@
|
|||
|
||||
// explore.php :: Handles all map exploring, chances to fight, etc.
|
||||
|
||||
function move()
|
||||
{
|
||||
global $userrow, $controlrow;
|
||||
function move() {
|
||||
global $controlrow;
|
||||
|
||||
if ($userrow["currentaction"] == "Fighting") { redirect('/fight'); }
|
||||
// Early exit if fighting
|
||||
if (user()->currentaction == 'Fighting') redirect('/fight');
|
||||
|
||||
$latitude = $userrow["latitude"];
|
||||
$longitude = $userrow["longitude"];
|
||||
// Validate direction
|
||||
$form = validate($_POST, ['direction' => ['in:north,west,east,south']]);
|
||||
if (!$form['valid']) display(ul_from_validate_errors($form['errors']), 'Move Error');
|
||||
|
||||
$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'];
|
||||
// Current game state
|
||||
$game_size = $controlrow['gamesize'];
|
||||
$latitude = user('latitude');
|
||||
$longitude = user('longitude');
|
||||
$direction = $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); } }
|
||||
// Calculate new coordinates with boundary checks
|
||||
switch ($direction) {
|
||||
case 'north':
|
||||
$latitude = min($latitude + 1, $game_size);
|
||||
break;
|
||||
case 'south':
|
||||
$latitude = max($latitude - 1, -$game_size);
|
||||
break;
|
||||
case 'east':
|
||||
$longitude = min($longitude + 1, $game_size);
|
||||
break;
|
||||
case 'west':
|
||||
$longitude = max($longitude - 1, -$game_size);
|
||||
break;
|
||||
}
|
||||
|
||||
$town = get_town_by_xy($longitude, $latitude);
|
||||
// Check for town
|
||||
$town = get_town_by_xy($longitude, $latitude);
|
||||
if ($town !== false) {
|
||||
Towns\travelto($town['id'], false);
|
||||
return;
|
||||
}
|
||||
|
||||
$chancetofight = rand(1, 5);
|
||||
$action = $chancetofight === 1 ? "currentaction='Fighting', currentfight='1'," : "currentaction='Exploring',";
|
||||
// Determine action (1 in 5 chance of fighting)
|
||||
$action = (rand(1, 5) === 1)
|
||||
? "currentaction='Fighting', currentfight='1',"
|
||||
: "currentaction='Exploring',";
|
||||
|
||||
// Update user's position
|
||||
db()->query(
|
||||
"UPDATE users SET $action latitude = ?, longitude = ?, dropcode = 0 WHERE id = ?;",
|
||||
[$latitude, $longitude, user()->id]
|
||||
);
|
||||
|
||||
db()->query("UPDATE users SET $action latitude = ?, longitude = ?, dropcode = 0 WHERE id = ?;", [$latitude, $longitude, $userrow['id']]);
|
||||
redirect('/');
|
||||
}
|
||||
|
|
|
@ -25,20 +25,18 @@ function register_routes(Router $r): Router
|
|||
*/
|
||||
function inn()
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
$townrow = get_town_by_xy($userrow["longitude"], $userrow["latitude"]);
|
||||
$townrow = get_town_by_xy(user()->longitude, user()->latitude);
|
||||
if ($townrow === false) { display("Cheat attempt detected.<br><br>Get a life, loser.", "Error"); }
|
||||
|
||||
if ($userrow["gold"] < $townrow["innprice"]) {
|
||||
if (user()->gold < $townrow["innprice"]) {
|
||||
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"])) {
|
||||
$newgold = $userrow["gold"] - $townrow["innprice"];
|
||||
$newgold = user()->gold - $townrow["innprice"];
|
||||
db()->query(
|
||||
'UPDATE users SET gold=?, currenthp=?, currentmp=?, currenttp=? WHERE id=?',
|
||||
[$newgold, $userrow['maxhp'], $userrow['maxmp'], $userrow['maxtp'], $userrow['id']
|
||||
[$newgold, user()->maxhp, user()->maxmp, user()->maxtp, user()->id
|
||||
]);
|
||||
$title = "Inn";
|
||||
$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.";
|
||||
|
@ -63,9 +61,7 @@ function inn()
|
|||
*/
|
||||
function buy()
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
$townrow = get_town_by_xy($userrow['longitude'], $userrow['latitude']);
|
||||
$townrow = get_town_by_xy(user()->longitude, user()->latitude);
|
||||
if ($townrow === false) display("Cheat attempt detected.<br><br>Get a life, loser.", "Error");
|
||||
|
||||
$items = db()->query("SELECT * FROM items WHERE id IN ({$townrow["itemslist"]});");
|
||||
|
@ -79,7 +75,7 @@ function buy()
|
|||
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"]) {
|
||||
if (user()->weaponid == $itemsrow["id"] || user()->armorid == $itemsrow["id"] || user()->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 = ""; }
|
||||
|
@ -98,21 +94,19 @@ function buy()
|
|||
*/
|
||||
function buy2($id)
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
$townrow = get_town_by_xy($userrow['longitude'], $userrow['latitude']);
|
||||
$townrow = get_town_by_xy(user()->longitude, user()->latitude);
|
||||
if ($townrow === false) display("Cheat attempt detected.<br><br>Get a life, loser.", "Error");
|
||||
$townitems = explode(",", $townrow["itemslist"]);
|
||||
if (!in_array($id, $townitems)) display("Cheat attempt detected.<br><br>Get a life, loser.", "Error");
|
||||
|
||||
$item = get_item($id);
|
||||
|
||||
if ($userrow["gold"] < $item["buycost"]) {
|
||||
if (user()->gold < $item["buycost"]) {
|
||||
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'];
|
||||
$current_equipped_id = $userrow[$type_to_row_mapping[$item['type']] ?? 0];
|
||||
$current_equipped_id = user()[$type_to_row_mapping[$item['type']] ?? 0];
|
||||
|
||||
if ($current_equipped_id != 0) {
|
||||
$item2 = get_item($current_equipped_id);
|
||||
|
@ -132,16 +126,14 @@ function buy3($id)
|
|||
|
||||
if (isset($_POST["cancel"])) redirect('/');
|
||||
|
||||
global $userrow;
|
||||
|
||||
$townrow = get_town_by_xy($userrow['longitude'], $userrow['latitude']);
|
||||
$townrow = get_town_by_xy(user()->longitude, user()->latitude);
|
||||
if ($townrow === false) display("Cheat attempt detected.<br><br>Get a life, loser.", "Error");
|
||||
$townitems = explode(",", $townrow["itemslist"]);
|
||||
if (!in_array($id, $townitems)) display("Cheat attempt detected.<br><br>Get a life, loser.", "Error");
|
||||
|
||||
$item = get_item($id);
|
||||
|
||||
if ($userrow["gold"] < $item["buycost"]) {
|
||||
if (user()->gold < $item["buycost"]) {
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -157,7 +149,7 @@ function buy3($id)
|
|||
}
|
||||
|
||||
// Retrieve current equipped item or create a default
|
||||
$current_equip_id = $userrow[$type_mapping[$item["type"]]['id']];
|
||||
$current_equip_id = user()[$type_mapping[$item["type"]]['id']];
|
||||
if ($current_equip_id != 0) {
|
||||
$item2 = get_item($current_equip_id);
|
||||
} else {
|
||||
|
@ -175,9 +167,9 @@ function buy3($id)
|
|||
$toChange = $special[0];
|
||||
$changeAmount = $index === 0 ? $special[1] : -$special[1];
|
||||
|
||||
$userrow[$toChange] += $changeAmount;
|
||||
user()[$toChange] += $changeAmount;
|
||||
$specialFields[] = "$toChange = ?";
|
||||
$specialValues[] = $userrow[$toChange];
|
||||
$specialValues[] = user()[$toChange];
|
||||
|
||||
// Adjust attack or defense power
|
||||
if ($toChange == "strength" || $toChange == "dexterity") {
|
||||
|
@ -190,15 +182,15 @@ function buy3($id)
|
|||
// Determine power and type-specific updates
|
||||
$currentType = $type_mapping[$item["type"]];
|
||||
$powerField = $currentType['power'];
|
||||
$newPower = $userrow[$powerField] + $item["attribute"] - $item2["attribute"];
|
||||
$newPower = user()[$powerField] + $item["attribute"] - $item2["attribute"];
|
||||
|
||||
// Calculate new gold with trade-in value
|
||||
$newGold = $userrow["gold"] + ceil($item2["buycost"]/2) - $item["buycost"];
|
||||
$newGold = user()->gold + ceil($item2["buycost"]/2) - $item["buycost"];
|
||||
|
||||
// Ensure current HP/MP/TP don't exceed max values
|
||||
$newhp = min($userrow["currenthp"], $userrow["maxhp"]);
|
||||
$newmp = min($userrow["currentmp"], $userrow["maxmp"]);
|
||||
$newtp = min($userrow["currenttp"], $userrow["maxtp"]);
|
||||
$newhp = min(user()->currenthp, user()->maxhp);
|
||||
$newmp = min(user()->currentmp, user()->maxmp);
|
||||
$newtp = min(user()->currenttp, user()->maxtp);
|
||||
|
||||
$updateFields = array_merge(
|
||||
$specialFields,
|
||||
|
@ -223,7 +215,7 @@ function buy3($id)
|
|||
$newhp,
|
||||
$newmp,
|
||||
$newtp,
|
||||
$userrow["id"]
|
||||
user()->id
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -238,9 +230,7 @@ function buy3($id)
|
|||
*/
|
||||
function maps()
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
$mappedtowns = explode(",", $userrow["towns"]);
|
||||
$mappedtowns = explode(",", user()->towns);
|
||||
|
||||
$page = "Buying maps will put the town in your Travel To box, and it won't cost you as many TP to get there.<br><br>\n";
|
||||
$page .= "Click a town name to purchase its map.<br><br>\n";
|
||||
|
@ -272,11 +262,9 @@ function maps()
|
|||
*/
|
||||
function maps2($id)
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
$townrow = get_town_by_id($id);
|
||||
|
||||
if ($userrow["gold"] < $townrow["mapprice"]) {
|
||||
if (user()->gold < $townrow["mapprice"]) {
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -292,18 +280,16 @@ function maps3($id)
|
|||
{
|
||||
if (isset($_POST["cancel"])) redirect('/');
|
||||
|
||||
global $userrow;
|
||||
|
||||
$townrow = get_town_by_id($id);
|
||||
|
||||
if ($userrow["gold"] < $townrow["mapprice"]) {
|
||||
if (user()->gold < $townrow["mapprice"]) {
|
||||
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";
|
||||
$newgold = $userrow["gold"] - $townrow["mapprice"];
|
||||
$mappedtowns = user()->towns.",$id";
|
||||
$newgold = user()->gold - $townrow["mapprice"];
|
||||
|
||||
db()->query('UPDATE users SET towns=?, gold=? WHERE id=?;', [$mappedtowns, $newgold, $userrow['id']]);
|
||||
db()->query('UPDATE users SET towns=?, gold=? WHERE id=?;', [$mappedtowns, $newgold, user()->id]);
|
||||
|
||||
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");
|
||||
}
|
||||
|
@ -313,32 +299,30 @@ function maps3($id)
|
|||
*/
|
||||
function travelto($id, bool $usepoints = true)
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
if ($userrow["currentaction"] == "Fighting") redirect('/fight');
|
||||
if (user()->currentaction == "Fighting") redirect('/fight');
|
||||
|
||||
$townrow = get_town_by_id($id);
|
||||
|
||||
if ($usepoints) {
|
||||
if ($userrow["currenttp"] < $townrow["travelpoints"]) {
|
||||
if (user()->currenttp < $townrow["travelpoints"]) {
|
||||
display("You do not have enough TP to travel here. Please go back and try again when you get more TP.", "Travel To");
|
||||
}
|
||||
$mapped = explode(",",$userrow["towns"]);
|
||||
$mapped = explode(",",user()->towns);
|
||||
if (!in_array($id, $mapped)) { display("Cheat attempt detected.<br><br>Get a life, loser.", "Error"); }
|
||||
}
|
||||
|
||||
if (($userrow["latitude"] == $townrow["latitude"]) && ($userrow["longitude"] == $townrow["longitude"])) {
|
||||
if ((user()->latitude == $townrow["latitude"]) && (user()->longitude == $townrow["longitude"])) {
|
||||
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"];
|
||||
$newtp = ($usepoints) ? user()->currenttp - $townrow["travelpoints"] : user()->currenttp;
|
||||
|
||||
$newlat = $townrow["latitude"];
|
||||
$newlon = $townrow["longitude"];
|
||||
$newid = $userrow["id"];
|
||||
$newid = user()->id;
|
||||
|
||||
// If they got here by exploring, add this town to their map.
|
||||
$mapped = explode(",",$userrow["towns"]);
|
||||
$mapped = explode(",",user()->towns);
|
||||
$town = false;
|
||||
foreach($mapped as $b) if ($b == $id) $town = true;
|
||||
$mapped = implode(",", $mapped);
|
||||
|
|
|
@ -21,6 +21,8 @@ function register_routes(Router $r): Router
|
|||
*/
|
||||
function login()
|
||||
{
|
||||
global $auth;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$form = validate($_POST, [
|
||||
'username' => ['length:3-18', 'alpha-spaces'],
|
||||
|
@ -33,11 +35,8 @@ function login()
|
|||
}
|
||||
|
||||
$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']))
|
||||
$row = get_user($form['username']);
|
||||
if ($row === false || !$auth->login($form['username'], $form['password']))
|
||||
die("Invalid username or password. Please go back and try again.");
|
||||
|
||||
$expiretime = $form['remember'] ? time() + 31536000 : 0;
|
||||
|
@ -56,6 +55,8 @@ function login()
|
|||
*/
|
||||
function logout()
|
||||
{
|
||||
global $auth;
|
||||
$auth->logout();
|
||||
set_cookie("dkgame", "", -3600);
|
||||
redirect('/login');
|
||||
}
|
||||
|
@ -186,8 +187,6 @@ function changepassword()
|
|||
|
||||
function settings()
|
||||
{
|
||||
global $userrow;
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$form = validate($_POST, [
|
||||
'game_skin' => ['in:0,1']
|
||||
|
@ -195,7 +194,8 @@ function settings()
|
|||
if (!$form['valid']) exit(ul_from_validate_errors($form['errors']));
|
||||
$form = $form['data'];
|
||||
|
||||
db()->query('UPDATE users SET game_skin=? WHERE id=?;', [$form['game_skin'], $userrow['id']]);
|
||||
user()->game_skin = $form['game_skin'];
|
||||
user()->save();
|
||||
|
||||
$alert = '<div class="alert">Settings updated</div>';
|
||||
display($alert . render('settings'), "Account Settings");
|
||||
|
|
104
src/auth.php
Normal file
104
src/auth.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
This is an experimental new class for handling user auth. The idea is to rely as much as possible on PHP's native
|
||||
session handling. When authenticated, the class will store use data in GLOBALS state.
|
||||
*/
|
||||
|
||||
class Auth
|
||||
{
|
||||
/**
|
||||
* Set up the auth manager; adjust PHP session settings on the fly to improve security. Starts the session for
|
||||
* this request.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// enhance the native session's sessid cryptography
|
||||
ini_set('session.sid_length', 64);
|
||||
ini_set('session.sid_bits_per_character', 6);
|
||||
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 2592000, // 30 days
|
||||
'path' => '/',
|
||||
'secure' => true,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict'
|
||||
]);
|
||||
|
||||
session_start();
|
||||
|
||||
$this->validate();
|
||||
}
|
||||
|
||||
private function validate(): void
|
||||
{
|
||||
// Check for IP address change
|
||||
if (!isset($_SESSION['ip_address'])) {
|
||||
$_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
|
||||
} elseif ($_SESSION['ip_address'] !== $_SERVER['REMOTE_ADDR']) {
|
||||
$this->destroy(); // Possible hijacking
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check for User-Agent change
|
||||
if (!isset($_SESSION['user_agent'])) {
|
||||
$_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
|
||||
} elseif ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
|
||||
$this->destroy(); // Possible hijacking
|
||||
exit;
|
||||
}
|
||||
|
||||
// Regenerate session ID periodically for security
|
||||
if (!isset($_SESSION['last_regeneration'])) {
|
||||
$_SESSION['last_regeneration'] = time();
|
||||
} elseif (time() - $_SESSION['last_regeneration'] > 300) { // Every 5 minutes
|
||||
$this->regenerate();
|
||||
}
|
||||
}
|
||||
|
||||
public function login(string $username, string $password): bool
|
||||
{
|
||||
$user = get_user($username);
|
||||
if ($user === false) return false;
|
||||
|
||||
if (password_verify($password, $user['password'])) {
|
||||
$_SESSION['authenticated'] = true;
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['login_time'] = time();
|
||||
|
||||
$this->regenerate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function good(): bool
|
||||
{
|
||||
return isset($_SESSION['authenticated']) && $_SESSION['authenticated'] === true;
|
||||
}
|
||||
|
||||
public function logout(): void
|
||||
{
|
||||
$this->destroy();
|
||||
}
|
||||
|
||||
private function regenerate(): void
|
||||
{
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['last_regeneration'] = time();
|
||||
}
|
||||
|
||||
public function destroy(): void
|
||||
{
|
||||
$_SESSION = [];
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require_once 'lib.php';
|
||||
require_once 'router.php';
|
||||
require_once 'auth.php';
|
||||
require_once 'mail.php';
|
||||
require_once 'actions/explore.php';
|
||||
require_once 'actions/heal.php';
|
||||
|
@ -12,11 +13,14 @@ require_once 'actions/fight.php';
|
|||
require_once 'actions/forum.php';
|
||||
require_once 'actions/install.php';
|
||||
require_once 'actions/admin.php';
|
||||
require_once 'models/model.php';
|
||||
require_once 'models/user.php';
|
||||
|
||||
env_load('../.env');
|
||||
|
||||
$uri = uri();
|
||||
$GLOBALS['cache'] = [];
|
||||
$GLOBALS['state'] = [];
|
||||
|
||||
if (!file_exists('../.installed') && $uri[0] !== 'install') {
|
||||
redirect('/install');
|
||||
|
@ -29,24 +33,26 @@ if (!file_exists('../.installed') && $uri[0] !== 'install') {
|
|||
display("The game is currently closed for maintanence. Please check back later.", "Game Closed");
|
||||
}
|
||||
|
||||
$auth = new Auth;
|
||||
|
||||
// Login (or verify) if not logged in.
|
||||
if (($userrow = checkcookies()) === false) {
|
||||
if (user() === false) {
|
||||
if (!in_array($uri[0], ['login', 'register', 'verify', 'lostpassword', 'help'])) {
|
||||
redirect('/login');
|
||||
}
|
||||
} else {
|
||||
// Block user if he/she has been banned.
|
||||
if ($userrow["authlevel"] === 2) {
|
||||
if (user()->authlevel === 2) {
|
||||
exit("Your account has been banned.");
|
||||
}
|
||||
|
||||
// Force verify if the user isn't verified yet.
|
||||
if ($controlrow['verifyemail'] && $userrow['verify'] !== 'g2g' && !in_array($uri[0], ['verify', 'logout'])) {
|
||||
if ($controlrow['verifyemail'] && user()->verify !== 'g2g' && !in_array($uri[0], ['verify', 'logout'])) {
|
||||
redirect('/verify');
|
||||
}
|
||||
|
||||
// Ensure the user can't use the admin panel.
|
||||
if ($userrow['authlevel'] !== 1 && $uri[0] === 'admin') {
|
||||
if (user()->authlevel !== 1 && $uri[0] === 'admin') {
|
||||
redirect('/');
|
||||
}
|
||||
}
|
||||
|
|
89
src/lib.php
89
src/lib.php
|
@ -99,10 +99,10 @@ function display_admin($content, $title)
|
|||
*/
|
||||
function display($content, $title, bool $topnav = true, bool $leftnav = true, bool $rightnav = true): void
|
||||
{
|
||||
global $userrow, $controlrow;
|
||||
global $controlrow;
|
||||
|
||||
if ($topnav == true) {
|
||||
if ($userrow !== false) { // user should be logged in
|
||||
if (user() !== false) { // user should be logged in
|
||||
$topnav = <<<HTML
|
||||
<a href='/logout'><img src='/img/button_logout.gif' alt='Log Out' title='Log Out'></a>
|
||||
<a href='/help'><img src='/img/button_help.gif' alt='Help' title='Help'></a>
|
||||
|
@ -118,75 +118,60 @@ function display($content, $title, bool $topnav = true, bool $leftnav = true, bo
|
|||
$topnav = '';
|
||||
}
|
||||
|
||||
if (isset($userrow) && $userrow !== false) {
|
||||
|
||||
// Get userrow again, in case something has been updated.
|
||||
$userquery = db()->query('SELECT * FROM users WHERE id = ? LIMIT 1;', [$userrow['id']]);
|
||||
unset($userrow);
|
||||
$userrow = $userquery->fetchArray(SQLITE3_ASSOC);
|
||||
|
||||
// Current town name.
|
||||
if ($userrow['currentaction'] == 'In Town') {
|
||||
$townrow = get_town_by_xy($userrow['latitude'], $userrow['longitude']);
|
||||
$userrow['currenttown'] = "Welcome to <b>{$townrow['name']}</b>.<br><br>";
|
||||
if (user() !== false) {
|
||||
if (user()->currentaction == 'In Town') {
|
||||
$town = get_town_by_xy(user()->latitude, user()->longitude);
|
||||
$current_town = "Welcome to <b>{$town['name']}</b>.<br><br>";
|
||||
} else {
|
||||
$userrow['currenttown'] = '';
|
||||
$current_town = '';
|
||||
}
|
||||
|
||||
$userrow['forumslink'] = '<a href="/forum">Forum</a><br>';
|
||||
|
||||
// Format various userrow stuffs...
|
||||
if ($userrow["latitude"] < 0) { $userrow["latitude"] = $userrow["latitude"] * -1 . "S"; } else { $userrow["latitude"] .= "N"; }
|
||||
if ($userrow["longitude"] < 0) { $userrow["longitude"] = $userrow["longitude"] * -1 . "W"; } else { $userrow["longitude"] .= "E"; }
|
||||
$userrow["experience"] = number_format($userrow["experience"]);
|
||||
$userrow["gold"] = number_format($userrow["gold"]);
|
||||
if ($userrow["authlevel"] == 1) { $userrow["adminlink"] = "<a href=\"/admin\">Admin</a><br>"; } else { $userrow["adminlink"] = ""; }
|
||||
|
||||
// HP/MP/TP bars.
|
||||
$userrow['statbars'] = create_stat_table($userrow);
|
||||
if (user()->latitude < 0) { user()->latitude = user()->latitude * -1 . "S"; } else { user()->latitude .= "N"; }
|
||||
if (user()->longitude < 0) { user()->longitude = user()->longitude * -1 . "W"; } else { user()->longitude .= "E"; }
|
||||
user()->experience = number_format(user()->experience);
|
||||
user()->gold = number_format(user()->gold);
|
||||
|
||||
// Now make numbers stand out if they're low.
|
||||
if ($userrow["currenthp"] <= ($userrow["maxhp"]/5)) { $userrow["currenthp"] = "<blink><span class=\"highlight\"><b>*".$userrow["currenthp"]."*</b></span></blink>"; }
|
||||
if ($userrow["currentmp"] <= ($userrow["maxmp"]/5)) { $userrow["currentmp"] = "<blink><span class=\"highlight\"><b>*".$userrow["currentmp"]."*</b></span></blink>"; }
|
||||
if (user()->currenthp <= (user()->maxhp/5)) { user()->currenthp = "<blink><span class=\"highlight\"><b>*".user()->currenthp."*</b></span></blink>"; }
|
||||
if (user()->currentmp <= (user()->maxmp/5)) { user()->currentmp = "<blink><span class=\"highlight\"><b>*".user()->currentmp."*</b></span></blink>"; }
|
||||
|
||||
$user_spells = explode(',', $userrow['spells']);
|
||||
$user_spells = explode(',', user()->spells);
|
||||
$spellquery = get_spells_from_list($user_spells);
|
||||
$userrow['magiclist'] = '';
|
||||
user()->magiclist = '';
|
||||
while ($spell = $spellquery->fetchArray(SQLITE3_ASSOC)) {
|
||||
$spell = false;
|
||||
foreach($user_spells as $id) {
|
||||
if ($id === $spell['id'] && $spell['type'] == 1) $spell = true;
|
||||
}
|
||||
if ($spell == true) {
|
||||
$userrow['magiclist'] .= "<a href=\"/spell/{$spell['id']}\">".$spell['name']."</a><br>";
|
||||
user()->magiclist .= "<a href=\"/spell/{$spell['id']}\">".$spell['name']."</a><br>";
|
||||
}
|
||||
}
|
||||
if ($userrow["magiclist"] == "") { $userrow["magiclist"] = "None"; }
|
||||
if (user()->magiclist == "") { user()->magiclist = "None"; }
|
||||
|
||||
// Travel To list.
|
||||
$townslist = explode(",",$userrow["towns"]);
|
||||
$townslist = explode(",",user()->towns);
|
||||
$townquery2 = db()->query('SELECT * FROM towns ORDER BY id;');
|
||||
$userrow["townslist"] = "";
|
||||
$town_list_html = '';
|
||||
while ($townrow2 = $townquery2->fetchArray(SQLITE3_ASSOC)) {
|
||||
$town = false;
|
||||
foreach($townslist as $a => $b) {
|
||||
if ($b == $townrow2["id"]) { $town = true; }
|
||||
foreach($townslist as $id) {
|
||||
if ($id == $townrow2["id"]) { $town = true; }
|
||||
}
|
||||
if ($town == true) {
|
||||
$userrow["townslist"] .= "<a href=\"/gotown/{$townrow2["id"]}\">".$townrow2["name"]."</a><br>\n";
|
||||
$town_list_html .= "<a href=\"/gotown/{$townrow2["id"]}\">".$townrow2["name"]."</a><br>\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$userrow = [];
|
||||
}
|
||||
|
||||
echo render('primary', [
|
||||
"dkgamename" => $controlrow["gamename"],
|
||||
"title" => $title,
|
||||
"content" => $content,
|
||||
"game_skin" => $userrow['game_skin'] ??= '0',
|
||||
'rightnav' => $rightnav ? render('rightnav', ['user' => $userrow]) : '',
|
||||
"leftnav" => $leftnav ? render('leftnav', ['user' => $userrow]) : '',
|
||||
"game_skin" => user()->game_skin ??= '0',
|
||||
'rightnav' => $rightnav ? render('rightnav', ['statbars' => create_stat_table(user())]) : '',
|
||||
"leftnav" => $leftnav ? render('leftnav', ['town_list' => $town_list_html, 'current_town' => $current_town]) : '',
|
||||
"topnav" => $topnav,
|
||||
"totaltime" => round(microtime(true) - START, 4),
|
||||
"numqueries" => db()->count,
|
||||
|
@ -271,11 +256,14 @@ function get_town_by_id(int $id): array|false
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a user's data by their ID.
|
||||
* Get a user's data by their ID, username or email.
|
||||
*/
|
||||
function get_user_by_id(int $id): array|false
|
||||
function get_user(int|string $id, string $data = '*'): array|false
|
||||
{
|
||||
$query = db()->query('SELECT * FROM users WHERE id = ? LIMIT 1;', [$id]);
|
||||
$query = db()->query(
|
||||
"SELECT $data FROM users WHERE id=? OR username=? COLLATE NOCASE OR email=? COLLATE NOCASE LIMIT 1;",
|
||||
[$id, $id, $id]
|
||||
);
|
||||
if ($query === false) return false;
|
||||
return $query->fetchArray(SQLITE3_ASSOC);
|
||||
}
|
||||
|
@ -610,11 +598,20 @@ function create_stat_table($userrow)
|
|||
{
|
||||
$stat_table = '<div class="stat-table">' .
|
||||
'<div class="stat-row">' .
|
||||
'<div class="stat-col">' . generate_stat_bar($userrow['currenthp'], $userrow['maxhp']) . '<div>HP</div></div>' .
|
||||
'<div class="stat-col">' . generate_stat_bar($userrow['currentmp'], $userrow['maxmp']) . '<div>MP</div></div>' .
|
||||
'<div class="stat-col">' . generate_stat_bar($userrow['currenttp'], $userrow['maxtp']) . '<div>TP</div></div>' .
|
||||
'<div class="stat-col">' . generate_stat_bar(user()->currenthp, user()->maxhp) . '<div>HP</div></div>' .
|
||||
'<div class="stat-col">' . generate_stat_bar(user()->currentmp, user()->maxmp) . '<div>MP</div></div>' .
|
||||
'<div class="stat-col">' . generate_stat_bar(user()->currenttp, user()->maxtp) . '<div>TP</div></div>' .
|
||||
'</div>' .
|
||||
'</div>';
|
||||
|
||||
return $stat_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user in the GLOBALS state, if there is one. If not, populates it if there is a SESSION user_id.
|
||||
*/
|
||||
function user(): User|false
|
||||
{
|
||||
$GLOBALS['state']['user'] ??= ($_SESSION['user_id'] ? User::find($_SESSION['user_id']) : false);
|
||||
return $GLOBALS['state']['user'];
|
||||
}
|
||||
|
|
42
src/models/model.php
Normal file
42
src/models/model.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
class Model
|
||||
{
|
||||
protected string $table_name = '';
|
||||
protected array $original_data = [];
|
||||
protected array $changes = [];
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->original_data = $data;
|
||||
$this->changes = [];
|
||||
}
|
||||
|
||||
public function __get(string $key): mixed
|
||||
{
|
||||
return array_key_exists($key, $this->changes) ? $this->changes[$key] : $this->original_data[$key] ?? false;
|
||||
}
|
||||
|
||||
public function __set(string $key, mixed $value): void
|
||||
{
|
||||
if (array_key_exists($key, $this->original_data)) $this->changes[$key] = $value;
|
||||
}
|
||||
|
||||
public function save(): bool
|
||||
{
|
||||
if (empty($this->changes)) return true;
|
||||
|
||||
$placeholders = [];
|
||||
$values = [];
|
||||
foreach ($this->changes as $key => $value) {
|
||||
$placeholders[] = "$key=?";
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
$values[] = $this->id;
|
||||
$query = 'UPDATE ' . $this->table_name . ' SET ' . implode(', ', $placeholders) . ' WHERE id = ?;';
|
||||
|
||||
$result = db()->query($query, $values);
|
||||
return $result === false ? false : true;
|
||||
}
|
||||
}
|
21
src/models/user.php
Normal file
21
src/models/user.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
protected string $table_name = 'users';
|
||||
|
||||
/**
|
||||
* Find a user by their ID, username or email. Returns false on any failure.
|
||||
*/
|
||||
public static function find(int|string $id): User|false
|
||||
{
|
||||
$query = db()->query(
|
||||
"SELECT * FROM users WHERE id=? OR username=? COLLATE NOCASE OR email=? COLLATE NOCASE LIMIT 1;",
|
||||
[$id, $id, $id]
|
||||
);
|
||||
if ($query === false) return false;
|
||||
$data = $query->fetchArray(SQLITE3_ASSOC);
|
||||
if ($data === false) return false;
|
||||
return new User($data);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<section>
|
||||
<div class="title"><img src="/img/button_location.gif" alt="Location" title="Location"></div>
|
||||
Currently: <?= $user['currentaction'] ?><br>
|
||||
Latitude: <?= $user['latitude'] ?><br>
|
||||
Longitude: <?= $user['longitude'] ?><br>
|
||||
Currently: <?= user()->currentaction ?><br>
|
||||
Latitude: <?= user()->latitude ?><br>
|
||||
Longitude: <?= user()->longitude ?><br>
|
||||
<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>
|
||||
|
@ -16,18 +16,25 @@
|
|||
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_towns.gif" alt="Towns" title="Towns"></div>
|
||||
<?= $user['currenttown'] ?>
|
||||
<?php
|
||||
if (user()->currentaction == 'In Town') {
|
||||
$town = get_town_by_xy((int) user()->latitude, (int) user()->longitude);
|
||||
echo "Welcome to <b>{$town['name']}</b>.<br><br>";
|
||||
}
|
||||
?>
|
||||
Travel To:<br>
|
||||
<?= $user['townslist'] ?>
|
||||
<?= $town_list ?>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="title"><img src="/img/button_functions.gif" alt="Functions" title="Functions"></div>
|
||||
<a href="/">Home</a><br>
|
||||
<?= $user['forumslink'] ?>
|
||||
<?= $user['adminlink'] ?>
|
||||
<a href="/forum">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>
|
||||
</section>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<section>
|
||||
<div class="title"><img src="/img/button_character.gif" alt="Character" title="Character"></div>
|
||||
<b><?= $user['username'] ?></b><br>
|
||||
Level: <?= $user['level'] ?><br>
|
||||
Exp: <?= $user['experience'] ?><br>
|
||||
Gold: <?= $user['gold'] ?><br>
|
||||
HP: <?= $user['currenthp'] ?><br>
|
||||
MP: <?= $user['currentmp'] ?><br>
|
||||
TP: <?= $user['currenttp'] ?><br><br>
|
||||
<?= $user['statbars'] ?><br>
|
||||
<b><?= user()->username ?></b><br>
|
||||
Level: <?= user()->level ?><br>
|
||||
Exp: <?= user()->experience ?><br>
|
||||
Gold: <?= user()->gold ?><br>
|
||||
HP: <?= user()->currenthp ?><br>
|
||||
MP: <?= user()->currentmp ?><br>
|
||||
TP: <?= user()->currenttp ?><br><br>
|
||||
<?= $statbars ?><br>
|
||||
<a href="javascript:opencharpopup()">Extended Stats</a>
|
||||
</section>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user