Compare commits

...

3 Commits

22 changed files with 620 additions and 653 deletions

View File

@ -38,7 +38,23 @@ body {
margin-bottom: 2rem;
}
.my-1 {
margin-top: 1rem;
margin-bottom: 1rem;
}
.my-2 {
margin-top: 2rem;
margin-bottom: 2rem;
}
div.alert {
font-size: 0.9rem;
padding: 0.5rem;
background-color: gray;
&.is-danger {
color: hsl(359deg, 68%, 11%);
background-color: hsl(359deg, 68%, 71%);
}
}

View File

@ -1,554 +0,0 @@
<?php // install.php :: creates/populates database tables on a new installation.
const SERVER = '../../server';
require_once SERVER.'/bootstrap.php';
if (installed()) redirect('/');
$db = new Database(DB);
// Define our pages and whitelist the request
const STEPS = ['first', 'second', 'third'];
$step = isset($_GET['step']) && in_array($_GET['step'], STEPS) ? $_GET['step'] : 'first';
// Introduction; offer the user two options for installation;
// Complete: all default data
// Partial: no default data
if ($step == 'first') {
echo render('install/layout', ['title' => 'Intro', 'step' => 'first']);
exit;
}
// Database setup; create tables and default data (if requested)
if ($step == 'second') {
$istart = microtime(true); // time the database setup
if (!required(['mode'])) redirect('/install/'); // dont run step two if a button wasnt clicked
$complete = $_POST['mode'] == 'complete'; // complete or partial setup
// Create Control table
$db->table('control')->create([
'id INTEGER PRIMARY KEY',
"game_name TEXT DEFAULT 'Dragon Knight'",
'game_size INTEGER DEFAULT 250',
'game_open INTEGER DEFAULT 1',
"admin_email TEXT DEFAULT ''",
'forum_type INTEGER DEFAULT 1',
"forum_addr TEXT DEFAULT ''",
'verify_email INTEGER DEFAULT 1',
'show_news INTEGER DEFAULT 1',
'show_online INTEGER DEFAULT 1',
'show_babble INTEGER DEFAULT 1'
]);
// Insert default control row
$db->insertDefaultValues();
// Create classes table
$db->table('classes')->create([
'id INTEGER PRIMARY KEY',
'name TEXT NOT NULL',
'start_hp INTEGER DEFAULT 0',
'start_mp INTEGER DEFAULT 0',
'start_str INTEGER DEFAULT 0',
'start_atk INTEGER DEFAULT 0',
'start_def INTEGER DEFAULT 0',
'start_dex INTEGER DEFAULT 0',
'growth_hp INTEGER DEFAULT 0',
'growth_mp INTEGER DEFAULT 0',
'growth_str INTEGER DEFAULT 0',
'growth_atk INTEGER DEFAULT 0',
'growth_def INTEGER DEFAULT 0',
'growth_dex INTEGER DEFAULT 0',
"spells TEXT DEFAULT ''"
]);
// Add default classes if complete install
if ($complete) {
$db->insert([
['name' => 'Mage', 'start_hp' => 10, 'start_mp' => 10, 'start_str' => 5, 'start_atk' => 5, 'start_def' => 5, 'start_dex' => 5, 'growth_hp' => 3, 'growth_mp' => 5, 'growth_str' => 1, 'growth_atk' => 3, 'growth_def' => 1, 'growth_dex' => 3, 'spells' => '1:6,18'],
['name' => 'Warrior', 'start_hp' => 20, 'start_mp' => 0, 'start_str' => 10, 'start_atk' => 5, 'start_def' => 10, 'start_dex' => 5, 'growth_hp' => 6, 'growth_mp' => 2, 'growth_str' => 3, 'growth_atk' => 1, 'growth_def' => 3, 'growth_dex' => 1, 'spells' => ''],
['name' => 'Paladin', 'start_hp' => 15, 'start_mp' => 5, 'start_str' => 5, 'start_atk' => 5, 'start_def' => 10, 'start_dex' => 10, 'growth_hp' => 4, 'growth_mp' => 4, 'growth_str' => 2, 'growth_atk' => 2, 'growth_def' => 2, 'growth_dex' => 2, 'spells' => '1:1,15,18']
]);
} else {
// There must be at least one class, for user creation to work
$db->insert(['name' => 'Adventurer']);
}
// Create Babble table
$db->table('babble')->create([
'id INTEGER PRIMARY KEY',
'posted DATETIME DEFAULT CURRENT_TIMESTAMP',
'author INTEGER DEFAULT 1',
'babble TEXT NOT NULL'
]);
// Create Drops table
$db->table('drops')->create([
'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) {
$db->insert([
['name' => 'Life Pebble', 'level' => 1, 'type' => 1, 'attr' => 'hp,10'],
['name' => 'Life Stone', 'level' => 10, 'type' => 1, 'attr' => 'hp,25'],
['name' => 'Life Rock', 'level' => 25, 'type' => 1, 'attr' => 'hp,50'],
['name' => 'Life Ore', 'level' => 50, 'type' => 1, 'attr' => 'hp,100'],
['name' => 'Life Gem', 'level' => 75, 'type' => 1, 'attr' => 'hp,150'],
['name' => 'Magic Pebble', 'level' => 1, 'type' => 1, 'attr' => 'mp,10'],
['name' => 'Magic Stone', 'level' => 10, 'type' => 1, 'attr' => 'mp,25'],
['name' => 'Magic Rock', 'level' => 25, 'type' => 1, 'attr' => 'mp,50'],
['name' => 'Magic Ore', 'level' => 50, 'type' => 1, 'attr' => 'mp,100'],
['name' => 'Magic Gem', 'level' => 75, 'type' => 1, 'attr' => 'mp,150'],
['name' => "Dragon's Scale", 'level' => 10, 'type' => 1, 'attr' => 'def,25'],
['name' => "Dragon's Plate", 'level' => 30, 'type' => 1, 'attr' => 'def,50'],
['name' => "Dragon's Claw", 'level' => 10, 'type' => 1, 'attr' => 'atk,25'],
['name' => "Dragon's Fang", 'level' => 30, 'type' => 1, 'attr' => 'atk,50'],
['name' => "Dragon's Tear", 'level' => 35, 'type' => 1, 'attr' => 'str,75'],
['name' => "Dragon's Wing", 'level' => 35, 'type' => 1, 'attr' => 'dex,75'],
['name' => "Demon's Sin", 'level' => 35, 'type' => 1, 'attr' => 'hp,-50|str,65'],
['name' => "Demon's Fall", 'level' => 35, 'type' => 1, 'attr' => 'mp,-50|str,65'],
['name' => "Demon's Lie", 'level' => 45, 'type' => 1, 'attr' => 'hp,-100|str,125'],
['name' => "Demon's Hate", 'level' => 45, 'type' => 1, 'attr' => 'mp,-100|str,125'],
['name' => "Angel's Joy", 'level' => 25, 'type' => 1, 'attr' => 'hp,25|str,25'],
['name' => "Angel's Rise", 'level' => 30, 'type' => 1, 'attr' => 'hp,50|str,50'],
['name' => "Angel's Truth", 'level' => 35, 'type' => 1, 'attr' => 'hp,75|str,75'],
['name' => "Angel's Grace", 'level' => 40, 'type' => 1, 'attr' => 'hp,100|str,100'],
['name' => "Seraph's Strength", 'level' => 25, 'type' => 1, 'attr' => 'mp,25|dex,25'],
['name' => "Seraph's Power", 'level' => 30, 'type' => 1, 'attr' => 'mp,50|dex,50'],
['name' => "Seraph's Justice", 'level' => 35, 'type' => 1, 'attr' => 'mp,75|dex,75'],
['name' => "Seraph's Judgement", 'level' => 40, 'type' => 1, 'attr' => 'mp,100|dex,100'],
['name' => 'Ruby', 'level' => 50, 'type' => 1, 'attr' => 'hp,150'],
['name' => 'Sapphire', 'level' => 50, 'type' => 1, 'attr' => 'mp,150'],
['name' => 'Emerald', 'level' => 50, 'type' => 1, 'attr' => 'str,150'],
['name' => 'Amethyst', 'level' => 50, 'type' => 1, 'attr' => 'dex,150'],
['name' => 'Topaz', 'level' => 50, 'type' => 1, 'attr' => 'atk,150'],
['name' => 'Diamond', 'level' => 50, 'type' => 1, 'attr' => 'def,150'],
['name' => "Ocean Blessing", 'level' => 77, 'type' => 1, 'attr' => 'str,7007|dex,7007'],
['name' => 'Memory Tonic', 'level' => 5, 'type' => 1, 'attr' => 'exp,10',],
['name' => 'Memory Potion', 'level' => 30, 'type' => 1, 'attr' => 'exp,20',],
['name' => 'Memory Elixir', 'level' => 50, 'type' => 1, 'attr' => 'exp,30',],
['name' => 'Gold Tonic', 'level' => 5, 'type' => 1, 'attr' => 'gold,10'],
['name' => 'Gold Potion', 'level' => 30, 'type' => 1, 'attr' => 'gold,20'],
['name' => 'Gold Elixir', 'level' => 50, 'type' => 1, 'attr' => 'gold,30'],
]);
}
// Create Forum table
$db->table('forum')->create([
'id INTEGER PRIMARY KEY',
'posted DATETIME DEFAULT CURRENT_TIMESTAMP',
'new_post DATETIME DEFAULT CURRENT_TIMESTAMP',
'author INTEGER DEFAULT 1',
"subject TEXT DEFAULT ''",
"message TEXT DEFAULT ''",
'locked INTEGER DEFAULT 0',
'sticky INTEGER DEFAULT 0',
'parent INTEGER DEFAULT 0'
]);
// Create Items table
$db->table('items')->create([
'id INTEGER PRIMARY KEY',
'type INTEGER DEFAULT 1',
'name TEXT NOT NULL',
'cost INTEGER DEFAULT 0',
"attr TEXT DEFAULT ''",
"icon TEXT DEFAULT ''"
]);
// Create default items, if complete install
if ($complete) {
$db->insert([
// Type 1 - weapons
['type' => 1, 'name' => 'Stick', 'cost' => 10, 'attr' => 'atk,2', 'icon' => 'stick.png' ], // 1
['type' => 1, 'name' => 'Branch', 'cost' => 30, 'attr' => 'atk,4', 'icon' => 'branch.png' ], // 2
['type' => 1, 'name' => 'Club', 'cost' => 40, 'attr' => 'atk,6', 'icon' => 'club.png' ], // 3
['type' => 1, 'name' => 'Dagger', 'cost' => 80, 'attr' => 'atk,8', 'icon' => 'dagger.png' ], // 4
['type' => 1, 'name' => 'Hatchet', 'cost' => 120, 'attr' => 'atk,12', 'icon' => 'hatchet.png' ], // 5
['type' => 1, 'name' => 'Axe', 'cost' => 200, 'attr' => 'atk,18', 'icon' => 'axe.png' ], // 6
['type' => 1, 'name' => 'Spear', 'cost' => 300, 'attr' => 'atk,25', 'icon' => 'spear.png' ], // 7
['type' => 1, 'name' => 'Poleaxe', 'cost' => 500, 'attr' => 'atk,35', 'icon' => 'poleaxe.png' ], // 8
['type' => 1, 'name' => 'Warhammer', 'cost' => 800, 'attr' => 'atk,50', 'icon' => 'warhammer.png' ], // 9
['type' => 1, 'name' => 'Longsword', 'cost' => 1200, 'attr' => 'atk,65', 'icon' => 'longsword.png' ], // 10
['type' => 1, 'name' => 'Claymore', 'cost' => 1800, 'attr' => 'atk,85', 'icon' => 'claymore.png' ], // 11
['type' => 1, 'name' => 'Demon Axe', 'cost' => 2800, 'attr' => 'atk,125|exp,-5', 'icon' => 'demonaxe.png' ], // 12
['type' => 1, 'name' => 'Dark Sword', 'cost' => 4500, 'attr' => 'atk,225|exp,-10', 'icon' => 'darksword.png' ], // 13
['type' => 1, 'name' => 'Magic Axe', 'cost' => 2800, 'attr' => 'atk,95|exp,5', 'icon' => 'magicaxe.png' ], // 14
['type' => 1, 'name' => 'Bright Sword', 'cost' => 4500, 'attr' => 'atk,185|exp,10', 'icon' => 'brightsword.png'], // 15
['type' => 1, 'name' => 'Dragonbane', 'cost' => 10000, 'attr' => 'atk,300|str,50', 'icon' => 'dragonbane.png' ], // 16
// Type 2 - armors
['type' => 2, 'name' => 'Underwear', 'cost' => 25, 'attr' => 'def,2|gold,10', 'icon' => 'underwear.png' ], // 17
['type' => 2, 'name' => 'Clothes', 'cost' => 50, 'attr' => 'def,5', 'icon' => 'clothes.png' ], // 18
['type' => 2, 'name' => 'Leather', 'cost' => 75, 'attr' => 'def,10', 'icon' => 'leather.png' ], // 19
['type' => 2, 'name' => 'Hard Leather', 'cost' => 150, 'attr' => 'def,25', 'icon' => 'hardleather.png' ], // 20
['type' => 2, 'name' => 'Chainmail', 'cost' => 300, 'attr' => 'def,35', 'icon' => 'chainmail.png' ], // 21
['type' => 2, 'name' => 'Scale Armor', 'cost' => 900, 'attr' => 'def,50', 'icon' => 'scalearmor.png' ], // 22
['type' => 2, 'name' => 'Platemail', 'cost' => 1800, 'attr' => 'def,100', 'icon' => 'platemail.png' ], // 23
['type' => 2, 'name' => 'Magic Plate', 'cost' => 3000, 'attr' => 'def,125|mp,50', 'icon' => 'magicplate.png' ], // 24
['type' => 2, 'name' => 'Darkmail', 'cost' => 5000, 'attr' => 'def,200|exp,-10', 'icon' => 'darkmail.png' ], // 25
['type' => 2, 'name' => 'Dragon Plate', 'cost' => 10000, 'attr' => 'def,165|exp,10', 'icon' => 'dragonplate.png' ], // 26
['type' => 2, 'name' => 'Destiny Raiment', 'cost' => 50000, 'attr' => 'def,200|dex,50', 'icon' => 'destinyraiment.png'], // 27
// Type 3 - shields
['type' => 3, 'name' => 'Reed Shield', 'cost' => 50, 'attr' => 'def,5', 'icon' => 'reedshield.png' ], // 28
['type' => 3, 'name' => 'Buckler', 'cost' => 100, 'attr' => 'def,10', 'icon' => 'nuckler.png' ], // 29
['type' => 3, 'name' => 'Round Shield', 'cost' => 500, 'attr' => 'def,25', 'icon' => 'roundshield.png' ], // 30
['type' => 3, 'name' => 'Tower Shield', 'cost' => 2500, 'attr' => 'def,50', 'icon' => 'towershield.png' ], // 31
['type' => 3, 'name' => 'Silver Shield', 'cost' => 10000, 'attr' => 'def,100', 'icon' => 'silvershield.png'], // 32
['type' => 3, 'name' => 'Dragon Shield', 'cost' => 25000, 'attr' => 'def,125|mp,100', 'icon' => 'dragonshield.png'], // 33
['type' => 3, 'name' => 'Aegis', 'cost' => 50000, 'attr' => 'def,225|exp,10', 'icon' => 'aegis.png' ] // 34
]);
}
// Create Monsters table
$db->table('monsters')->create([
'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 ''"
]);
// Fill monsters table if complete install
if ($complete) {
$db->insert([
['name' => 'Blue Slime', 'level' => 1, 'hp' => 4, 'atk' => 3, 'def' => 1, 'exp' => 1, 'gold' => 1, 'immune' => 0],
['name' => 'Red Slime', 'level' => 1, 'hp' => 6, 'atk' => 5, 'def' => 1, 'exp' => 2, 'gold' => 1, 'immune' => 0],
['name' => 'Critter', 'level' => 1, 'hp' => 6, 'atk' => 5, 'def' => 2, 'exp' => 4, 'gold' => 2, 'immune' => 0],
['name' => 'Creature', 'level' => 2, 'hp' => 10, 'atk' => 8, 'def' => 2, 'exp' => 4, 'gold' => 2, 'immune' => 0],
['name' => 'Shadow', 'level' => 2, 'hp' => 10, 'atk' => 9, 'def' => 3, 'exp' => 6, 'gold' => 2, 'immune' => 1],
['name' => 'Drake', 'level' => 2, 'hp' => 11, 'atk' => 10, 'def' => 3, 'exp' => 8, 'gold' => 3, 'immune' => 0],
['name' => 'Shade', 'level' => 3, 'hp' => 12, 'atk' => 10, 'def' => 3, 'exp' => 10, 'gold' => 3, 'immune' => 1],
['name' => 'Drakelor', 'level' => 3, 'hp' => 14, 'atk' => 12, 'def' => 4, 'exp' => 10, 'gold' => 3, 'immune' => 0],
['name' => 'Silver Slime', 'level' => 30, 'hp' => 15, 'atk' => 100, 'def' => 200, 'exp' => 15, 'gold' => 1000, 'immune' => 2],
['name' => 'Scamp', 'level' => 4, 'hp' => 16, 'atk' => 13, 'def' => 5, 'exp' => 15, 'gold' => 5, 'immune' => 0],
['name' => 'Raven', 'level' => 4, 'hp' => 16, 'atk' => 13, 'def' => 5, 'exp' => 18, 'gold' => 6, 'immune' => 0],
['name' => 'Scorpion', 'level' => 5, 'hp' => 18, 'atk' => 14, 'def' => 6, 'exp' => 20, 'gold' => 7, 'immune' => 0],
['name' => 'Illusion', 'level' => 5, 'hp' => 20, 'atk' => 15, 'def' => 6, 'exp' => 20, 'gold' => 7, 'immune' => 1],
['name' => 'Nightshade', 'level' => 6, 'hp' => 22, 'atk' => 16, 'def' => 6, 'exp' => 24, 'gold' => 8, 'immune' => 0],
['name' => 'Drakemal', 'level' => 6, 'hp' => 22, 'atk' => 18, 'def' => 7, 'exp' => 24, 'gold' => 8, 'immune' => 0],
['name' => 'Shadow Raven', 'level' => 6, 'hp' => 24, 'atk' => 18, 'def' => 7, 'exp' => 26, 'gold' => 9, 'immune' => 1],
['name' => 'Ghost', 'level' => 6, 'hp' => 24, 'atk' => 20, 'def' => 8, 'exp' => 28, 'gold' => 9, 'immune' => 0],
['name' => 'Frost Raven', 'level' => 7, 'hp' => 26, 'atk' => 20, 'def' => 8, 'exp' => 30, 'gold' => 10, 'immune' => 0],
['name' => 'Rogue Scorpion', 'level' => 7, 'hp' => 28, 'atk' => 22, 'def' => 9, 'exp' => 32, 'gold' => 11, 'immune' => 0],
['name' => 'Ghoul', 'level' => 7, 'hp' => 29, 'atk' => 24, 'def' => 9, 'exp' => 34, 'gold' => 11, 'immune' => 0],
['name' => 'Magician', 'level' => 8, 'hp' => 30, 'atk' => 24, 'def' => 10, 'exp' => 36, 'gold' => 12, 'immune' => 0],
['name' => 'Rogue', 'level' => 8, 'hp' => 30, 'atk' => 25, 'def' => 12, 'exp' => 40, 'gold' => 13, 'immune' => 0],
['name' => 'Drakefin', 'level' => 8, 'hp' => 32, 'atk' => 26, 'def' => 12, 'exp' => 40, 'gold' => 13, 'immune' => 0],
['name' => 'Shimmer', 'level' => 8, 'hp' => 32, 'atk' => 26, 'def' => 14, 'exp' => 45, 'gold' => 15, 'immune' => 1],
['name' => 'Fire Raven', 'level' => 9, 'hp' => 34, 'atk' => 28, 'def' => 14, 'exp' => 45, 'gold' => 15, 'immune' => 0],
['name' => 'Dybbuk', 'level' => 9, 'hp' => 34, 'atk' => 28, 'def' => 14, 'exp' => 50, 'gold' => 17, 'immune' => 0],
['name' => 'Knave', 'level' => 9, 'hp' => 36, 'atk' => 30, 'def' => 15, 'exp' => 52, 'gold' => 17, 'immune' => 0],
['name' => 'Goblin', 'level' => 10, 'hp' => 36, 'atk' => 30, 'def' => 15, 'exp' => 54, 'gold' => 18, 'immune' => 0],
['name' => 'Skeleton', 'level' => 10, 'hp' => 38, 'atk' => 30, 'def' => 18, 'exp' => 58, 'gold' => 19, 'immune' => 0],
['name' => 'Dark Slime', 'level' => 10, 'hp' => 38, 'atk' => 32, 'def' => 18, 'exp' => 62, 'gold' => 21, 'immune' => 0],
['name' => 'Silver Scorpion', 'level' => 40, 'hp' => 30, 'atk' => 160, 'def' => 350, 'exp' => 63, 'gold' => 2000, 'immune' => 2],
['name' => 'Mirage', 'level' => 11, 'hp' => 40, 'atk' => 32, 'def' => 20, 'exp' => 64, 'gold' => 21, 'immune' => 1],
['name' => 'Sorceror', 'level' => 11, 'hp' => 41, 'atk' => 33, 'def' => 22, 'exp' => 68, 'gold' => 23, 'immune' => 0],
['name' => 'Imp', 'level' => 12, 'hp' => 42, 'atk' => 34, 'def' => 22, 'exp' => 70, 'gold' => 23, 'immune' => 0],
['name' => 'Nymph', 'level' => 12, 'hp' => 43, 'atk' => 35, 'def' => 22, 'exp' => 70, 'gold' => 23, 'immune' => 0],
['name' => 'Scoundrel', 'level' => 12, 'hp' => 43, 'atk' => 35, 'def' => 22, 'exp' => 75, 'gold' => 25, 'immune' => 0],
['name' => 'Megaskeleton', 'level' => 13, 'hp' => 44, 'atk' => 36, 'def' => 24, 'exp' => 78, 'gold' => 26, 'immune' => 0],
['name' => 'Grey Wolf', 'level' => 13, 'hp' => 44, 'atk' => 36, 'def' => 24, 'exp' => 82, 'gold' => 27, 'immune' => 0],
['name' => 'Phantom', 'level' => 14, 'hp' => 46, 'atk' => 38, 'def' => 24, 'exp' => 85, 'gold' => 28, 'immune' => 1],
['name' => 'Specter', 'level' => 14, 'hp' => 46, 'atk' => 38, 'def' => 24, 'exp' => 90, 'gold' => 30, 'immune' => 0],
['name' => 'Dark Scorpion', 'level' => 15, 'hp' => 48, 'atk' => 40, 'def' => 26, 'exp' => 95, 'gold' => 32, 'immune' => 1],
['name' => 'Warlock', 'level' => 15, 'hp' => 48, 'atk' => 40, 'def' => 26, 'exp' => 100, 'gold' => 33, 'immune' => 1],
['name' => 'Orc', 'level' => 15, 'hp' => 49, 'atk' => 42, 'def' => 28, 'exp' => 104, 'gold' => 35, 'immune' => 0],
['name' => 'Sylph', 'level' => 15, 'hp' => 49, 'atk' => 42, 'def' => 28, 'exp' => 106, 'gold' => 35, 'immune' => 0],
['name' => 'Wraith', 'level' => 16, 'hp' => 50, 'atk' => 45, 'def' => 30, 'exp' => 108, 'gold' => 36, 'immune' => 0],
['name' => 'Hellion', 'level' => 16, 'hp' => 50, 'atk' => 45, 'def' => 30, 'exp' => 110, 'gold' => 37, 'immune' => 0],
['name' => 'Bandit', 'level' => 16, 'hp' => 52, 'atk' => 45, 'def' => 30, 'exp' => 114, 'gold' => 38, 'immune' => 0],
['name' => 'Ultraskeleton', 'level' => 16, 'hp' => 52, 'atk' => 46, 'def' => 32, 'exp' => 116, 'gold' => 39, 'immune' => 0],
['name' => 'Dark Wolf', 'level' => 17, 'hp' => 54, 'atk' => 47, 'def' => 36, 'exp' => 120, 'gold' => 40, 'immune' => 1],
['name' => 'Troll', 'level' => 17, 'hp' => 56, 'atk' => 48, 'def' => 36, 'exp' => 120, 'gold' => 40, 'immune' => 0],
['name' => 'Werewolf', 'level' => 17, 'hp' => 56, 'atk' => 48, 'def' => 38, 'exp' => 124, 'gold' => 41, 'immune' => 0],
['name' => 'Hellcat', 'level' => 18, 'hp' => 58, 'atk' => 50, 'def' => 38, 'exp' => 128, 'gold' => 43, 'immune' => 0],
['name' => 'Spirit', 'level' => 18, 'hp' => 58, 'atk' => 50, 'def' => 38, 'exp' => 132, 'gold' => 44, 'immune' => 0],
['name' => 'Nisse', 'level' => 19, 'hp' => 60, 'atk' => 52, 'def' => 40, 'exp' => 132, 'gold' => 44, 'immune' => 0],
['name' => 'Dawk', 'level' => 19, 'hp' => 60, 'atk' => 54, 'def' => 40, 'exp' => 136, 'gold' => 45, 'immune' => 0],
['name' => 'Figment', 'level' => 19, 'hp' => 64, 'atk' => 55, 'def' => 42, 'exp' => 140, 'gold' => 47, 'immune' => 1],
['name' => 'Hellhound', 'level' => 20, 'hp' => 66, 'atk' => 56, 'def' => 44, 'exp' => 140, 'gold' => 47, 'immune' => 0],
['name' => 'Wizard', 'level' => 20, 'hp' => 66, 'atk' => 56, 'def' => 44, 'exp' => 144, 'gold' => 48, 'immune' => 0],
['name' => 'Uruk', 'level' => 20, 'hp' => 68, 'atk' => 58, 'def' => 44, 'exp' => 146, 'gold' => 49, 'immune' => 0],
['name' => 'Siren', 'level' => 50, 'hp' => 68, 'atk' => 400, 'def' => 800, 'exp' => 10000, 'gold' => 50, 'immune' => 2],
['name' => 'Megawraith', 'level' => 21, 'hp' => 70, 'atk' => 60, 'def' => 46, 'exp' => 155, 'gold' => 52, 'immune' => 0],
['name' => 'Dawkin', 'level' => 21, 'hp' => 70, 'atk' => 60, 'def' => 46, 'exp' => 155, 'gold' => 52, 'immune' => 0],
['name' => 'Grey Bear', 'level' => 21, 'hp' => 70, 'atk' => 62, 'def' => 48, 'exp' => 160, 'gold' => 53, 'immune' => 0],
['name' => 'Haunt', 'level' => 22, 'hp' => 72, 'atk' => 62, 'def' => 48, 'exp' => 160, 'gold' => 53, 'immune' => 0],
['name' => 'Hellbeast', 'level' => 22, 'hp' => 74, 'atk' => 64, 'def' => 50, 'exp' => 165, 'gold' => 55, 'immune' => 0],
['name' => 'Fear', 'level' => 23, 'hp' => 76, 'atk' => 66, 'def' => 52, 'exp' => 165, 'gold' => 55, 'immune' => 0],
['name' => 'Beast', 'level' => 23, 'hp' => 76, 'atk' => 66, 'def' => 52, 'exp' => 170, 'gold' => 57, 'immune' => 0],
['name' => 'Ogre', 'level' => 23, 'hp' => 78, 'atk' => 68, 'def' => 54, 'exp' => 170, 'gold' => 57, 'immune' => 0],
['name' => 'Dark Bear', 'level' => 24, 'hp' => 80, 'atk' => 70, 'def' => 56, 'exp' => 175, 'gold' => 58, 'immune' => 1],
['name' => 'Fire', 'level' => 24, 'hp' => 80, 'atk' => 72, 'def' => 56, 'exp' => 175, 'gold' => 58, 'immune' => 0],
['name' => 'Polgergeist', 'level' => 25, 'hp' => 84, 'atk' => 74, 'def' => 58, 'exp' => 180, 'gold' => 60, 'immune' => 0],
['name' => 'Fright', 'level' => 25, 'hp' => 86, 'atk' => 76, 'def' => 58, 'exp' => 180, 'gold' => 60, 'immune' => 0],
['name' => 'Lycan', 'level' => 25, 'hp' => 88, 'atk' => 78, 'def' => 60, 'exp' => 185, 'gold' => 62, 'immune' => 0],
['name' => 'Terra Elemental', 'level' => 25, 'hp' => 88, 'atk' => 80, 'def' => 62, 'exp' => 185, 'gold' => 62, 'immune' => 1],
['name' => 'Necromancer', 'level' => 26, 'hp' => 90, 'atk' => 80, 'def' => 62, 'exp' => 190, 'gold' => 63, 'immune' => 0],
['name' => 'Ultrawraith', 'level' => 26, 'hp' => 90, 'atk' => 82, 'def' => 64, 'exp' => 190, 'gold' => 63, 'immune' => 0],
['name' => 'Dawkor', 'level' => 26, 'hp' => 92, 'atk' => 82, 'def' => 64, 'exp' => 195, 'gold' => 65, 'immune' => 0],
['name' => 'Werebear', 'level' => 26, 'hp' => 92, 'atk' => 84, 'def' => 65, 'exp' => 195, 'gold' => 65, 'immune' => 0],
['name' => 'Brute', 'level' => 27, 'hp' => 94, 'atk' => 84, 'def' => 65, 'exp' => 200, 'gold' => 67, 'immune' => 0],
['name' => 'Large Beast', 'level' => 27, 'hp' => 96, 'atk' => 88, 'def' => 66, 'exp' => 200, 'gold' => 67, 'immune' => 0],
['name' => 'Horror', 'level' => 27, 'hp' => 96, 'atk' => 88, 'def' => 68, 'exp' => 210, 'gold' => 70, 'immune' => 0],
['name' => 'Flame', 'level' => 28, 'hp' => 100, 'atk' => 90, 'def' => 70, 'exp' => 210, 'gold' => 70, 'immune' => 0],
['name' => 'Lycanthor', 'level' => 28, 'hp' => 100, 'atk' => 90, 'def' => 70, 'exp' => 210, 'gold' => 70, 'immune' => 0],
['name' => 'Wyrm', 'level' => 28, 'hp' => 100, 'atk' => 92, 'def' => 72, 'exp' => 220, 'gold' => 73, 'immune' => 0],
['name' => 'Aero Elemental', 'level' => 29, 'hp' => 104, 'atk' => 94, 'def' => 74, 'exp' => 220, 'gold' => 73, 'immune' => 1],
['name' => 'Dawkare', 'level' => 29, 'hp' => 106, 'atk' => 96, 'def' => 76, 'exp' => 220, 'gold' => 73, 'immune' => 0],
['name' => 'Large Brute', 'level' => 29, 'hp' => 108, 'atk' => 98, 'def' => 78, 'exp' => 230, 'gold' => 77, 'immune' => 0],
['name' => 'Frost Wyrm', 'level' => 30, 'hp' => 110, 'atk' => 100, 'def' => 80, 'exp' => 230, 'gold' => 77, 'immune' => 0],
['name' => 'Knight', 'level' => 30, 'hp' => 110, 'atk' => 102, 'def' => 80, 'exp' => 240, 'gold' => 80, 'immune' => 0],
['name' => 'Lycanthra', 'level' => 30, 'hp' => 112, 'atk' => 104, 'def' => 82, 'exp' => 240, 'gold' => 80, 'immune' => 0],
['name' => 'Terror', 'level' => 31, 'hp' => 115, 'atk' => 108, 'def' => 84, 'exp' => 250, 'gold' => 83, 'immune' => 0],
['name' => 'Blaze', 'level' => 31, 'hp' => 118, 'atk' => 108, 'def' => 84, 'exp' => 250, 'gold' => 83, 'immune' => 0],
['name' => 'Aqua Elemental', 'level' => 31, 'hp' => 120, 'atk' => 110, 'def' => 90, 'exp' => 260, 'gold' => 87, 'immune' => 1],
['name' => 'Fire Wyrm', 'level' => 32, 'hp' => 120, 'atk' => 110, 'def' => 90, 'exp' => 260, 'gold' => 87, 'immune' => 0],
['name' => 'Lesser Wyvern', 'level' => 32, 'hp' => 122, 'atk' => 110, 'def' => 92, 'exp' => 270, 'gold' => 90, 'immune' => 0],
['name' => 'Doomer', 'level' => 32, 'hp' => 124, 'atk' => 112, 'def' => 92, 'exp' => 270, 'gold' => 90, 'immune' => 0],
['name' => 'Armor Knight', 'level' => 33, 'hp' => 130, 'atk' => 115, 'def' => 95, 'exp' => 280, 'gold' => 93, 'immune' => 0],
['name' => 'Wyvern', 'level' => 33, 'hp' => 134, 'atk' => 120, 'def' => 95, 'exp' => 290, 'gold' => 97, 'immune' => 0],
['name' => 'Nightmare', 'level' => 33, 'hp' => 138, 'atk' => 125, 'def' => 100, 'exp' => 300, 'gold' => 100, 'immune' => 0],
['name' => 'Fira Elemental', 'level' => 34, 'hp' => 140, 'atk' => 125, 'def' => 100, 'exp' => 310, 'gold' => 103, 'immune' => 1],
['name' => 'Megadoomer', 'level' => 34, 'hp' => 140, 'atk' => 128, 'def' => 105, 'exp' => 320, 'gold' => 107, 'immune' => 0],
['name' => 'Greater Wyvern', 'level' => 34, 'hp' => 145, 'atk' => 130, 'def' => 105, 'exp' => 335, 'gold' => 112, 'immune' => 0],
['name' => 'Advocate', 'level' => 35, 'hp' => 148, 'atk' => 132, 'def' => 108, 'exp' => 350, 'gold' => 117, 'immune' => 0],
['name' => 'Strong Knight', 'level' => 35, 'hp' => 150, 'atk' => 135, 'def' => 110, 'exp' => 365, 'gold' => 122, 'immune' => 0],
['name' => 'Liche', 'level' => 35, 'hp' => 150, 'atk' => 135, 'def' => 110, 'exp' => 380, 'gold' => 127, 'immune' => 0],
['name' => 'Ultradoomer', 'level' => 36, 'hp' => 155, 'atk' => 140, 'def' => 115, 'exp' => 395, 'gold' => 132, 'immune' => 0],
['name' => 'Fanatic', 'level' => 36, 'hp' => 160, 'atk' => 140, 'def' => 115, 'exp' => 410, 'gold' => 137, 'immune' => 0],
['name' => 'Green Dragon', 'level' => 36, 'hp' => 160, 'atk' => 140, 'def' => 115, 'exp' => 425, 'gold' => 142, 'immune' => 0],
['name' => 'Fiend', 'level' => 37, 'hp' => 160, 'atk' => 145, 'def' => 120, 'exp' => 445, 'gold' => 148, 'immune' => 0],
['name' => 'Greatest Wyvern', 'level' => 37, 'hp' => 162, 'atk' => 150, 'def' => 120, 'exp' => 465, 'gold' => 155, 'immune' => 0],
['name' => 'Lesser Devil', 'level' => 37, 'hp' => 164, 'atk' => 150, 'def' => 120, 'exp' => 485, 'gold' => 162, 'immune' => 0],
['name' => 'Liche Master', 'level' => 38, 'hp' => 168, 'atk' => 155, 'def' => 125, 'exp' => 505, 'gold' => 168, 'immune' => 0],
['name' => 'Zealot', 'level' => 38, 'hp' => 168, 'atk' => 155, 'def' => 125, 'exp' => 530, 'gold' => 177, 'immune' => 0],
['name' => 'Serafiend', 'level' => 38, 'hp' => 170, 'atk' => 155, 'def' => 125, 'exp' => 555, 'gold' => 185, 'immune' => 0],
['name' => 'Pale Knight', 'level' => 39, 'hp' => 175, 'atk' => 160, 'def' => 130, 'exp' => 580, 'gold' => 193, 'immune' => 0],
['name' => 'Blue Dragon', 'level' => 39, 'hp' => 180, 'atk' => 160, 'def' => 130, 'exp' => 605, 'gold' => 202, 'immune' => 0],
['name' => 'Obsessive', 'level' => 40, 'hp' => 180, 'atk' => 160, 'def' => 135, 'exp' => 630, 'gold' => 210, 'immune' => 0],
['name' => 'Devil', 'level' => 40, 'hp' => 184, 'atk' => 164, 'def' => 135, 'exp' => 666, 'gold' => 222, 'immune' => 0],
['name' => 'Liche Prince', 'level' => 40, 'hp' => 190, 'atk' => 168, 'def' => 138, 'exp' => 660, 'gold' => 220, 'immune' => 0],
['name' => 'Cherufiend', 'level' => 41, 'hp' => 195, 'atk' => 170, 'def' => 140, 'exp' => 690, 'gold' => 230, 'immune' => 0],
['name' => 'Red Dragon', 'level' => 41, 'hp' => 200, 'atk' => 180, 'def' => 145, 'exp' => 720, 'gold' => 240, 'immune' => 0],
['name' => 'Greater Devil', 'level' => 41, 'hp' => 200, 'atk' => 180, 'def' => 145, 'exp' => 750, 'gold' => 250, 'immune' => 0],
['name' => 'Renegade', 'level' => 42, 'hp' => 205, 'atk' => 185, 'def' => 150, 'exp' => 780, 'gold' => 260, 'immune' => 0],
['name' => 'Archfiend', 'level' => 42, 'hp' => 210, 'atk' => 190, 'def' => 150, 'exp' => 810, 'gold' => 270, 'immune' => 0],
['name' => 'Liche Lord', 'level' => 42, 'hp' => 210, 'atk' => 190, 'def' => 155, 'exp' => 850, 'gold' => 283, 'immune' => 0],
['name' => 'Greatest Devil', 'level' => 43, 'hp' => 215, 'atk' => 195, 'def' => 160, 'exp' => 890, 'gold' => 297, 'immune' => 0],
['name' => 'Dark Knight', 'level' => 43, 'hp' => 220, 'atk' => 200, 'def' => 160, 'exp' => 930, 'gold' => 310, 'immune' => 0],
['name' => 'Giant', 'level' => 43, 'hp' => 220, 'atk' => 200, 'def' => 165, 'exp' => 970, 'gold' => 323, 'immune' => 0],
['name' => 'Shadow Dragon', 'level' => 44, 'hp' => 225, 'atk' => 200, 'def' => 170, 'exp' => 1010, 'gold' => 337, 'immune' => 0],
['name' => 'Liche King', 'level' => 44, 'hp' => 225, 'atk' => 205, 'def' => 170, 'exp' => 1050, 'gold' => 350, 'immune' => 0],
['name' => 'Incubus', 'level' => 44, 'hp' => 230, 'atk' => 205, 'def' => 175, 'exp' => 1100, 'gold' => 367, 'immune' => 1],
['name' => 'Traitor', 'level' => 45, 'hp' => 230, 'atk' => 205, 'def' => 175, 'exp' => 1150, 'gold' => 383, 'immune' => 0],
['name' => 'Demon', 'level' => 45, 'hp' => 240, 'atk' => 210, 'def' => 180, 'exp' => 1200, 'gold' => 400, 'immune' => 0],
['name' => 'Dark Dragon', 'level' => 45, 'hp' => 245, 'atk' => 215, 'def' => 180, 'exp' => 1250, 'gold' => 417, 'immune' => 1],
['name' => 'Insurgent', 'level' => 46, 'hp' => 250, 'atk' => 220, 'def' => 190, 'exp' => 1300, 'gold' => 433, 'immune' => 0],
['name' => 'Leviathan', 'level' => 46, 'hp' => 255, 'atk' => 225, 'def' => 190, 'exp' => 1350, 'gold' => 450, 'immune' => 0],
['name' => 'Grey Daemon', 'level' => 46, 'hp' => 260, 'atk' => 230, 'def' => 190, 'exp' => 1400, 'gold' => 467, 'immune' => 0],
['name' => 'Succubus', 'level' => 47, 'hp' => 265, 'atk' => 240, 'def' => 200, 'exp' => 1460, 'gold' => 487, 'immune' => 1],
['name' => 'Demon Prince', 'level' => 47, 'hp' => 270, 'atk' => 240, 'def' => 200, 'exp' => 1520, 'gold' => 507, 'immune' => 0],
['name' => 'Black Dragon', 'level' => 47, 'hp' => 275, 'atk' => 250, 'def' => 205, 'exp' => 1580, 'gold' => 527, 'immune' => 1],
['name' => 'Nihilist', 'level' => 47, 'hp' => 280, 'atk' => 250, 'def' => 205, 'exp' => 1640, 'gold' => 547, 'immune' => 0],
['name' => 'Behemoth', 'level' => 48, 'hp' => 285, 'atk' => 260, 'def' => 210, 'exp' => 1700, 'gold' => 567, 'immune' => 0],
['name' => 'Demagogue', 'level' => 48, 'hp' => 290, 'atk' => 260, 'def' => 210, 'exp' => 1760, 'gold' => 587, 'immune' => 0],
['name' => 'Demon Lord', 'level' => 48, 'hp' => 300, 'atk' => 270, 'def' => 220, 'exp' => 1820, 'gold' => 607, 'immune' => 0],
['name' => 'Red Daemon', 'level' => 48, 'hp' => 310, 'atk' => 280, 'def' => 230, 'exp' => 1880, 'gold' => 627, 'immune' => 0],
['name' => 'Colossus', 'level' => 49, 'hp' => 320, 'atk' => 300, 'def' => 240, 'exp' => 1940, 'gold' => 647, 'immune' => 0],
['name' => 'Demon King', 'level' => 49, 'hp' => 330, 'atk' => 300, 'def' => 250, 'exp' => 2000, 'gold' => 667, 'immune' => 0],
['name' => 'Dark Daemon', 'level' => 49, 'hp' => 340, 'atk' => 320, 'def' => 260, 'exp' => 2200, 'gold' => 733, 'immune' => 1],
['name' => 'Titan', 'level' => 50, 'hp' => 360, 'atk' => 340, 'def' => 270, 'exp' => 2400, 'gold' => 800, 'immune' => 0],
['name' => 'Black Daemon', 'level' => 50, 'hp' => 400, 'atk' => 400, 'def' => 280, 'exp' => 3000, 'gold' => 1000, 'immune' => 1],
['name' => 'Lucifuge', 'level' => 50, 'hp' => 600, 'atk' => 600, 'def' => 400, 'exp' => 10000, 'gold' => 10000, 'immune' => 2],
]);
}
// Create News table
$db->table('news')->create([
'id INTEGER PRIMARY KEY',
'posted DATETIME DEFAULT CURRENT_TIMESTAMP',
'author INTEGER DEFAULT 1',
"title TEXT DEFAULT ''",
"content TEXT DEFAULT ''"
]);
// Create Spells table
$db->table('spells')->create([
'id INTEGER PRIMARY KEY',
'name TEXT NOT NULL',
'type INTEGER DEFAULT 1',
'mp INTEGER DEFAULT 0',
"effect TEXT DEFAULT ''",
"icon TEXT DEFAULT ''"
]);
// Fill spells if complete install
if ($complete) {
$db->table('spells')->insert([
// Type 1 = healing
['name' => 'Heal', 'type' => 1, 'mp' => 5, 'effect' => 'heal:self,10', 'icon' => 'heal.png' ], // 1
['name' => 'Cure', 'type' => 1, 'mp' => 10, 'effect' => 'heal:self,25', 'icon' => 'cure.png' ], // 2
['name' => 'Breath', 'type' => 1, 'mp' => 25, 'effect' => 'heal:self,50', 'icon' => 'breath.png'], // 3
['name' => 'Revive', 'type' => 1, 'mp' => 50, 'effect' => 'heal:self,100', 'icon' => 'revive.png'], // 4
['name' => 'Gaia', 'type' => 1, 'mp' => 75, 'effect' => 'heal:self,150', 'icon' => 'gaia.png' ], // 5
// Type 2 = damage
['name' => 'Slash', 'type' => 2, 'mp' => 5, 'effect' => 'damage:opp,10', 'icon' => 'slash.png' ], // 6
['name' => 'Magic Missile', 'type' => 2, 'mp' => 12, 'effect' => 'damage:opp,35', 'icon' => 'missile.png' ], // 7
['name' => 'Fireball', 'type' => 2, 'mp' => 25, 'effect' => 'damage:opp,70', 'icon' => 'fireball.png' ], // 8
['name' => 'Pain', 'type' => 2, 'mp' => 40, 'effect' => 'damage:opp,100', 'icon' => 'pain.png' ], // 9
['name' => 'Lightning', 'type' => 2, 'mp' => 50, 'effect' => 'damage:opp,130', 'icon' => 'lightning.png'], // 10
['name' => 'Chaos', 'type' => 2, 'mp' => 75, 'effect' => 'damage:opp,200', 'icon' => 'chaos.png' ], // 11
// Type 3 = sleep
['name' => 'Sleep', 'type' => 3, 'mp' => 10, 'effect' => 'sleep:opp,3', 'icon' => 'sleep.png' ], // 12
['name' => 'Dream', 'type' => 3, 'mp' => 30, 'effect' => 'sleep:opp,6', 'icon' => 'dream.png' ], // 13
['name' => 'Nightmare', 'type' => 3, 'mp' => 60, 'effect' => 'sleep:opp,13', 'icon' => 'nightmare.png'], // 14
// Type 4 = rage
['name' => 'Craze', 'type' => 4, 'mp' => 10, 'effect' => 'rage:self,3', 'icon' => 'craze.png'], // 15
['name' => 'Rage', 'type' => 4, 'mp' => 30, 'effect' => 'rage:self,6', 'icon' => 'rage.png' ], // 16
['name' => 'Fury', 'type' => 4, 'mp' => 60, 'effect' => 'rage:self,13', 'icon' => 'fury.png' ], // 17
// Type 5 = protect
['name' => 'Ward', 'type' => 5, 'mp' => 10, 'effect' => 'protect:self,3', 'icon' => 'ward.png' ], // 18
['name' => 'Guard', 'type' => 5, 'mp' => 30, 'effect' => 'protect:self,6', 'icon' => 'guard.png' ], // 19
['name' => 'Barrier', 'type' => 5, 'mp' => 60, 'effect' => 'protect:self,13', 'icon' => 'barrier.png'] // 20
]);
}
// Create Towns table
$db->table('towns')->create([
'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 ''",
]);
// Fill towns table if complete install
if ($complete) {
$db->insert([
['name' => 'Midworld', 'x' => 0, 'y' => 0, 'inn_cost' => 5, 'map_cost' => 5, 'tp_cost' => 0, 'shop_list' => '1,2,3,17,18,19,28,29', 'image' => 'midworld.png'],
['name' => 'Roma', 'x' => 30, 'y' => 30, 'inn_cost' => 10, 'map_cost' => 25, 'tp_cost' => 5, 'shop_list' => '2,3,4,18,19,29', 'image' => 'roma.png' ],
['name' => 'Bris', 'x' => 70, 'y' => -70, 'inn_cost' => 25, 'map_cost' => 50, 'tp_cost' => 15, 'shop_list' => '2,3,4,5,18,19,20,29,30', 'image' => 'bris.png' ],
['name' => 'Kalle', 'x' => -100, 'y' => 100, 'inn_cost' => 40, 'map_cost' => 100, 'tp_cost' => 30, 'shop_list' => '5,6,8,10,12,21,22,23,29,30', 'image' => 'kalle.png' ],
['name' => 'Narcissa', 'x' => -130, 'y' => -130, 'inn_cost' => 60, 'map_cost' => 500, 'tp_cost' => 50, 'shop_list' => '4,7,9,11,13,21,22,23,29,30,31', 'image' => 'narcissa.png'],
['name' => 'Hambry', 'x' => 170, 'y' => 170, 'inn_cost' => 90, 'map_cost' => 1000, 'tp_cost' => 80, 'shop_list' => '10,11,12,13,14,23,24,30,31', 'image' => 'hambry.png' ],
['name' => 'Gilead', 'x' => 200, 'y' => -200, 'inn_cost' => 100, 'map_cost' => 3000, 'tp_cost' => 110,'shop_list' => '12,13,14,15,24,25,26,32', 'image' => 'gilead.png' ],
['name' => 'Endworld', 'x' => -250, 'y' => -250, 'inn_cost' => 150, 'map_cost' => 9000, 'tp_cost' => 160,'shop_list' => '16,27,33', 'image' => 'endworld.png'],
]);
}
// Create Players table
$db->table('players')->create([
'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 ''",
]);
// Create Fights table
$db->table('fights')->create([
'id INTEGER PRIMARY KEY',
'player_id INTEGER DEFAULT 1',
'monster_id INTEGER DEFAULT 1',
'turn INTEGER DEFAULT 1',
'player_hp INTEGER DEFAULT 0',
'player_mp INTEGER DEFAULT 0',
'monster_hp INTEGER DEFAULT 0',
'monster_mp INTEGER DEFAULT 0',
'player_uber_dmg INTEGER DEFAULT 0',
'monster_uber_dmg INTEGER DEFAULT 0',
'player_uber_def INTEGER DEFAULT 0',
'monster_uber_def INTEGER DEFAULT 0',
'monster_immune INTEGER DEFAULT 0',
'monster_sleep INTEGER DEFAULT 0',
]);
echo render('install/layout', ['title' => 'Database Setup', 'step' => 'second', 'complete' => $complete, 'start' => $istart]);
exit;
}
// Admin account; create it from the provided info
if ($step == 'third') {
$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
createUser($_POST['username'], $_POST['password'], $_POST['email'], $class, ['role' => 5, 'verified' => 1]);
// Render the finished page!
echo render('install/layout', ['title' => 'Finished!', 'step' => 'done', 'name' => $_POST['username'], 'complete' => $_POST['complete'] ?? false]);
exit;
}

View File

@ -7,11 +7,21 @@
class App
{
public static Database $db;
private static string $dbPath;
public static Request $req;
public function __construct(string $dbPath)
{
self::$req = new Request(); // the current request
self::$db = new Database($dbPath); // the database
self::$dbPath = $dbPath; // the database path
}
public static function performDatabaseReset(): void
{
if (file_exists(self::$dbPath)) {
unlink(self::$dbPath);
self::$db = new Database(self::$dbPath);
}
}
}

View File

@ -12,7 +12,6 @@ class Database
private PDO $c;
private int $queries = 0;
private array $log = [];
private string $error = '';
private float $time = 0;
public function __construct(string $path, array $opts = [])
@ -27,7 +26,6 @@ class Database
$this->c->exec('PRAGMA foreign_keys = ON;'); // Enable foreign keys
$this->c->exec('PRAGMA journal_mode = WAL;'); // Enable WAL
} catch (PDOException $e) {
$this->error = "Failed to open database: " . $e->getMessage();
throw $e;
}
}
@ -42,8 +40,8 @@ class Database
$this->record($query, $start);
return $stmt;
} catch (PDOException $e) {
$this->error = $e->getMessage();
return false;
print_r($query);
throw $e;
}
}
@ -56,8 +54,8 @@ class Database
$this->record($query, $start);
return $stmt;
} catch (PDOException $e) {
$this->error = $e->getMessage();
return false;
print_r($query);
throw $e;
}
}
@ -69,11 +67,6 @@ class Database
$this->time += $time;
}
public function error(): string
{
return $this->error;
}
public function queries(): int
{
return $this->queries;
@ -88,4 +81,42 @@ class Database
{
return $this->time;
}
public function lastInsertID(): int
{
return $this->c->lastInsertId();
}
public function insertFromCSV(string $table, string $path): PDOStatement|false
{
// open the file
$handle = fopen($path, 'r');
if ($handle === false) return false;
// reduce the column names to lower case with underscores
$columns = array_map(function ($column) {
return strtolower(str_replace(' ', '_', $column));
}, fgetcsv($handle));
// set up the query
$query = "INSERT INTO $table (" . implode(',', $columns) . ') VALUES ';
// read the rows and add them to the query
while (($row = fgetcsv($handle)) !== false) {
// go through the row and put strings into single quotes
$row = array_map(function ($column) {
if (is_numeric($column)) return $column;
return "'" . str_replace("'", "''", $column) . "'";
}, $row);
// add the row to the query
$query .= '(' . implode(',', $row) . '),';
}
// remove the trailing comma
$query = rtrim($query, ',') . ';';
// execute the insert
return $this->q($query);
}
}

View File

@ -30,6 +30,10 @@ const MAP = [
// modules
'HomeModule' => SERVER.'/modules/HomeModule.php',
'InstallModule' => SERVER.'/modules/InstallModule.php',
// models
'Classes' => SERVER.'/models/Classes.php',
'Player' => SERVER.'/models/Player.php',
];
// autoloader

View File

@ -4,7 +4,10 @@ This folder serves as the home for the game's database; `dragon.db` by default.
### Packs
New to Dragon Knight is the ability to upload "data packs" to the game! Using this feature, it is possible to upload and store `.zip` files that contain `.csv` files (spreadsheets) of data for the game. These spreadsheets must have a 1:1 structure to what's expected in Dragon Knight. This allows an admin to populate the game data quickly and easily with data they either make or get from someone else.
The `Default.zip` data pack is the default data used when doing a **Complete** install of Dragon Knight. You can edit this before running the installer to change the default data. You can also use it as a template for your own data packs!
The `Default` data pack is the default data used when doing a **Complete** install of Dragon Knight. You can edit this before running the installer to change the default data. You can also use it as a template for your own data packs!
#### Installing
@TODO
### Installation
When performing a **Complete** install, the installer will look for and use the `Default.zip` data pack if it exists. If not, the installer will error. When performing a **Partial** install, the installer itself will insert the bare minimum data needed (at the moment this is a single class, "Adventurer") to create a user account, and data can be added in the admin panel afterwards.
When performing a **Complete** install, the installer will look for and use the `Default` data pack if it exists. If not, the installer will error. When performing a **Partial** install, the installer itself will insert the bare minimum data needed (at the moment this is a single class, "Adventurer") to create a user account, and data can be added in the admin panel afterwards.

Binary file not shown.

View File

@ -0,0 +1,4 @@
Name,"Start HP","Start MP","Start STR","Start ATK","Start DEF","Start DEX","Growth HP","Growth MP","Growth STR","Growth ATK","Growth DEF","Growth DEX",Spells
Mage,10,10,5,5,5,5,3,5,1,3,1,3,"1:6,18"
Warrior,20,0,10,5,10,5,6,2,3,1,3,1,
Paladin,15,5,5,5,10,10,4,4,2,2,2,2,"1:1,15,18"
1 Name Start HP Start MP Start STR Start ATK Start DEF Start DEX Growth HP Growth MP Growth STR Growth ATK Growth DEF Growth DEX Spells
2 Mage 10 10 5 5 5 5 3 5 1 3 1 3 1:6,18
3 Warrior 20 0 10 5 10 5 6 2 3 1 3 1
4 Paladin 15 5 5 5 10 10 4 4 2 2 2 2 1:1,15,18

View File

@ -0,0 +1,42 @@
Name,Level,Type,Attr
"Life Pebble",1,1,"hp,10"
"Life Stone",10,1,"hp,25"
"Life Rock",25,1,"hp,50"
"Life Ore",50,1,"hp,100"
"Life Gem",75,1,"hp,150"
"Magic Pebble",1,1,"mp,10"
"Magic Stone",10,1,"mp,25"
"Magic Rock",25,1,"mp,50"
"Magic Ore",50,1,"mp,100"
"Magic Gem",75,1,"mp,150"
"Dragon's Scale",10,1,"def,25"
"Dragon's Plate",30,1,"def,50"
"Dragon's Claw",10,1,"atk,25"
"Dragon's Fang",30,1,"atk,50"
"Dragon's Tear",35,1,"str,75"
"Dragon's Wing",35,1,"dex,75"
"Demon's Sin",35,1,"hp,-50|str,65"
"Demon's Fall",35,1,"mp,-50|str,65"
"Demon's Lie",45,1,"hp,-100|str,125"
"Demon's Hate",45,1,"mp,-100|str,125"
"Angel's Joy",25,1,"hp,25|str,25"
"Angel's Rise",30,1,"hp,50|str,50"
"Angel's Truth",35,1,"hp,75|str,75"
"Angel's Grace",40,1,"hp,100|str,100"
"Seraph's Strength",25,1,"mp,25|dex,25"
"Seraph's Power",30,1,"mp,50|dex,50"
"Seraph's Justice",35,1,"mp,75|dex,75"
"Seraph's Judgement",40,1,"mp,100|dex,100"
Ruby,50,1,"hp,150"
Sapphire,50,1,"mp,150"
Emerald,50,1,"str,150"
Amethyst,50,1,"dex,150"
Topaz,50,1,"atk,150"
Diamond,50,1,"def,150"
"Ocean Blessing",77,1,"str,7007|dex,7007"
"Memory Tonic",5,1,"exp,10"
"Memory Potion",30,1,"exp,20"
"Memory Elixir",50,1,"exp,30"
"Gold Tonic",5,1,"gold,10"
"Gold Potion",30,1,"gold,20"
"Gold Elixir",50,1,"gold,30"
1 Name Level Type Attr
2 Life Pebble 1 1 hp,10
3 Life Stone 10 1 hp,25
4 Life Rock 25 1 hp,50
5 Life Ore 50 1 hp,100
6 Life Gem 75 1 hp,150
7 Magic Pebble 1 1 mp,10
8 Magic Stone 10 1 mp,25
9 Magic Rock 25 1 mp,50
10 Magic Ore 50 1 mp,100
11 Magic Gem 75 1 mp,150
12 Dragon's Scale 10 1 def,25
13 Dragon's Plate 30 1 def,50
14 Dragon's Claw 10 1 atk,25
15 Dragon's Fang 30 1 atk,50
16 Dragon's Tear 35 1 str,75
17 Dragon's Wing 35 1 dex,75
18 Demon's Sin 35 1 hp,-50|str,65
19 Demon's Fall 35 1 mp,-50|str,65
20 Demon's Lie 45 1 hp,-100|str,125
21 Demon's Hate 45 1 mp,-100|str,125
22 Angel's Joy 25 1 hp,25|str,25
23 Angel's Rise 30 1 hp,50|str,50
24 Angel's Truth 35 1 hp,75|str,75
25 Angel's Grace 40 1 hp,100|str,100
26 Seraph's Strength 25 1 mp,25|dex,25
27 Seraph's Power 30 1 mp,50|dex,50
28 Seraph's Justice 35 1 mp,75|dex,75
29 Seraph's Judgement 40 1 mp,100|dex,100
30 Ruby 50 1 hp,150
31 Sapphire 50 1 mp,150
32 Emerald 50 1 str,150
33 Amethyst 50 1 dex,150
34 Topaz 50 1 atk,150
35 Diamond 50 1 def,150
36 Ocean Blessing 77 1 str,7007|dex,7007
37 Memory Tonic 5 1 exp,10
38 Memory Potion 30 1 exp,20
39 Memory Elixir 50 1 exp,30
40 Gold Tonic 5 1 gold,10
41 Gold Potion 30 1 gold,20
42 Gold Elixir 50 1 gold,30

View File

@ -0,0 +1,35 @@
Type,Name,Cost,Attr,Icon
1,Stick,10,"atk,2",stick.png
1,Branch,30,"atk,4",branch.png
1,Club,40,"atk,6",club.png
1,Dagger,80,"atk,8",dagger.png
1,Hatchet,120,"atk,12",hatchet.png
1,Axe,200,"atk,18",axe.png
1,Spear,300,"atk,25",spear.png
1,Poleaxe,500,"atk,35",poleaxe.png
1,Warhammer,800,"atk,50",warhammer.png
1,Longsword,1200,"atk,65",longsword.png
1,Claymore,1800,"atk,85",claymore.png
1,"Demon Axe",2800,"atk,125|exp,-5",demonaxe.png
1,"Dark Sword",4500,"atk,225|exp,-10",darksword.png
1,"Magic Axe",2800,"atk,95|exp,5",magicaxe.png
1,"Bright Sword",4500,"atk,185|exp,10",brightsword.png
1,Dragonbane,10000,"atk,300|str,50",dragonbane.png
2,Underwear,25,"def,2|gold,10",underwear.png
2,Clothes,50,"def,5",clothes.png
2,Leather,75,"def,10",leather.png
2,"Hard Leather",150,"def,25",hardleather.png
2,Chainmail,300,"def,35",chainmail.png
2,"Scale Armor",900,"def,50",scalearmor.png
2,Platemail,1800,"def,100",platemail.png
2,"Magic Plate",3000,"def,125|mp,50",magicplate.png
2,Darkmail,5000,"def,200|exp,-10",darkmail.png
2,"Dragon Plate",10000,"def,165|exp,10",dragonplate.png
2,"Destiny Raiment",50000,"def,200|dex,50",destinyraiment.png
3,"Reed Shield",50,"def,5",reedshield.png
3,Buckler,100,"def,10",nuckler.png
3,"Round Shield",500,"def,25",roundshield.png
3,"Tower Shield",2500,"def,50",towershield.png
3,"Silver Shield",10000,"def,100",silvershield.png
3,"Dragon Shield",25000,"def,125|mp,100",dragonshield.png
3,Aegis,50000,"def,225|exp,10",aegis.png
1 Type Name Cost Attr Icon
2 1 Stick 10 atk,2 stick.png
3 1 Branch 30 atk,4 branch.png
4 1 Club 40 atk,6 club.png
5 1 Dagger 80 atk,8 dagger.png
6 1 Hatchet 120 atk,12 hatchet.png
7 1 Axe 200 atk,18 axe.png
8 1 Spear 300 atk,25 spear.png
9 1 Poleaxe 500 atk,35 poleaxe.png
10 1 Warhammer 800 atk,50 warhammer.png
11 1 Longsword 1200 atk,65 longsword.png
12 1 Claymore 1800 atk,85 claymore.png
13 1 Demon Axe 2800 atk,125|exp,-5 demonaxe.png
14 1 Dark Sword 4500 atk,225|exp,-10 darksword.png
15 1 Magic Axe 2800 atk,95|exp,5 magicaxe.png
16 1 Bright Sword 4500 atk,185|exp,10 brightsword.png
17 1 Dragonbane 10000 atk,300|str,50 dragonbane.png
18 2 Underwear 25 def,2|gold,10 underwear.png
19 2 Clothes 50 def,5 clothes.png
20 2 Leather 75 def,10 leather.png
21 2 Hard Leather 150 def,25 hardleather.png
22 2 Chainmail 300 def,35 chainmail.png
23 2 Scale Armor 900 def,50 scalearmor.png
24 2 Platemail 1800 def,100 platemail.png
25 2 Magic Plate 3000 def,125|mp,50 magicplate.png
26 2 Darkmail 5000 def,200|exp,-10 darkmail.png
27 2 Dragon Plate 10000 def,165|exp,10 dragonplate.png
28 2 Destiny Raiment 50000 def,200|dex,50 destinyraiment.png
29 3 Reed Shield 50 def,5 reedshield.png
30 3 Buckler 100 def,10 nuckler.png
31 3 Round Shield 500 def,25 roundshield.png
32 3 Tower Shield 2500 def,50 towershield.png
33 3 Silver Shield 10000 def,100 silvershield.png
34 3 Dragon Shield 25000 def,125|mp,100 dragonshield.png
35 3 Aegis 50000 def,225|exp,10 aegis.png

View File

@ -0,0 +1,152 @@
Name,Level,HP,ATK,DEF,EXP,Gold,Immune
"Blue Slime",1,4,3,1,1,1,0
"Red Slime",1,6,5,1,2,1,0
Critter,1,6,5,2,4,2,0
Creature,2,10,8,2,4,2,0
Shadow,2,10,9,3,6,2,1
Drake,2,11,10,3,8,3,0
Shade,3,12,10,3,10,3,1
Drakelor,3,14,12,4,10,3,0
"Silver Slime",30,15,100,200,15,1000,2
Scamp,4,16,13,5,15,5,0
Raven,4,16,13,5,18,6,0
Scorpion,5,18,14,6,20,7,0
Illusion,5,20,15,6,20,7,1
Nightshade,6,22,16,6,24,8,0
Drakemal,6,22,18,7,24,8,0
"Shadow Raven",6,24,18,7,26,9,1
Ghost,6,24,20,8,28,9,0
"Frost Raven",7,26,20,8,30,10,0
"Rogue Scorpion",7,28,22,9,32,11,0
Ghoul,7,29,24,9,34,11,0
Magician,8,30,24,10,36,12,0
Rogue,8,30,25,12,40,13,0
Drakefin,8,32,26,12,40,13,0
Shimmer,8,32,26,14,45,15,1
"Fire Raven",9,34,28,14,45,15,0
Dybbuk,9,34,28,14,50,17,0
Knave,9,36,30,15,52,17,0
Goblin,10,36,30,15,54,18,0
Skeleton,10,38,30,18,58,19,0
"Dark Slime",10,38,32,18,62,21,0
"Silver Scorpion",40,30,160,350,63,2000,2
Mirage,11,40,32,20,64,21,1
Sorceror,11,41,33,22,68,23,0
Imp,12,42,34,22,70,23,0
Nymph,12,43,35,22,70,23,0
Scoundrel,12,43,35,22,75,25,0
Megaskeleton,13,44,36,24,78,26,0
"Grey Wolf",13,44,36,24,82,27,0
Phantom,14,46,38,24,85,28,1
Specter,14,46,38,24,90,30,0
"Dark Scorpion",15,48,40,26,95,32,1
Warlock,15,48,40,26,100,33,1
Orc,15,49,42,28,104,35,0
Sylph,15,49,42,28,106,35,0
Wraith,16,50,45,30,108,36,0
Hellion,16,50,45,30,110,37,0
Bandit,16,52,45,30,114,38,0
Ultraskeleton,16,52,46,32,116,39,0
"Dark Wolf",17,54,47,36,120,40,1
Troll,17,56,48,36,120,40,0
Werewolf,17,56,48,38,124,41,0
Hellcat,18,58,50,38,128,43,0
Spirit,18,58,50,38,132,44,0
Nisse,19,60,52,40,132,44,0
Dawk,19,60,54,40,136,45,0
Figment,19,64,55,42,140,47,1
Hellhound,20,66,56,44,140,47,0
Wizard,20,66,56,44,144,48,0
Uruk,20,68,58,44,146,49,0
Siren,50,68,400,800,10000,50,2
Megawraith,21,70,60,46,155,52,0
Dawkin,21,70,60,46,155,52,0
"Grey Bear",21,70,62,48,160,53,0
Haunt,22,72,62,48,160,53,0
Hellbeast,22,74,64,50,165,55,0
Fear,23,76,66,52,165,55,0
Beast,23,76,66,52,170,57,0
Ogre,23,78,68,54,170,57,0
"Dark Bear",24,80,70,56,175,58,1
Fire,24,80,72,56,175,58,0
Polgergeist,25,84,74,58,180,60,0
Fright,25,86,76,58,180,60,0
Lycan,25,88,78,60,185,62,0
"Terra Elemental",25,88,80,62,185,62,1
Necromancer,26,90,80,62,190,63,0
Ultrawraith,26,90,82,64,190,63,0
Dawkor,26,92,82,64,195,65,0
Werebear,26,92,84,65,195,65,0
Brute,27,94,84,65,200,67,0
"Large Beast",27,96,88,66,200,67,0
Horror,27,96,88,68,210,70,0
Flame,28,100,90,70,210,70,0
Lycanthor,28,100,90,70,210,70,0
Wyrm,28,100,92,72,220,73,0
"Aero Elemental",29,104,94,74,220,73,1
Dawkare,29,106,96,76,220,73,0
"Large Brute",29,108,98,78,230,77,0
"Frost Wyrm",30,110,100,80,230,77,0
Knight,30,110,102,80,240,80,0
Lycanthra,30,112,104,82,240,80,0
Terror,31,115,108,84,250,83,0
Blaze,31,118,108,84,250,83,0
"Aqua Elemental",31,120,110,90,260,87,1
"Fire Wyrm",32,120,110,90,260,87,0
"Lesser Wyvern",32,122,110,92,270,90,0
Doomer,32,124,112,92,270,90,0
"Armor Knight",33,130,115,95,280,93,0
Wyvern,33,134,120,95,290,97,0
Nightmare,33,138,125,100,300,100,0
"Fira Elemental",34,140,125,100,310,103,1
Megadoomer,34,140,128,105,320,107,0
"Greater Wyvern",34,145,130,105,335,112,0
Advocate,35,148,132,108,350,117,0
"Strong Knight",35,150,135,110,365,122,0
Liche,35,150,135,110,380,127,0
Ultradoomer,36,155,140,115,395,132,0
Fanatic,36,160,140,115,410,137,0
"Green Dragon",36,160,140,115,425,142,0
Fiend,37,160,145,120,445,148,0
"Greatest Wyvern",37,162,150,120,465,155,0
"Lesser Devil",37,164,150,120,485,162,0
"Liche Master",38,168,155,125,505,168,0
Zealot,38,168,155,125,530,177,0
Serafiend,38,170,155,125,555,185,0
"Pale Knight",39,175,160,130,580,193,0
"Blue Dragon",39,180,160,130,605,202,0
Obsessive,40,180,160,135,630,210,0
Devil,40,184,164,135,666,222,0
"Liche Prince",40,190,168,138,660,220,0
Cherufiend,41,195,170,140,690,230,0
"Red Dragon",41,200,180,145,720,240,0
"Greater Devil",41,200,180,145,750,250,0
Renegade,42,205,185,150,780,260,0
Archfiend,42,210,190,150,810,270,0
"Liche Lord",42,210,190,155,850,283,0
"Greatest Devil",43,215,195,160,890,297,0
"Dark Knight",43,220,200,160,930,310,0
Giant,43,220,200,165,970,323,0
"Shadow Dragon",44,225,200,170,1010,337,0
"Liche King",44,225,205,170,1050,350,0
Incubus,44,230,205,175,1100,367,1
Traitor,45,230,205,175,1150,383,0
Demon,45,240,210,180,1200,400,0
"Dark Dragon",45,245,215,180,1250,417,1
Insurgent,46,250,220,190,1300,433,0
Leviathan,46,255,225,190,1350,450,0
"Grey Daemon",46,260,230,190,1400,467,0
Succubus,47,265,240,200,1460,487,1
"Demon Prince",47,270,240,200,1520,507,0
"Black Dragon",47,275,250,205,1580,527,1
Nihilist,47,280,250,205,1640,547,0
Behemoth,48,285,260,210,1700,567,0
Demagogue,48,290,260,210,1760,587,0
"Demon Lord",48,300,270,220,1820,607,0
"Red Daemon",48,310,280,230,1880,627,0
Colossus,49,320,300,240,1940,647,0
"Demon King",49,330,300,250,2000,667,0
"Dark Daemon",49,340,320,260,2200,733,1
Titan,50,360,340,270,2400,800,0
"Black Daemon",50,400,400,280,3000,1000,1
Lucifuge,50,600,600,400,10000,10000,2
1 Name Level HP ATK DEF EXP Gold Immune
2 Blue Slime 1 4 3 1 1 1 0
3 Red Slime 1 6 5 1 2 1 0
4 Critter 1 6 5 2 4 2 0
5 Creature 2 10 8 2 4 2 0
6 Shadow 2 10 9 3 6 2 1
7 Drake 2 11 10 3 8 3 0
8 Shade 3 12 10 3 10 3 1
9 Drakelor 3 14 12 4 10 3 0
10 Silver Slime 30 15 100 200 15 1000 2
11 Scamp 4 16 13 5 15 5 0
12 Raven 4 16 13 5 18 6 0
13 Scorpion 5 18 14 6 20 7 0
14 Illusion 5 20 15 6 20 7 1
15 Nightshade 6 22 16 6 24 8 0
16 Drakemal 6 22 18 7 24 8 0
17 Shadow Raven 6 24 18 7 26 9 1
18 Ghost 6 24 20 8 28 9 0
19 Frost Raven 7 26 20 8 30 10 0
20 Rogue Scorpion 7 28 22 9 32 11 0
21 Ghoul 7 29 24 9 34 11 0
22 Magician 8 30 24 10 36 12 0
23 Rogue 8 30 25 12 40 13 0
24 Drakefin 8 32 26 12 40 13 0
25 Shimmer 8 32 26 14 45 15 1
26 Fire Raven 9 34 28 14 45 15 0
27 Dybbuk 9 34 28 14 50 17 0
28 Knave 9 36 30 15 52 17 0
29 Goblin 10 36 30 15 54 18 0
30 Skeleton 10 38 30 18 58 19 0
31 Dark Slime 10 38 32 18 62 21 0
32 Silver Scorpion 40 30 160 350 63 2000 2
33 Mirage 11 40 32 20 64 21 1
34 Sorceror 11 41 33 22 68 23 0
35 Imp 12 42 34 22 70 23 0
36 Nymph 12 43 35 22 70 23 0
37 Scoundrel 12 43 35 22 75 25 0
38 Megaskeleton 13 44 36 24 78 26 0
39 Grey Wolf 13 44 36 24 82 27 0
40 Phantom 14 46 38 24 85 28 1
41 Specter 14 46 38 24 90 30 0
42 Dark Scorpion 15 48 40 26 95 32 1
43 Warlock 15 48 40 26 100 33 1
44 Orc 15 49 42 28 104 35 0
45 Sylph 15 49 42 28 106 35 0
46 Wraith 16 50 45 30 108 36 0
47 Hellion 16 50 45 30 110 37 0
48 Bandit 16 52 45 30 114 38 0
49 Ultraskeleton 16 52 46 32 116 39 0
50 Dark Wolf 17 54 47 36 120 40 1
51 Troll 17 56 48 36 120 40 0
52 Werewolf 17 56 48 38 124 41 0
53 Hellcat 18 58 50 38 128 43 0
54 Spirit 18 58 50 38 132 44 0
55 Nisse 19 60 52 40 132 44 0
56 Dawk 19 60 54 40 136 45 0
57 Figment 19 64 55 42 140 47 1
58 Hellhound 20 66 56 44 140 47 0
59 Wizard 20 66 56 44 144 48 0
60 Uruk 20 68 58 44 146 49 0
61 Siren 50 68 400 800 10000 50 2
62 Megawraith 21 70 60 46 155 52 0
63 Dawkin 21 70 60 46 155 52 0
64 Grey Bear 21 70 62 48 160 53 0
65 Haunt 22 72 62 48 160 53 0
66 Hellbeast 22 74 64 50 165 55 0
67 Fear 23 76 66 52 165 55 0
68 Beast 23 76 66 52 170 57 0
69 Ogre 23 78 68 54 170 57 0
70 Dark Bear 24 80 70 56 175 58 1
71 Fire 24 80 72 56 175 58 0
72 Polgergeist 25 84 74 58 180 60 0
73 Fright 25 86 76 58 180 60 0
74 Lycan 25 88 78 60 185 62 0
75 Terra Elemental 25 88 80 62 185 62 1
76 Necromancer 26 90 80 62 190 63 0
77 Ultrawraith 26 90 82 64 190 63 0
78 Dawkor 26 92 82 64 195 65 0
79 Werebear 26 92 84 65 195 65 0
80 Brute 27 94 84 65 200 67 0
81 Large Beast 27 96 88 66 200 67 0
82 Horror 27 96 88 68 210 70 0
83 Flame 28 100 90 70 210 70 0
84 Lycanthor 28 100 90 70 210 70 0
85 Wyrm 28 100 92 72 220 73 0
86 Aero Elemental 29 104 94 74 220 73 1
87 Dawkare 29 106 96 76 220 73 0
88 Large Brute 29 108 98 78 230 77 0
89 Frost Wyrm 30 110 100 80 230 77 0
90 Knight 30 110 102 80 240 80 0
91 Lycanthra 30 112 104 82 240 80 0
92 Terror 31 115 108 84 250 83 0
93 Blaze 31 118 108 84 250 83 0
94 Aqua Elemental 31 120 110 90 260 87 1
95 Fire Wyrm 32 120 110 90 260 87 0
96 Lesser Wyvern 32 122 110 92 270 90 0
97 Doomer 32 124 112 92 270 90 0
98 Armor Knight 33 130 115 95 280 93 0
99 Wyvern 33 134 120 95 290 97 0
100 Nightmare 33 138 125 100 300 100 0
101 Fira Elemental 34 140 125 100 310 103 1
102 Megadoomer 34 140 128 105 320 107 0
103 Greater Wyvern 34 145 130 105 335 112 0
104 Advocate 35 148 132 108 350 117 0
105 Strong Knight 35 150 135 110 365 122 0
106 Liche 35 150 135 110 380 127 0
107 Ultradoomer 36 155 140 115 395 132 0
108 Fanatic 36 160 140 115 410 137 0
109 Green Dragon 36 160 140 115 425 142 0
110 Fiend 37 160 145 120 445 148 0
111 Greatest Wyvern 37 162 150 120 465 155 0
112 Lesser Devil 37 164 150 120 485 162 0
113 Liche Master 38 168 155 125 505 168 0
114 Zealot 38 168 155 125 530 177 0
115 Serafiend 38 170 155 125 555 185 0
116 Pale Knight 39 175 160 130 580 193 0
117 Blue Dragon 39 180 160 130 605 202 0
118 Obsessive 40 180 160 135 630 210 0
119 Devil 40 184 164 135 666 222 0
120 Liche Prince 40 190 168 138 660 220 0
121 Cherufiend 41 195 170 140 690 230 0
122 Red Dragon 41 200 180 145 720 240 0
123 Greater Devil 41 200 180 145 750 250 0
124 Renegade 42 205 185 150 780 260 0
125 Archfiend 42 210 190 150 810 270 0
126 Liche Lord 42 210 190 155 850 283 0
127 Greatest Devil 43 215 195 160 890 297 0
128 Dark Knight 43 220 200 160 930 310 0
129 Giant 43 220 200 165 970 323 0
130 Shadow Dragon 44 225 200 170 1010 337 0
131 Liche King 44 225 205 170 1050 350 0
132 Incubus 44 230 205 175 1100 367 1
133 Traitor 45 230 205 175 1150 383 0
134 Demon 45 240 210 180 1200 400 0
135 Dark Dragon 45 245 215 180 1250 417 1
136 Insurgent 46 250 220 190 1300 433 0
137 Leviathan 46 255 225 190 1350 450 0
138 Grey Daemon 46 260 230 190 1400 467 0
139 Succubus 47 265 240 200 1460 487 1
140 Demon Prince 47 270 240 200 1520 507 0
141 Black Dragon 47 275 250 205 1580 527 1
142 Nihilist 47 280 250 205 1640 547 0
143 Behemoth 48 285 260 210 1700 567 0
144 Demagogue 48 290 260 210 1760 587 0
145 Demon Lord 48 300 270 220 1820 607 0
146 Red Daemon 48 310 280 230 1880 627 0
147 Colossus 49 320 300 240 1940 647 0
148 Demon King 49 330 300 250 2000 667 0
149 Dark Daemon 49 340 320 260 2200 733 1
150 Titan 50 360 340 270 2400 800 0
151 Black Daemon 50 400 400 280 3000 1000 1
152 Lucifuge 50 600 600 400 10000 10000 2

View File

@ -0,0 +1,21 @@
Name,Type,MP,Effect,Icon
Heal,1,5,"heal:self,10",heal.png
Cure,1,10,"heal:self,25",cure.png
Breath,1,25,"heal:self,50",breath.png
Revive,1,50,"heal:self,100",revive.png
Gaia,1,75,"heal:self,150",gaia.png
Slash,2,5,"damage:opp,10",slash.png
"Magic Missile",2,12,"damage:opp,35",missile.png
Fireball,2,25,"damage:opp,70",fireball.png
Pain,2,40,"damage:opp,100",pain.png
Lightning,2,50,"damage:opp,130",lightning.png
Chaos,2,75,"damage:opp,200",chaos.png
Sleep,3,10,"sleep:opp,3",sleep.png
Dream,3,30,"sleep:opp,6",dream.png
Nightmare,3,60,"sleep:opp,13",nightmare.png
Craze,4,10,"rage:self,3",craze.png
Rage,4,30,"rage:self,6",rage.png
Fury,4,60,"rage:self,13",fury.png
Ward,5,10,"protect:self,3",ward.png
Guard,5,30,"protect:self,6",guard.png
Barrier,5,60,"protect:self,13",barrier.png
1 Name Type MP Effect Icon
2 Heal 1 5 heal:self,10 heal.png
3 Cure 1 10 heal:self,25 cure.png
4 Breath 1 25 heal:self,50 breath.png
5 Revive 1 50 heal:self,100 revive.png
6 Gaia 1 75 heal:self,150 gaia.png
7 Slash 2 5 damage:opp,10 slash.png
8 Magic Missile 2 12 damage:opp,35 missile.png
9 Fireball 2 25 damage:opp,70 fireball.png
10 Pain 2 40 damage:opp,100 pain.png
11 Lightning 2 50 damage:opp,130 lightning.png
12 Chaos 2 75 damage:opp,200 chaos.png
13 Sleep 3 10 sleep:opp,3 sleep.png
14 Dream 3 30 sleep:opp,6 dream.png
15 Nightmare 3 60 sleep:opp,13 nightmare.png
16 Craze 4 10 rage:self,3 craze.png
17 Rage 4 30 rage:self,6 rage.png
18 Fury 4 60 rage:self,13 fury.png
19 Ward 5 10 protect:self,3 ward.png
20 Guard 5 30 protect:self,6 guard.png
21 Barrier 5 60 protect:self,13 barrier.png

View File

@ -0,0 +1,9 @@
Name,X,Y,"Inn Cost","Map Cost","TP Cost","Shop List",Image
Midworld,0,0,5,5,0,"1,2,3,17,18,19,28,29",midworld.png
Roma,30,30,10,25,5,"2,3,4,18,19,29",roma.png
Bris,70,-70,25,50,15,"2,3,4,5,18,19,20,29,30",bris.png
Kalle,-100,100,40,100,30,"5,6,8,10,12,21,22,23,29,30",kalle.png
Narcissa,-130,-130,60,500,50,"4,7,9,11,13,21,22,23,29,30,31",narcissa.png
Hambry,170,170,90,1000,80,"10,11,12,13,14,23,24,30,31",hambry.png
Gilead,200,-200,100,3000,110,"12,13,14,15,24,25,26,32",gilead.png
Endworld,-250,-250,150,9000,160,"16,27,33",endworld.png
1 Name X Y Inn Cost Map Cost TP Cost Shop List Image
2 Midworld 0 0 5 5 0 1,2,3,17,18,19,28,29 midworld.png
3 Roma 30 30 10 25 5 2,3,4,18,19,29 roma.png
4 Bris 70 -70 25 50 15 2,3,4,5,18,19,20,29,30 bris.png
5 Kalle -100 100 40 100 30 5,6,8,10,12,21,22,23,29,30 kalle.png
6 Narcissa -130 -130 60 500 50 4,7,9,11,13,21,22,23,29,30,31 narcissa.png
7 Hambry 170 170 90 1000 80 10,11,12,13,14,23,24,30,31 hambry.png
8 Gilead 200 -200 100 3000 110 12,13,14,15,24,25,26,32 gilead.png
9 Endworld -250 -250 150 9000 160 16,27,33 endworld.png

View File

@ -57,25 +57,6 @@ function dd(mixed $var, bool $r = false)
exit;
}
/**
* Creates a new user. Optionally pass an array of additional fields to add. Returns the user ID, or 0 if failed.
*/
function createUser(string $username, string $password, string $email, int $class = 1, array $addtl = []): int
{
// @BAD Yes, this is bad, but it works.
global $db;
$data = [
'username' => trim($username),
'password' => password_hash($password, PASSWORD_ARGON2ID),
'email' => trim($email),
'class_id' => $class
];
$db->table('players')->insert(array_merge($data, $addtl));
return $db->lastInsertId();
}
function getmicrotime() { // Used for timing script operations.
list($usec, $sec) = explode(" ",microtime());

10
server/models/Classes.php Normal file
View File

@ -0,0 +1,10 @@
<?php
class Classes
{
public static function all(): array|false
{
$res = App::$db->q("SELECT * FROM classes");
return $res->fetchAll() ?: false;
}
}

13
server/models/Player.php Normal file
View File

@ -0,0 +1,13 @@
<?php
class Player
{
public static function create(array $data): int
{
$keys = implode(', ', array_keys($data));
$placeholders = implode(', ', array_fill(0, count($data), '?'));
App::$db->do("INSERT INTO 'players' ($keys) VALUES ($placeholders);", array_values($data));
return App::$db->lastInsertID();
}
}

View File

@ -13,6 +13,8 @@ class InstallModule
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()
@ -25,86 +27,262 @@ class InstallModule
$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
$resFmt = '%s <span class="extra-data">(%ss)</span><br />';
$defaults = SERVER.'/database/packs/Default/';
$results = '';
// 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
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
);");
$results .= sprintf($resFmt, 'Settings table created', stopwatch($istart));
// insert default settings
App::$db->q("INSERT INTO settings DEFAULT VALUES;");
$results .= sprintf($resFmt, 'Default settings inserted', stopwatch($istart));
// @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 '',
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 ''
);");
$results .= sprintf($resFmt, 'Classes table created', stopwatch($istart));
if ($complete) {
// add default classes if complete install
App::$db->q("INSERT INTO classes VALUES
(1, 'Mage', 10, 10, 5, 5, 5, 5, 3, 5, 1, 3, 1, 3, '1:6,18'),
(2, 'Warrior', 20, 0, 10, 5, 10, 5, 6, 2, 3, 1, 3, 1, ''),
(3, 'Paladin', 15, 5, 5, 5, 10, 10, 4, 4, 2, 2, 2, 2, '1:1,15,18');");
App::$db->insertFromCSV('classes', "$defaults/classes.csv");
} else {
// there must be at least one class, for user creation to work
// there must be at least one class for user creation to work
App::$db->q("INSERT INTO classes (name) VALUES ('Adventurer');");
}
$results .= sprintf($resFmt, 'Default classes inserted', stopwatch($istart));
// @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
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
);");
$results .= sprintf($resFmt, 'Babble table created', stopwatch($istart));
// @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 ''
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']);
}
}

View File

@ -6,7 +6,7 @@
</p>
<p class="mb-1">
<a href="/">Click here to log in.</a>
<a href="/gate/login">Click here to log in.</a>
</p>
<p>

View File

@ -23,7 +23,7 @@
</ul>
</p>
<p>
<p class="mb-1">
Click the appropriate button below for your preferred installation method.
<form action="/install/database" method="post">
<button type="submit" name="mode" value="complete">Complete Setup</button><br>
@ -31,3 +31,8 @@
<button type="submit" name="mode" value="partial">Partial Setup</button>
</form>
</p>
<div class="alert is-danger my-2">
<b>WARNING:</b> if the database already exists, clicking either
option will delete all existing data. This is not reversible.
</div>

View File

@ -0,0 +1,7 @@
<p class="mb-1">
That's weird... you're not supposed to be here.
</p>
<p class="mb-1">
<a href="/">Go back.</a>
</p>

View File

@ -1,9 +1,9 @@
<form action="/install/?step=third" method="post" style="max-width: 300px;">
<form action="/install/finish" method="post" style="max-width: 300px;">
<input type="hidden" name="complete" value="<?= $complete ? "true" : "false" ?>">
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" id="username">
<input type="text" name="username" id="username" required>
</div>
<div class="form-group">
@ -20,9 +20,9 @@
<div class="form-group">
<label for="class">Class</label>
<select name="class" id="class">
<option value="1">Mage</option>
<option value="2">Paladin</option>
<option value="3">Warrior</option>
<?php foreach (Classes::all() as $class): ?>
<option value="<?= $class['id'] ?>"><?= $class['name'] ?></option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>

View File

@ -22,4 +22,4 @@
panel.<?php endif; ?>
</p>
<?= render('install/partials/adminForm', ['complete' => $complete]) ?>
<?= render('install/partials/adminForm', ['complete' => $complete]) ?>