uri(1) ?? ''; // second segment $m = App::$req->method; // request method if ($s == '' || $s == 'intro') return self::intro(); if ($s == 'database' && $m == 'POST') return self::database(); if ($s == 'finish' && $m == 'POST') return self::finish(); return self::fourOhFour(); } private static function intro() { echo render('install/layout', ['title' => 'Intro', 'step' => 'first']); } private static function database() { $istart = microtime(true); // time the database setup if (!isset($_POST['mode'])) redirect('/install'); // redirect if no mode $complete = $_POST['mode'] == 'complete'; // complete or partial setup $defaults = SERVER.'/database/packs/Default/'; // if the database already exists, have the app remake it App::performDatabaseReset(); // @Settings App::$db->q("CREATE TABLE IF NOT EXISTS 'settings' ( 'id' INTEGER PRIMARY KEY, 'game_name' TEXT DEFAULT 'Dragon Knight', 'game_version' TEXT DEFAULT '1.0', 'game_dev' TEXT DEFAULT 'Sharkk', 'game_url' TEXT DEFAULT 'https://dragonknight.dev', 'game_size' INT DEFAULT 250, 'game_open' INT DEFAULT 1, 'admin_email' TEXT DEFAULT 'admin@dragonknight.dev', 'forum_type' INT DEFAULT 1, 'forum_url' TEXT DEFAULT '', 'verify_email' INT DEFAULT 1, 'show_news' INT DEFAULT 1, 'show_online' INT DEFAULT 1, 'show_babble' INT DEFAULT 1 );"); // insert default settings App::$db->q("INSERT INTO settings DEFAULT VALUES;"); // @Classes App::$db->q("CREATE TABLE IF NOT EXISTS 'classes' ( 'id' INTEGER PRIMARY KEY, 'name' TEXT DEFAULT '', 'start_hp' INT DEFAULT 0, 'start_mp' INT DEFAULT 0, 'start_str' INT DEFAULT 0, 'start_atk' INT DEFAULT 0, 'start_dex' INT DEFAULT 0, 'start_def' INT DEFAULT 0, 'growth_hp' INT DEFAULT 0, 'growth_mp' INT DEFAULT 0, 'growth_str' INT DEFAULT 0, 'growth_atk' INT DEFAULT 0, 'growth_dex' INT DEFAULT 0, 'growth_def' INT DEFAULT 0, 'spells' TEXT DEFAULT '' );"); if ($complete) { // add default classes if complete install App::$db->insertFromCSV('classes', "$defaults/classes.csv"); } else { // there must be at least one class for user creation to work App::$db->q("INSERT INTO classes (name) VALUES ('Adventurer');"); } // @Babble App::$db->q("CREATE TABLE IF NOT EXISTS 'babble' ( 'id' INTEGER PRIMARY KEY, 'author' INTEGER NOT NULL, 'babble' TEXT NOT NULL, 'posted' DATETIME DEFAULT CURRENT_TIMESTAMP );"); // @Drops App::$db->q("CREATE TABLE IF NOT EXISTS 'drops' ( 'id' INTEGER PRIMARY KEY, 'name' TEXT NOT NULL, 'level' INTEGER DEFAULT 1, 'type' INTEGER DEFAULT 1, 'attr' TEXT DEFAULT '' );"); // add default drops if complete install if ($complete) App::$db->insertFromCSV('drops', "$defaults/drops.csv"); // @Forum App::$db->q("CREATE TABLE IF NOT EXISTS 'forum' ( 'id' INTEGER PRIMARY KEY, 'posted' DATETIME DEFAULT CURRENT_TIMESTAMP, 'new_post' DATETIME DEFAULT CURRENT_TIMESTAMP, 'author' INTEGER NOT NULL, 'subject' TEXT DEFAULT '', 'message' TEXT DEFAULT '', 'locked' INTEGER DEFAULT 0, 'sticky' INTEGER DEFAULT 0, 'parent' INTEGER DEFAULT 0, 'posts' INTEGER DEFAULT 0, 'views' INTEGER DEFAULT 0, 'hidden' INTEGER DEFAULT 0 );"); // @Items App::$db->q("CREATE TABLE IF NOT EXISTS 'items' ( 'id' INTEGER PRIMARY KEY, 'type' INTEGER DEFAULT 1, 'name' TEXT NOT NULL, 'cost' INTEGER DEFAULT 0, 'attr' TEXT DEFAULT '', 'icon' TEXT DEFAULT '' );"); // add default items if complete install if ($complete) App::$db->insertFromCSV('items', "$defaults/items.csv"); // @Monsters App::$db->q("CREATE TABLE IF NOT EXISTS 'monsters' ( 'id' INTEGER PRIMARY KEY, 'name' TEXT NOT NULL, 'level' INTEGER DEFAULT 1, 'hp' INTEGER DEFAULT 1, 'atk' INTEGER DEFAULT 1, 'def' INTEGER DEFAULT 1, 'exp' INTEGER DEFAULT 1, 'gold' INTEGER DEFAULT 1, 'immune' INTEGER DEFAULT 0, 'image' TEXT DEFAULT '' );"); // add default monsters if complete install if ($complete) App::$db->insertFromCSV('monsters', "$defaults/monsters.csv"); // @News App::$db->q("CREATE TABLE IF NOT EXISTS 'news' ( 'id' INTEGER PRIMARY KEY, 'author' INTEGER DEFAULT 1, 'title' TEXT DEFAULT '', 'content' TEXT DEFAULT '', 'posted' DATETIME DEFAULT CURRENT_TIMESTAMP );"); // @Spells App::$db->q("CREATE TABLE IF NOT EXISTS 'spells' ( 'id' INTEGER PRIMARY KEY, 'name' TEXT NOT NULL, 'type' INTEGER DEFAULT 1, 'mp' INTEGER DEFAULT 0, 'effect' TEXT DEFAULT '', 'icon' TEXT DEFAULT '' );"); // add default spells if complete install if ($complete) App::$db->insertFromCSV('spells', "$defaults/spells.csv"); // @Towns App::$db->q("CREATE TABLE IF NOT EXISTS 'towns' ( 'id' INTEGER PRIMARY KEY, 'name' TEXT NOT NULL, 'x' INTEGER DEFAULT 0, 'y' INTEGER DEFAULT 0, 'inn_cost' INTEGER DEFAULT 0, 'map_cost' INTEGER DEFAULT 5, 'tp_cost' INTEGER DEFAULT 0, 'shop_list' TEXT DEFAULT '', 'image' TEXT DEFAULT '' );"); // add default towns if complete install if ($complete) App::$db->insertFromCSV('towns', "$defaults/towns.csv"); // @Players App::$db->q("CREATE TABLE IF NOT EXISTS 'players' ( 'id' INTEGER PRIMARY KEY, 'username' TEXT NOT NULL, 'password' TEXT NOT NULL, 'email' TEXT DEFAULT '', 'verified' INTEGER DEFAULT 1, 'registered' DATETIME DEFAULT CURRENT_TIMESTAMP, 'last_online' DATETIME DEFAULT CURRENT_TIMESTAMP, 'currently' INTEGER DEFAULT 0, 'role' INTEGER DEFAULT 1, 'class_id' INTEGER DEFAULT 1, 'level' INTEGER DEFAULT 1, 'exp' INTEGER DEFAULT 0, 'gold' INTEGER DEFAULT 0, 'stat_points' INTEGER DEFAULT 0, 'hp' INTEGER DEFAULT 0, 'max_hp' INTEGER DEFAULT 0, 'mp' INTEGER DEFAULT 0, 'max_mp' INTEGER DEFAULT 0, 'tp' INTEGER DEFAULT 0, 'max_tp' INTEGER DEFAULT 0, 'str' INTEGER DEFAULT 0, 'atk' INTEGER DEFAULT 0, 'dex' INTEGER DEFAULT 0, 'def' INTEGER DEFAULT 0, 'weapon_id' INTEGER DEFAULT 0, 'armor_id' INTEGER DEFAULT 0, 'shield_id' INTEGER DEFAULT 0, 'slot_1_id' INTEGER DEFAULT 0, 'slot_2_id' INTEGER DEFAULT 0, 'slot_3_id' INTEGER DEFAULT 0, 'spells' TEXT DEFAULT '', 'maps' TEXT DEFAULT '' );"); // @Fights App::$db->q("CREATE TABLE IF NOT EXISTS 'fights' ( 'id' INTEGER PRIMARY KEY, 'p_id' INTEGER DEFAULT 1, 'm_id' INTEGER DEFAULT 1, 'turn' INTEGER DEFAULT 1, 'p_hp' INTEGER DEFAULT 0, 'p_maxhp' INTEGER DEFAULT 0, 'p_mp' INTEGER DEFAULT 0, 'p_maxmp' INTEGER DEFAULT 0, 'm_hp' INTEGER DEFAULT 0, 'm_maxhp' INTEGER DEFAULT 0, 'condi' TEXT DEFAULT '' );"); echo render('install/layout', ['title' => 'Database Setup', 'step' => 'second', 'complete' => $complete, 'start' => $istart]); } private static function finish() { $errors = []; // Make sure our info is at least mostly valid if (!required(['username', 'password', 'email'])) { $errors[] = 'All fields are required.'; } else { if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { $errors[] = 'Invalid email address format.'; } if (strlen($_POST['password']) < 6) { $errors[] = 'Password must be at least 6 characters long.'; } } // Make sure the class selection is valid $class = isset($_POST['class']) && in_array($_POST['class'], [1, 2, 3]) ? $_POST['class'] : 1; // If we have any errors, bail to the form and let the user know if (!empty($errors)) { echo render('install/layout', ['title' => 'Admin Account', 'step' => 'third', 'errors' => $errors, 'complete' => $_POST['complete'] ?? false]); exit; } // Create the .installed file in the server folder file_put_contents(SERVER.'/.installed', 'Installed on '.date('Y-m-d H:i:s')); // Create the admin account Player::create([ 'username' => trim($_POST['username']), 'password' => password_hash($_POST['password'], PASSWORD_ARGON2ID), 'email' => trim($_POST['email']), 'class_id' => $class, 'verified' => 1, 'role' => 5 ]); // Render the finished page! echo render('install/layout', ['title' => 'Finished!', 'step' => 'done', 'name' => $_POST['username'], 'complete' => $_POST['complete'] ?? false]); } private static function fourOhFour() { echo render('install/layout', ['title' => 'Four Oh Four', 'step' => 'four']); } }