Compare commits

...

7 Commits

Author SHA1 Message Date
4eb4d29a5b Finish install 2 2024-07-02 10:04:20 -05:00
624e2a7bc8 Finish install step 1 2024-07-02 09:34:38 -05:00
30b6b46823 Add db file to gitignore 2024-07-01 20:59:19 -05:00
bbb7a84ad0 Update form styling 2024-07-01 20:58:49 -05:00
7659cbed52 Reorganize, update install to step two 2024-07-01 20:53:23 -05:00
6bad6a1816 Remove upgrades 2024-07-01 15:40:59 -05:00
6f068d25f3 Update readme/license 2024-07-01 15:35:14 -05:00
78 changed files with 1203 additions and 592 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
server/database/dragon.db

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2017 renderse7en
Copyright (c) 2024 Sharkk
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,51 +1,2 @@
# Dragon Knight
- See also: [Dragon Scourge](https://github.com/renderse7en/dragon-scourge)
- [Live Demo](http://dragon.se7enet.com/)
Many years ago, when I was young and dumb, I wrote a simple little game based on the game *Dragon Warrior* for the NES. It was fun, it helped me learn how to code, and a lot of people liked it.
I am now turning it over to the open source community. Fork it, do what you want, make it your own.
Couple things to keep in mind though:
- It's super old. It may not even work on modern versions of PHP. It may have security issues. I have no idea.
- I have moved on with my life, and am no longer changing or doing anything with this game.
- I am not providing help or support. You're on your own.
- I am not accepting pull requests. If you fork this, you are welcome to do whatever you want, but no changes will be merged back into this.
- Quite frankly, I don't really suggest that you use this as is. It's probably better as an inspiration for your own project.
- Have fun with this. I gave it a lot of love a long time ago. I hope it inspires you to give something a lot of love as well.
- This Git repo represents the final released version, 1.1.11, originally released 3/26/2006.
# System Requirements
- PHP (4.1 and higher)
- MySQL
- zlib compression enabled on your server (optional)
# Installation Instructions
1. Clone this repo or download the zip.
2. Create a new database for Dragon Knight to use, if you don't already have one set up.
3. Edit `config.php` to include the correct values for your database setup.
4. Upload the contents of the Dragon Knight folder to your site.
5. In your browser, run `install.php` and follow the instructions.
6. After completing installation, delete `install.php` from your Dragon Knight directory for security.
7. Enjoy the game.
# License
MIT License
Copyright (c) 2017 renderse7en
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
todo...

View File

@ -1,11 +0,0 @@
<?php // config.php :: Low-level app/database variables.
$dbsettings = Array(
"server" => "localhost", // MySQL server name. (Default: localhost)
"user" => "", // MySQL username.
"pass" => "", // MySQL password.
"name" => "", // MySQL database name.
"prefix" => "dk", // Prefix for table names. (Default: dk)
"secretword" => ""); // Secret word used when hashing information for cookies.
?>

39
public/css/dragon.css Normal file
View File

@ -0,0 +1,39 @@
* {
box-sizing: border-box;
}
body {
font-size: 16px;
background-image: url(/img/bg/bg.webp);
background-repeat: repeat;
}
#container {
max-width: 996px;
margin: 0 auto;
}
.form-group {
margin-bottom: 0.5rem;
label {
display: block;
font-size: 0.8rem;
}
input {
width: 100%;
}
}
.text-red {
color: #d20f39;
}
.mb-1 {
margin-bottom: 1rem;
}
.mb-2 {
margin-bottom: 2rem;
}

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

View File

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

View File

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

BIN
public/img/bg/bg.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
public/img/bg/retro.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 527 B

After

Width:  |  Height:  |  Size: 527 B

View File

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 575 B

View File

Before

Width:  |  Height:  |  Size: 561 B

After

Width:  |  Height:  |  Size: 561 B

View File

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 402 B

View File

Before

Width:  |  Height:  |  Size: 551 B

After

Width:  |  Height:  |  Size: 551 B

View File

Before

Width:  |  Height:  |  Size: 486 B

After

Width:  |  Height:  |  Size: 486 B

View File

Before

Width:  |  Height:  |  Size: 474 B

After

Width:  |  Height:  |  Size: 474 B

View File

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 500 B

View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

View File

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 565 B

View File

Before

Width:  |  Height:  |  Size: 469 B

After

Width:  |  Height:  |  Size: 469 B

View File

Before

Width:  |  Height:  |  Size: 469 B

After

Width:  |  Height:  |  Size: 469 B

View File

Before

Width:  |  Height:  |  Size: 461 B

After

Width:  |  Height:  |  Size: 461 B

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 147 B

View File

Before

Width:  |  Height:  |  Size: 121 B

After

Width:  |  Height:  |  Size: 121 B

View File

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 112 B

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1005 B

After

Width:  |  Height:  |  Size: 1005 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

5
public/index.php Normal file
View File

@ -0,0 +1,5 @@
<?php // index.php :: Primary program script, evil alien overlord, you decide.
require_once '../server/bootstrap.php';
if (!installed()) redirect('/install');

556
public/install/index.php Normal file
View File

@ -0,0 +1,556 @@
<?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',
"attr1 TEXT DEFAULT ''",
"attr2 TEXT DEFAULT ''"
]);
// Add default drops if complete install
if ($complete) {
$db->insert([
['name' => 'Life Pebble', 'level' => 1, 'type' => 1, 'attr1' => 'hp,10', 'attr2' => '' ],
['name' => 'Life Stone', 'level' => 10, 'type' => 1, 'attr1' => 'hp,25', 'attr2' => '' ],
['name' => 'Life Rock', 'level' => 25, 'type' => 1, 'attr1' => 'hp,50', 'attr2' => '' ],
['name' => 'Life Ore', 'level' => 50, 'type' => 1, 'attr1' => 'hp,100', 'attr2' => '' ],
['name' => 'Life Gem', 'level' => 75, 'type' => 1, 'attr1' => 'hp,150', 'attr2' => '' ],
['name' => 'Magic Pebble', 'level' => 1, 'type' => 1, 'attr1' => 'mp,10', 'attr2' => '' ],
['name' => 'Magic Stone', 'level' => 10, 'type' => 1, 'attr1' => 'mp,25', 'attr2' => '' ],
['name' => 'Magic Rock', 'level' => 25, 'type' => 1, 'attr1' => 'mp,50', 'attr2' => '' ],
['name' => 'Magic Ore', 'level' => 50, 'type' => 1, 'attr1' => 'mp,100', 'attr2' => '' ],
['name' => 'Magic Gem', 'level' => 75, 'type' => 1, 'attr1' => 'mp,150', 'attr2' => '' ],
['name' => "Dragon's Scale", 'level' => 10, 'type' => 1, 'attr1' => 'def,25', 'attr2' => '' ],
['name' => "Dragon's Plate", 'level' => 30, 'type' => 1, 'attr1' => 'def,50', 'attr2' => '' ],
['name' => "Dragon's Claw", 'level' => 10, 'type' => 1, 'attr1' => 'atk,25', 'attr2' => '' ],
['name' => "Dragon's Fang", 'level' => 30, 'type' => 1, 'attr1' => 'atk,50', 'attr2' => '' ],
['name' => "Dragon's Tear", 'level' => 35, 'type' => 1, 'attr1' => 'str,75', 'attr2' => '' ],
['name' => "Dragon's Wing", 'level' => 35, 'type' => 1, 'attr1' => 'dex,75', 'attr2' => '' ],
['name' => "Demon's Sin", 'level' => 35, 'type' => 1, 'attr1' => 'hp,-50', 'attr2' => 'str,50' ],
['name' => "Demon's Fall", 'level' => 35, 'type' => 1, 'attr1' => 'mp,-50', 'attr2' => 'str,50' ],
['name' => "Demon's Lie", 'level' => 45, 'type' => 1, 'attr1' => 'hp,-100', 'attr2' => 'str,100' ],
['name' => "Demon's Hate", 'level' => 45, 'type' => 1, 'attr1' => 'mp,-100', 'attr2' => 'str,100' ],
['name' => "Angel's Joy", 'level' => 25, 'type' => 1, 'attr1' => 'hp,25', 'attr2' => 'str,25' ],
['name' => "Angel's Rise", 'level' => 30, 'type' => 1, 'attr1' => 'hp,50', 'attr2' => 'str,50' ],
['name' => "Angel's Truth", 'level' => 35, 'type' => 1, 'attr1' => 'hp,75', 'attr2' => 'str,75' ],
['name' => "Angel's Grace", 'level' => 40, 'type' => 1, 'attr1' => 'hp,100', 'attr2' => 'str,100' ],
['name' => "Seraph's Strength", 'level' => 25, 'type' => 1, 'attr1' => 'mp,25', 'attr2' => 'dex,25' ],
['name' => "Seraph's Power", 'level' => 30, 'type' => 1, 'attr1' => 'mp,50', 'attr2' => 'dex,50' ],
['name' => "Seraph's Justice", 'level' => 35, 'type' => 1, 'attr1' => 'mp,75', 'attr2' => 'dex,75' ],
['name' => "Seraph's Judgement", 'level' => 40, 'type' => 1, 'attr1' => 'mp,100', 'attr2' => 'dex,100' ],
['name' => 'Ruby', 'level' => 50, 'type' => 1, 'attr1' => 'hp,150', 'attr2' => '' ],
['name' => 'Sapphire', 'level' => 50, 'type' => 1, 'attr1' => 'mp,150', 'attr2' => '' ],
['name' => 'Emerald', 'level' => 50, 'type' => 1, 'attr1' => 'str,150', 'attr2' => '' ],
['name' => 'Amethyst', 'level' => 50, 'type' => 1, 'attr1' => 'dex,150', 'attr2' => '' ],
['name' => 'Topaz', 'level' => 50, 'type' => 1, 'attr1' => 'atk,150', 'attr2' => '' ],
['name' => 'Diamond', 'level' => 50, 'type' => 1, 'attr1' => 'def,150', 'attr2' => '' ],
['name' => "Ocean Blessing", 'level' => 77, 'type' => 1, 'attr1' => 'str,7007', 'attr2' => 'dex,7007'],
['name' => 'Memory Tonic', 'level' => 5, 'type' => 1, 'attr1' => 'exp,10', 'attr2' => '' ],
['name' => 'Memory Potion', 'level' => 30, 'type' => 1, 'attr1' => 'exp,20', 'attr2' => '' ],
['name' => 'Memory Elixir', 'level' => 50, 'type' => 1, 'attr1' => 'exp,30', 'attr2' => '' ],
['name' => 'Gold Tonic', 'level' => 5, 'type' => 1, 'attr1' => 'gold,10', 'attr2' => '' ],
['name' => 'Gold Potion', 'level' => 30, 'type' => 1, 'attr1' => 'gold,20', 'attr2' => '' ],
['name' => 'Gold Elixir', 'level' => 50, 'type' => 1, 'attr1' => 'gold,30', 'attr2' => '' ],
]);
}
// 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',
"attr1 TEXT DEFAULT ''",
"attr2 TEXT DEFAULT ''",
"icon TEXT DEFAULT ''"
]);
// Create default items, if complete install
if ($complete) {
$db->insert([
// Type 1 - weapons
['type' => 1, 'name' => 'Stick', 'cost' => 10, 'attr1' => 'atk,2', 'attr2' => '', 'icon' => 'stick.png' ],
['type' => 1, 'name' => 'Branch', 'cost' => 30, 'attr1' => 'atk,4', 'attr2' => '', 'icon' => 'branch.png' ],
['type' => 1, 'name' => 'Club', 'cost' => 40, 'attr1' => 'atk,6', 'attr2' => '', 'icon' => 'club.png' ],
['type' => 1, 'name' => 'Dagger', 'cost' => 80, 'attr1' => 'atk,8', 'attr2' => '', 'icon' => 'dagger.png' ],
['type' => 1, 'name' => 'Hatchet', 'cost' => 120, 'attr1' => 'atk,12', 'attr2' => '', 'icon' => 'hatchet.png' ],
['type' => 1, 'name' => 'Axe', 'cost' => 200, 'attr1' => 'atk,18', 'attr2' => '', 'icon' => 'axe.png' ],
['type' => 1, 'name' => 'Spear', 'cost' => 300, 'attr1' => 'atk,25', 'attr2' => '', 'icon' => 'spear.png' ],
['type' => 1, 'name' => 'Poleaxe', 'cost' => 500, 'attr1' => 'atk,35', 'attr2' => '', 'icon' => 'poleaxe.png' ],
['type' => 1, 'name' => 'Warhammer', 'cost' => 800, 'attr1' => 'atk,50', 'attr2' => '', 'icon' => 'warhammer.png' ],
['type' => 1, 'name' => 'Longsword', 'cost' => 1200, 'attr1' => 'atk,65', 'attr2' => '', 'icon' => 'longsword.png' ],
['type' => 1, 'name' => 'Claymore', 'cost' => 1800, 'attr1' => 'atk,85', 'attr2' => '', 'icon' => 'claymore.png' ],
['type' => 1, 'name' => 'Demon Axe', 'cost' => 2800, 'attr1' => 'atk,125', 'attr2' => 'exp,-5', 'icon' => 'demonaxe.png' ],
['type' => 1, 'name' => 'Dark Sword', 'cost' => 4500, 'attr1' => 'atk,225', 'attr2' => 'exp,-10', 'icon' => 'darksword.png' ],
['type' => 1, 'name' => 'Magic Axe', 'cost' => 2800, 'attr1' => 'atk,95', 'attr2' => 'exp,5', 'icon' => 'magicaxe.png' ],
['type' => 1, 'name' => 'Bright Sword', 'cost' => 4500, 'attr1' => 'atk,185', 'attr2' => 'exp,10', 'icon' => 'brightsword.png'],
['type' => 1, 'name' => 'Dragonbane', 'cost' => 10000, 'attr1' => 'atk,300', 'attr2' => 'str,50', 'icon' => 'dragonbane.png' ],
// Type 2 - armors
['type' => 2, 'name' => 'Underwear', 'cost' => 25, 'attr1' => 'def,2', 'attr2' => 'gold,10', 'icon' => 'underwear.png' ],
['type' => 2, 'name' => 'Clothes', 'cost' => 50, 'attr1' => 'def,5', 'attr2' => '', 'icon' => 'clothes.png' ],
['type' => 2, 'name' => 'Leather', 'cost' => 75, 'attr1' => 'def,10', 'attr2' => '', 'icon' => 'leather.png' ],
['type' => 2, 'name' => 'Hard Leather', 'cost' => 150, 'attr1' => 'def,25', 'attr2' => '', 'icon' => 'hardleather.png' ],
['type' => 2, 'name' => 'Chainmail', 'cost' => 300, 'attr1' => 'def,35', 'attr2' => '', 'icon' => 'chainmail.png' ],
['type' => 2, 'name' => 'Scale Armor', 'cost' => 900, 'attr1' => 'def,50', 'attr2' => '', 'icon' => 'scalearmor.png' ],
['type' => 2, 'name' => 'Platemail', 'cost' => 1800, 'attr1' => 'def,100', 'attr2' => '', 'icon' => 'platemail.png' ],
['type' => 2, 'name' => 'Magic Plate', 'cost' => 3000, 'attr1' => 'def,125', 'attr2' => 'mp,50', 'icon' => 'magicplate.png' ],
['type' => 2, 'name' => 'Darkmail', 'cost' => 5000, 'attr1' => 'def,200', 'attr2' => 'exp,-10', 'icon' => 'darkmail.png' ],
['type' => 2, 'name' => 'Dragon Plate', 'cost' => 10000, 'attr1' => 'def,165', 'attr2' => 'exp,10', 'icon' => 'dragonplate.png' ],
['type' => 2, 'name' => 'Destiny Raiment', 'cost' => 50000, 'attr1' => 'def,200', 'attr2' => 'dex,50', 'icon' => 'destinyraiment.png'],
// Type 3 - shields
['type' => 3, 'name' => 'Reed Shield', 'cost' => 50, 'attr1' => 'def,5', 'attr2' => '', 'icon' => 'reedshield.png' ],
['type' => 3, 'name' => 'Buckler', 'cost' => 100, 'attr1' => 'def,10', 'attr2' => '', 'icon' => 'nuckler.png' ],
['type' => 3, 'name' => 'Round Shield', 'cost' => 500, 'attr1' => 'def,25', 'attr2' => '', 'icon' => 'roundshield.png' ],
['type' => 3, 'name' => 'Tower Shield', 'cost' => 2500, 'attr1' => 'def,50', 'attr2' => '', 'icon' => 'towershield.png' ],
['type' => 3, 'name' => 'Silver Shield', 'cost' => 10000, 'attr1' => 'def,100', 'attr2' => '', 'icon' => 'silvershield.png'],
['type' => 3, 'name' => 'Dragon Shield', 'cost' => 25000, 'attr1' => 'def,125', 'attr2' => 'mp,100', 'icon' => 'dragonshield.png'],
['type' => 3, 'name' => 'Aegis', 'cost' => 50000, 'attr1' => 'def,225', 'attr2' => 'exp,10', 'icon' => 'aegis.png' ]
]);
}
// 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',
'user_hp INTEGER DEFAULT 0',
'user_mp INTEGER DEFAULT 0',
'monster_hp INTEGER DEFAULT 0',
'monster_mp INTEGER DEFAULT 0',
'user_uber_dmg INTEGER DEFAULT 0',
'monster_uber_dmg INTEGER DEFAULT 0',
'user_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;
}

15
server/bootstrap.php Normal file
View File

@ -0,0 +1,15 @@
<?php // bootstrap.php :: Initialize all our boring stuff
ini_set('display_errors', 'on');
error_reporting(E_ALL | E_STRICT);
$start = microtime(true);
session_start();
const VERSION = '1.1.11';
const BUILD = '';
const DB = SERVER.'/database/dragon.db';
require_once SERVER.'/library.php';
require_once SERVER.'/database.php';

374
server/database.php Normal file
View File

@ -0,0 +1,374 @@
<?php
/**
* SQLite database wrapper class. Provides a non-static interface to interact with a
* SQLite database in as simple a way as possible.
*
* The wrapper provides a simple-to-use database API using PDO's SQLite driver.
* It was designed to have method signatures very close to Laravel's Eloquent ORM. There
* are not, however, any ORM features in the wrapper. These must be handled at
* the model level.
*
* By default, foreign keys are enabled and the database is in WAL mode. In general
* these defaults should be perfect for most use cases.
*/
class Database
{
/**
* The PDO handle.
*/
private PDO $c;
/**
* The current working table.
*/
private string $table = '';
/**
* The number of queries executed.
*/
private int $queries = 0;
/**
* The log of executed queries.
*/
private array $log = [];
/**
* The last error.
*/
private string $error = '';
/**
* The array for the query builder.
*/
private array $builder = [
'where' => [],
'order' => [],
'limit' => 0,
'values' => [],
];
/**
* Open a connection to the database.
*/
public function __construct(string $path, array $opts = [])
{
$opts = !empty($opts) ? $opts : [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$this->c = new PDO("sqlite:$path", null, null, $opts);
$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;
}
}
/**
* Change the current working table.
*/
public function table(string $name): Database
{
$this->table = $name;
return $this;
}
/**
* Create a table with the name of the current working table. Will drop
* the table if it already exists.
*/
public function create(array $columns): PDOStatement|false
{
$query = "CREATE TABLE IF NOT EXISTS $this->table (" . implode(', ', $columns) . ');';
$this->addToLog($query);
return $this->c->query($query);
}
/**
* Drop the current working table if it exists.
*/
public function drop(): PDOStatement|false
{
$query = "DROP TABLE IF EXISTS $this->table;";
$this->addToLog($query);
return $this->c->query($query);
}
/**
* Return the current working table's schema.
*/
public function schema(): array
{
$query = "PRAGMA table_info($this->table);";
$this->addToLog($query);
return $this->c->query($query)->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Insert data into the current working table. Pass an array of key/value
* pairs to insert one record, or an array of arrays to insert multiple. Returns
* the number of rows inserted, or false on failure.
*/
public function insert(array $data): int|false
{
// If the first element is not an array we can assume we're doing a single insert.
if (!isset($data[0])) {
$query = "INSERT INTO $this->table (" . implode(', ', array_keys($data)) . ')'
. ' VALUES (' . implode(', ', array_fill(0, count($data), '?')) . ');';
$this->addToLog($query);
return $this->c->prepare($query)->execute(array_values($data));
}
// Otherwise we will build a multi-insert query.
$query = "INSERT INTO $this->table (" . implode(', ', array_keys($data[0])) . ') VALUES ';
$placeholders = [];
$values = [];
foreach ($data as $row) {
$placeholders[] = '(' . implode(', ', array_fill(0, count($row), '?')) . ')';
foreach ($row as $value) $values[] = $value;
}
$query .= implode(', ', $placeholders) . ';';
$this->addToLog($query);
return $this->c->prepare($query)->execute($values);
}
/**
* Insert a default record into the current working table.
*/
public function insertDefaultValues(): int|false
{
$query = "INSERT INTO $this->table DEFAULT VALUES;";
$this->addToLog($query);
return $this->c->prepare($query)->execute();
}
/**
* Add a where clause to the builder. All values are paramaterized.
*/
public function where(string $column, string $operator, mixed $value): Database
{
$this->builder['where'][] = "$column $operator ?";
$this->builder['values'][] = $value;
return $this;
}
/**
* Add an order clause to the builder.
*/
public function order(string $column, string $direction = 'ASC'): Database
{
$this->builder['order'] = "$column $direction";
return $this;
}
/**
* Set a limit in the builder.
*/
public function limit(int $limit): Database
{
$this->builder['limit'] = $limit;
return $this;
}
/**
* Build a select query and return the result. By default selects the entire
* row. Optionally use fetchAll, but there is also the selectAll() alias method
* for this.
*/
public function select(string $what = '*', bool $fetchAll = false): array|false
{
$query = "SELECT $what FROM $this->table";
if (!empty($this->builder['where'])) $query .= " WHERE " . implode(' AND ', $this->builder['where']);
if (!empty($this->builder['order'])) $query .= " ORDER BY " . $this->builder['order'];
if (!empty($this->builder['limit'])) $query .= " LIMIT " . $this->builder['limit'];
$this->addToLog($query);
try {
$stmt = $this->c->prepare($query);
$stmt->execute($this->builder['values']);
} catch (PDOException $e) {
$this->error = "Failed to execute query: " . $e->getMessage();
return false;
}
$this->resetBuilder();
return $fetchAll ? $stmt->fetchAll() : $stmt->fetch();
}
/**
* Delete records from the current working table. Returns the number of rows
* deleted, or false on failure. Uses where clauses if set.
*/
public function delete(): int|false
{
$query = "DELETE FROM $this->table";
if (!empty($this->builder['where'])) $query .= " WHERE " . implode(' AND ', $this->builder['where']);
$this->addToLog($query);
$this->resetBuilder();
return $this->c->exec($query);
}
/**
* Update records in the current working table. Returns the number of rows
* updated, or false on failure. Uses where clauses if set.
*/
public function update(array $data): int|false
{
$query = "UPDATE $this->table SET " . implode(', ', array_keys($data)) . ' = ?';
if (!empty($this->builder['where'])) $query .= " WHERE " . implode(' AND ', $this->builder['where']);
$this->addToLog($query);
$values = array_merge(array_values($data), $this->builder['values']);
$this->resetBuilder();
return $this->c->prepare($query)->execute($values);
}
/**
* Get the number of rows in the current working table. Can use where clauses.
*/
public function count(): int|false
{
return $this->select('COUNT(*)', true)[0]['COUNT(*)'];
}
/**
* Alias for $db->select(true)
*/
public function selectAll(string $what = '*'): array|false
{
return $this->select($what, true);
}
/**
* Return whether the given table exists.
*/
public function tableExists(string $name): bool
{
$query = "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='$name';";
$this->addToLog($query);
return $this->c->query($query)->fetchColumn() > 0;
}
/**
* Return the PDO instance; for when more complex operations are needed.
*/
public function c(): PDO
{
return $this->c;
}
/**
* Alias for PDO::prepare
*/
public function prepare(string $query): PDOStatement
{
return $this->c->prepare($query);
}
/**
* Alias for PDO::lastInsertId
*/
public function lastInsertId(): int
{
return $this->c->lastInsertId();
}
/**
* Alias for PDO::exec
*/
public function exec(string $query): int
{
$this->addToLog($query);
return $this->c->exec($query);
}
/**
* Alias for PDO::beginTransaction
*/
public function begin(): bool
{
return $this->c->beginTransaction();
}
/**
* Alias for PDO::commit
*/
public function commit(): bool
{
return $this->c->commit();
}
/**
* Alias for PDO::rollBack
*/
public function rollBack(): bool
{
return $this->c->rollBack();
}
/**
* Alias for PDO::query
*/
public function query(string $query): PDOStatement|false
{
$this->addToLog($query);
return $this->c->query($query);
}
/**
* Add the query to the log and increment the number of queries executed.
*/
private function addToLog(string $query): void
{
$this->log[] = $query;
$this->queries++;
}
/**
* Reset the builder to it's default structure.
*/
public function resetBuilder(): void
{
$this->builder = [
'where' => [],
'order' => [],
'limit' => 0,
'values' => [],
];
}
/**
* Return the log of executed queries.
*/
public function log(): array
{
return $this->log;
}
/**
* Return the number of queries executed.
*/
public function queries(): int
{
return $this->queries;
}
/**
* Return the last error message.
*/
public function error(): string
{
return $this->error;
}
}

View File

@ -0,0 +1,4 @@
## /server/database
This README is here to allow git to keep this folder present in the repo.
The SQLite database for the game is generated into this folder, and PDO
will not create the path TO the SQLite database.

Binary file not shown.

Binary file not shown.

View File

@ -1,88 +1,90 @@
<?php // lib.php :: Common functions used throughout the program.
$starttime = getmicrotime();
$numqueries = 0;
$version = "1.1.11";
$build = "";
// Handling for servers with magic_quotes turned on.
// Example from php.net.
if (get_magic_quotes_gpc()) {
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
}
$_POST = array_map('addslashes_deep', $_POST);
$_POST = array_map('html_deep', $_POST);
$_GET = array_map('addslashes_deep', $_GET);
$_GET = array_map('html_deep', $_GET);
$_COOKIE = array_map('addslashes_deep', $_COOKIE);
$_COOKIE = array_map('html_deep', $_COOKIE);
function stripslashes_deep($value) {
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
<?php // library.php :: Common functions used throughout the program.
/**
* A stopwatch function to return the elapsed time in seconds.
*/
function stopwatch(float $start, int $roundTo = 3): float
{
return round(microtime(true) - $start, $roundTo);
}
function addslashes_deep($value) {
$value = is_array($value) ?
array_map('addslashes_deep', $value) :
addslashes($value);
return $value;
/**
* Redirects to a URL.
*/
function redirect(string $url): void
{
header("Location: $url");
exit;
}
function html_deep($value) {
$value = is_array($value) ?
array_map('html_deep', $value) :
htmlspecialchars($value);
return $value;
/**
* Checks if the server is installed.
*/
function installed(): bool
{
return file_exists(SERVER.'/.installed');
}
function opendb() { // Open database connection.
include('config.php');
extract($dbsettings);
$link = mysql_connect($server, $user, $pass) or die(mysql_error());
mysql_select_db($name) or die(mysql_error());
return $link;
/**
* Returns the path to a template.
*/
function template(string $name): string
{
return SERVER."/templates/$name.php";
}
function doquery($query, $table) { // Something of a tiny little database abstraction layer.
include('config.php');
global $numqueries;
$sqlquery = mysql_query(str_replace("{{table}}", $dbsettings["prefix"] . "_" . $table, $query)) or die(mysql_error());
$numqueries++;
return $sqlquery;
/**
* Renders a template. Pass data to it - uses an output buffer to have PHP process the template instead of using
* a template engine. If you're including partials in the page, call `render('partial', $data)`, as $data will still
* be available.
*/
function render(string $baseView, array $data = []): string
{
ob_start();
extract($data);
include template($baseView);
return ob_get_clean();
}
function gettemplate($templatename) { // SQL query for the template.
$filename = "templates/" . $templatename . ".php";
include("$filename");
return $template;
/**
* Checks if all required fields are set.
*/
function required(array $keys): bool
{
foreach ($keys as $key) {
if (!isset($_POST[$key]) || empty($_POST[$key])) return false;
}
return true;
}
function parsetemplate($template, $array) { // Replace template with proper content.
foreach($array as $a => $b) {
$template = str_replace("{{{$a}}}", $b, $template);
/**
* Dump and die. Useful for debugging.
*/
function dd(mixed $var, bool $r = false)
{
echo '<pre>';
$r ? print_r($var) : var_dump($var);
echo '</pre>';
exit;
}
return $template;
/**
* 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.

View File

@ -0,0 +1,15 @@
<p class="mb-1">
Congratulations, <?= $name ?>! Your installation is complete. Dragon Knight is ready to go.
All that's left is to log in and start playing. <?php if (!$complete): ?>Once you've logged in,
you can create some classes and assign your character one. By default you are a useless Adventurer.
😜<?php endif; ?>
</p>
<p class="mb-1">
<a href="/">Click here to log in.</a>
</p>
<p>
We'd love if you were to join the Sharkk community and let us know what you think!
@TODO
</p>

View File

@ -0,0 +1,33 @@
<p class="mb-1">
Installation for Dragon Knight is a simple two-step process:
set up the database tables, then create the admin user. After
that, you're done.
</p>
<p class="mb-1">
You have two options for database setup: complete or partial.
<ul>
<li>
<b>Complete Setup</b> includes table structure and all
default data (items, drops, monsters, levels, spells,
towns) - after complete setup, the game is totally
ready to run.
</li>
<li>
<b>Partial Setup</b> only creates the table structure,
it does not populate the tables - use this if you are
going to be creating or importing your own customized
game data later.
</li>
</ul>
</p>
<p>
Click the appropriate button below for your preferred installation method.
<form action="/install/?step=second" method="post">
<button type="submit" name="mode" value="complete">Complete Setup</button>
- OR - <br>
<button type="submit" name="mode" value="partial">Partial Setup</button>
</form>
</p>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $title ?> | Installer</title>
<link rel="stylesheet" href="/css/dragon.css">
</head>
<body>
<div id="container">
<h1>Dragon Knight Installation</h1>
<h2><?= $title ?></h2>
<?= render("install/$step", $data) ?>
</div>
</body>
</html>

View File

@ -0,0 +1,31 @@
<form action="/install/?step=third" 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">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" id="email" required>
</div>
<?php if ($complete): ?>
<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>
</select>
</div>
<?php endif; ?>
<button type="submit" name="submit">Submit</button>
</form>

View File

@ -0,0 +1,25 @@
<p class="mb-1">
If you're seeing this page with no errors, then database setup is complete!
It took about <?= stopwatch($start) ?> seconds.
</p>
<?php if ($complete): ?>
<p class="mb-1">
You chose a complete install, so the database has been filled with all sorts of
cool starting data! Items, drops, monsters, towns, weapons, armor, et cetera.
</p>
<?php else: ?>
<p class="mb-1">
You chose a partial install, so the database has been left empty. The onus is now
on you to fill it up with all your awesome ideas!
</p>
<?php endif; ?>
<p class="mb-1">
The next step is to create the admin account you'll run the game from. Do so
below. <?php if (!$complete): ?>Since your install was partial, you can't choose
a class here. Once you make some classes, you can assign yourself one in the admin
panel.<?php endif; ?>
</p>
<?= render('install/partials/adminForm', ['complete' => $complete]) ?>

View File

@ -0,0 +1,12 @@
<p class="mb-1">
It looks like we encountered some errors with the info provided for your
admin account. Let's try that again.
</p>
<?php
foreach ($errors as $error) {
echo '<p class="mb-1 text-red">' . $error . '</p>';
}
?>
<?= render('install/partials/adminForm', ['complete' => $complete]) ?>

View File

@ -1,96 +0,0 @@
<?
include('config.php');
include('lib.php');
$link = opendb();
$prefix = $dbsettings["prefix"];
// Thanks to Predrag Supurovic from php.net for this function!
function dobatch ($p_query) {
$query_split = preg_split ("/[;]+/", $p_query);
foreach ($query_split as $command_line) {
$command_line = trim($command_line);
if ($command_line != '') {
$query_result = mysql_query($command_line);
if ($query_result == 0) {
break;
};
};
};
return $query_result;
}
if (isset($_POST["submit"])) {
$control = $prefix . "_control";
$users = $prefix . "_users";
$query = <<<END
DROP TABLE IF EXISTS `$control`;
CREATE TABLE `$control` (
`id` tinyint(3) unsigned NOT NULL auto_increment,
`gamename` varchar(50) NOT NULL default '',
`gamesize` smallint(5) unsigned NOT NULL default '0',
`gameopen` tinyint(3) unsigned NOT NULL default '0',
`gameurl` varchar(200) NOT NULL default '',
`adminemail` varchar(100) NOT NULL default '',
`forumtype` tinyint(3) unsigned NOT NULL default '0',
`forumaddress` varchar(200) NOT NULL default '',
`class1name` varchar(50) NOT NULL default '',
`class2name` varchar(50) NOT NULL default '',
`class3name` varchar(50) NOT NULL default '',
`diff1name` varchar(50) NOT NULL default '',
`diff1mod` float unsigned NOT NULL default '0',
`diff2name` varchar(50) NOT NULL default '',
`diff2mod` float unsigned NOT NULL default '0',
`diff3name` varchar(50) NOT NULL default '',
`diff3mod` float unsigned NOT NULL default '0',
`compression` tinyint(3) unsigned NOT NULL default '0',
`verifyemail` tinyint(3) unsigned NOT NULL default '0',
`shownews` tinyint(3) unsigned NOT NULL default '0',
`showbabble` tinyint(3) unsigned NOT NULL default '0',
`showonline` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
) TYPE=MyISAM;
END;
if (dobatch($query) == 1) { echo "Control table upgraded.<br />"; } else { echo "Error upgrading Control table."; }
unset($query);
$query = <<<END
INSERT INTO `$control` VALUES (1, 'Dragon Knight', 250, 0, '', '', 1, '', 'Mage', 'Warrior', 'Paladin', 'Easy', '1', 'Medium', '1.2', 'Hard', '1.5', 1, 1, 1, 1, 1);
END;
if (dobatch($query) == 1) { echo "Control table populated.<br />"; } else { echo "Error populating Control table."; }
unset($query);
$query = mysql_query("SELECT * FROM $users ORDER BY id") or die(mysql_error());
$errors = 0; $errorlist = "";
while ($row = mysql_fetch_array($query)) {
$id = $row["id"];
$oldspells = explode(",",$row["spells"]);
$newspells = "0,";
$oldtowns = explode(",",$row["towns"]);
$newtowns = "0,";
foreach($oldspells as $a => $b) {
if ($b == 1) { $newspells .= "$a,"; }
}
$newspells = rtrim($newspells,",");
foreach($oldtowns as $c => $d) {
if ($d == 1) { $newtowns .= "$c,"; }
}
$newtowns = rtrim($newtowns,",");
$update = mysql_query("UPDATE $users SET spells='$newspells',towns='$newtowns',verify='1' WHERE id='$id' LIMIT 1");
if ($update == false) { $errors++; $errorlist .= mysql_error() . "<br />"; } else { echo "User $id upgraded.<br />"; }
}
if ($errors != 0) {
echo "<br /><b><span style=\"color:red\">The following errors occurred while upgrading the users list:</span></b><br />$errorlist";
} else {
echo "<br /><b>The upgrade completed successfully. Please log in to the game and visit the control panel to update your main game settings.<br /><br />You should also delete this file from your Dragon Knight directory for security reasons.</b>";
}
} else {
echo "Click the button below to run the upgrade script.<br /><form action=\"upgrade_to_110.php\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Upgrade\" /></form>";
die();
}
?>

View File

@ -1,361 +0,0 @@
<?
include('config.php');
include('lib.php');
$link = opendb();
$prefix = $dbsettings["prefix"];
// Thanks to Predrag Supurovic from php.net for this function!
function dobatch ($p_query) {
$query_split = preg_split ("/[;]+/", $p_query);
foreach ($query_split as $command_line) {
$command_line = trim($command_line);
if ($command_line != '') {
$query_result = mysql_query($command_line);
if ($query_result == 0) {
break;
};
};
};
return $query_result;
}
if (isset($_POST["submit"])) {
$users = $prefix . "_users";
$levels = array(1=>"",2=>"",3=>"");
$levels["1"] = array(
1=>"0",
2=>"0,1",
3=>"0,1",
4=>"0,1,6",
5=>"0,1,6",
6=>"0,1,6",
7=>"0,1,6,11",
8=>"0,1,6,11",
9=>"0,1,6,11,2",
10=>"0,1,6,11,2",
11=>"0,1,6,11,2",
12=>"0,1,6,11,2,7",
13=>"0,1,6,11,2,7",
14=>"0,1,6,11,2,7,17",
15=>"0,1,6,11,2,7,17",
16=>"0,1,6,11,2,7,17",
17=>"0,1,6,11,2,7,17,12",
18=>"0,1,6,11,2,7,17,12",
19=>"0,1,6,11,2,7,17,12",
20=>"0,1,6,11,2,7,17,12",
21=>"0,1,6,11,2,7,17,12",
22=>"0,1,6,11,2,7,17,12",
23=>"0,1,6,11,2,7,17,12",
24=>"0,1,6,11,2,7,17,12",
25=>"0,1,6,11,2,7,17,12,3",
26=>"0,1,6,11,2,7,17,12,3",
27=>"0,1,6,11,2,7,17,12,3",
28=>"0,1,6,11,2,7,17,12,3",
29=>"0,1,6,11,2,7,17,12,3",
30=>"0,1,6,11,2,7,17,12,3",
31=>"0,1,6,11,2,7,17,12,3,8",
32=>"0,1,6,11,2,7,17,12,3,8",
33=>"0,1,6,11,2,7,17,12,3,8",
34=>"0,1,6,11,2,7,17,12,3,8",
35=>"0,1,6,11,2,7,17,12,3,8",
36=>"0,1,6,11,2,7,17,12,3,8,18",
37=>"0,1,6,11,2,7,17,12,3,8,18",
38=>"0,1,6,11,2,7,17,12,3,8,18",
39=>"0,1,6,11,2,7,17,12,3,8,18",
40=>"0,1,6,11,2,7,17,12,3,8,18,13",
41=>"0,1,6,11,2,7,17,12,3,8,18,13",
42=>"0,1,6,11,2,7,17,12,3,8,18,13",
43=>"0,1,6,11,2,7,17,12,3,8,18,13",
44=>"0,1,6,11,2,7,17,12,3,8,18,13",
45=>"0,1,6,11,2,7,17,12,3,8,18,13,4",
46=>"0,1,6,11,2,7,17,12,3,8,18,13,4",
47=>"0,1,6,11,2,7,17,12,3,8,18,13,4",
48=>"0,1,6,11,2,7,17,12,3,8,18,13,4",
49=>"0,1,6,11,2,7,17,12,3,8,18,13,4",
50=>"0,1,6,11,2,7,17,12,3,8,18,13,4",
51=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
52=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
53=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
54=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
55=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
56=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
57=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
58=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
59=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9",
60=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
61=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
62=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
63=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
64=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
65=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
66=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
67=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
68=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
69=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19",
70=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
71=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
72=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
73=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
74=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
75=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
76=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
77=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
78=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5",
79=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
80=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
81=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
82=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
83=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
84=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
85=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
86=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
87=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
88=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
89=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
90=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
91=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
92=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
93=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
94=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
95=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
96=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
97=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
98=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10",
99=>"0,1,6,11,2,7,17,12,3,8,18,13,4,9,19,5,10");
$levels["2"] = array(
1=>"0",
2=>"0,1",
3=>"0,1",
4=>"0,1",
5=>"0,1,6",
6=>"0,1,6",
7=>"0,1,6",
8=>"0,1,6,11",
9=>"0,1,6,11",
10=>"0,1,6,11",
11=>"0,1,6,11,2",
12=>"0,1,6,11,2",
13=>"0,1,6,11,2",
14=>"0,1,6,11,2,7",
15=>"0,1,6,11,2,7",
16=>"0,1,6,11,2,7",
17=>"0,1,6,11,2,7",
18=>"0,1,6,11,2,7,14",
19=>"0,1,6,11,2,7,14",
20=>"0,1,6,11,2,7,14",
21=>"0,1,6,11,2,7,14",
22=>"0,1,6,11,2,7,14,12",
23=>"0,1,6,11,2,7,14,12",
24=>"0,1,6,11,2,7,14,12",
25=>"0,1,6,11,2,7,14,12,17",
26=>"0,1,6,11,2,7,14,12,17",
27=>"0,1,6,11,2,7,14,12,17",
28=>"0,1,6,11,2,7,14,12,17",
29=>"0,1,6,11,2,7,14,12,17,3",
30=>"0,1,6,11,2,7,14,12,17,3",
31=>"0,1,6,11,2,7,14,12,17,3",
32=>"0,1,6,11,2,7,14,12,17,3",
33=>"0,1,6,11,2,7,14,12,17,3",
34=>"0,1,6,11,2,7,14,12,17,3,8",
35=>"0,1,6,11,2,7,14,12,17,3,8",
36=>"0,1,6,11,2,7,14,12,17,3,8",
37=>"0,1,6,11,2,7,14,12,17,3,8",
38=>"0,1,6,11,2,7,14,12,17,3,8,15",
39=>"0,1,6,11,2,7,14,12,17,3,8,15",
40=>"0,1,6,11,2,7,14,12,17,3,8,15",
41=>"0,1,6,11,2,7,14,12,17,3,8,15",
42=>"0,1,6,11,2,7,14,12,17,3,8,15",
43=>"0,1,6,11,2,7,14,12,17,3,8,15",
44=>"0,1,6,11,2,7,14,12,17,3,8,15",
45=>"0,1,6,11,2,7,14,12,17,3,8,15,18",
46=>"0,1,6,11,2,7,14,12,17,3,8,15,18",
47=>"0,1,6,11,2,7,14,12,17,3,8,15,18",
48=>"0,1,6,11,2,7,14,12,17,3,8,15,18",
49=>"0,1,6,11,2,7,14,12,17,3,8,15,18",
50=>"0,1,6,11,2,7,14,12,17,3,8,15,18",
51=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13",
52=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13",
53=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13",
54=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13",
55=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13",
56=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13",
57=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13",
58=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
59=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
60=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
61=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
62=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
63=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
64=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
65=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
66=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
67=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
68=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
69=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19",
70=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
71=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
72=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
73=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
74=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
75=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
76=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
77=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
78=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
79=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
80=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
81=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
82=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
83=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
84=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
85=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
86=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
87=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
88=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
89=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
90=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
91=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
92=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
93=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
94=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
95=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
96=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
97=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
98=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16",
99=>"0,1,6,11,2,7,14,12,17,3,8,15,18,13,19,16");
$levels["3"] = array(
1=>"0",
2=>"0,1",
3=>"0,1",
4=>"0,1",
5=>"0,1,6",
6=>"0,1,6",
7=>"0,1,6",
8=>"0,1,6,11",
9=>"0,1,6,11",
10=>"0,1,6,11",
11=>"0,1,6,11,2",
12=>"0,1,6,11,2",
13=>"0,1,6,11,2",
14=>"0,1,6,11,2,7",
15=>"0,1,6,11,2,7",
16=>"0,1,6,11,2,7",
17=>"0,1,6,11,2,7",
18=>"0,1,6,11,2,7,17",
19=>"0,1,6,11,2,7,17",
20=>"0,1,6,11,2,7,17",
21=>"0,1,6,11,2,7,17",
22=>"0,1,6,11,2,7,17,12",
23=>"0,1,6,11,2,7,17,12",
24=>"0,1,6,11,2,7,17,12",
25=>"0,1,6,11,2,7,17,12,14",
26=>"0,1,6,11,2,7,17,12,14",
27=>"0,1,6,11,2,7,17,12,14",
28=>"0,1,6,11,2,7,17,12,14",
29=>"0,1,6,11,2,7,17,12,14,3",
30=>"0,1,6,11,2,7,17,12,14,3",
31=>"0,1,6,11,2,7,17,12,14,3",
32=>"0,1,6,11,2,7,17,12,14,3",
33=>"0,1,6,11,2,7,17,12,14,3",
34=>"0,1,6,11,2,7,17,12,14,3,8",
35=>"0,1,6,11,2,7,17,12,14,3,8",
36=>"0,1,6,11,2,7,17,12,14,3,8",
37=>"0,1,6,11,2,7,17,12,14,3,8",
38=>"0,1,6,11,2,7,17,12,14,3,8,18",
39=>"0,1,6,11,2,7,17,12,14,3,8,18",
40=>"0,1,6,11,2,7,17,12,14,3,8,18",
41=>"0,1,6,11,2,7,17,12,14,3,8,18",
42=>"0,1,6,11,2,7,17,12,14,3,8,18",
43=>"0,1,6,11,2,7,17,12,14,3,8,18",
44=>"0,1,6,11,2,7,17,12,14,3,8,18",
45=>"0,1,6,11,2,7,17,12,14,3,8,18,4",
46=>"0,1,6,11,2,7,17,12,14,3,8,18,4",
47=>"0,1,6,11,2,7,17,12,14,3,8,18,4",
48=>"0,1,6,11,2,7,17,12,14,3,8,18,4",
49=>"0,1,6,11,2,7,17,12,14,3,8,18,4",
50=>"0,1,6,11,2,7,17,12,14,3,8,18,4",
51=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13",
52=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13",
53=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13",
54=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13",
55=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13",
56=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9",
57=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9",
58=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9",
59=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9",
60=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
61=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
62=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
63=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
64=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
65=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
66=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
67=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
68=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
69=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
70=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
71=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
72=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
73=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
74=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
75=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
76=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
77=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
78=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
79=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
80=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
81=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
82=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
83=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
84=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
85=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
86=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
87=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
88=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
89=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
90=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
91=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
92=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
93=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
94=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
95=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
96=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
97=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
98=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15",
99=>"0,1,6,11,2,7,17,12,14,3,8,18,4,13,9,15");
$errors = 0; $errorlist = "";
$mainquery = mysql_query("SELECT id,level,charclass,spells FROM $users ORDER BY id");
while ($mainrow = mysql_fetch_array($mainquery)) {
$level = $mainrow["level"];
$charclass = $mainrow["charclass"];
$newspell = $levels[$charclass][$level];
$newquery = mysql_query("UPDATE $users SET spells='$newspell' WHERE id='".$mainrow["id"]."' LIMIT 1");
if ($newquery != true) {
$errors++; $errorlist .= mysql_error() . "<br />";
}
}
$users = $prefix . "_users";
$query = <<<END
ALTER TABLE `$users` CHANGE `towns` `towns` VARCHAR( 50 ) DEFAULT '0' NOT NULL;
ALTER TABLE `$users` CHANGE `spells` `spells` VARCHAR( 50 ) DEFAULT '0' NOT NULL;
END;
if (dobatch($query) == 1) { echo "Users table upgraded.<br />"; } else { $errors++; $errorlist .= "Error upgrading Users table.<br />"; }
unset($query);
if ($errors == 0) { echo "<br />Upgrade finished."; } else { echo $errorlist; }
} else {
echo "Click the button below to run the upgrade script.<br /><form action=\"upgrade_to_112.php\" method=\"post\"><input type=\"submit\" name=\"submit\" value=\"Upgrade\" /></form>";
die();
}
?>