lots of db and css work, profiles

This commit is contained in:
Sky Johnson 2024-10-16 20:55:47 -07:00
parent a6e959b8ef
commit c9ff054426
25 changed files with 770 additions and 681 deletions

28
database/create/auth.sql Normal file
View File

@ -0,0 +1,28 @@
DROP TABLE IF EXISTS users;
CREATE TABLE users (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`username` TEXT NOT NULL UNIQUE,
`email` TEXT NOT NULL UNIQUE,
`password` TEXT NOT NULL,
`auth` INT NOT NULL DEFAULT 0,
`char_id` INTEGER NOT NULL DEFAULT 0,
`char_slots` INTEGER NOT NULL DEFAULT 2,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`last_login` DATETIME DEFAULT CURRENT_TIMESTAMP
);
DROP TABLE IF EXISTS sessions;
CREATE TABLE sessions (
`user_id` INTEGER NOT NULL,
`token` TEXT NOT NULL UNIQUE,
`expires` INTEGER NOT NULL
);
CREATE INDEX idx_sessions_user_id ON sessions (`user_id`);
DROP TABLE IF EXISTS tokens;
CREATE TABLE tokens (
`user_id` INTEGER NOT NULL,
`token` TEXT NOT NULL UNIQUE,
`created` INTEGER NOT NULL
);
CREATE INDEX idx_tokens_user_id ON tokens (`user_id`);

View File

@ -0,0 +1,56 @@
DROP TABLE IF EXISTS items;
CREATE TABLE items (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`type` INTEGER NOT NULL DEFAULT 0,
`subtype` INTEGER NOT NULL DEFAULT 0,
`slot` INTEGER NOT NULL DEFAULT 0,
`rarity` INTEGER NOT NULL DEFAULT 0,
`value` INTEGER NOT NULL DEFAULT 0,
`consumable` INTEGER NOT NULL DEFAULT 0,
`duration` INTEGER NOT NULL DEFAULT 0,
`durability` INTEGER NOT NULL DEFAULT 0,
`pow` INTEGER NOT NULL DEFAULT 0, -- Power
`acc` INTEGER NOT NULL DEFAULT 0, -- Accuracy
`pen` INTEGER NOT NULL DEFAULT 0, -- Penetration
`foc` INTEGER NOT NULL DEFAULT 0, -- Focus
`tou` INTEGER NOT NULL DEFAULT 0, -- Toughness
`arm` INTEGER NOT NULL DEFAULT 0, -- Armor
`res` INTEGER NOT NULL DEFAULT 0, -- Resist
`pre` INTEGER NOT NULL DEFAULT 0, -- Precision
`fer` INTEGER NOT NULL DEFAULT 0, -- Ferocity
`luck` INTEGER NOT NULL DEFAULT 0,
`reqs` TEXT NOT NULL DEFAULT "",
`traits` TEXT NOT NULL DEFAULT "",
`lore` TEXT NOT NULL DEFAULT "",
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
DROP TABLE IF EXISTS mobs;
CREATE TABLE mobs (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`type` INTEGER NOT NULL,
`rank` INTEGER NOT NULL,
`level` INTEGER NOT NULL,
`hp` INTEGER NOT NULL,
`m_hp` INTEGER NOT NULL,
`mp` INTEGER NOT NULL,
`m_mp` INTEGER NOT NULL,
`pow` INTEGER NOT NULL, -- Power
`acc` INTEGER NOT NULL, -- Accuracy
`pen` INTEGER NOT NULL, -- Penetration
`foc` INTEGER NOT NULL, -- Focus
`tou` INTEGER NOT NULL, -- Toughness
`arm` INTEGER NOT NULL, -- Armor
`res` INTEGER NOT NULL, -- Resist
`pre` INTEGER NOT NULL, -- Precision
`fer` INTEGER NOT NULL, -- Ferocity
`xp` INTEGER NOT NULL,
`silver` INTEGER NOT NULL,
`loot` TEXT NOT NULL,
`lore` TEXT NOT NULL,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);

103
database/create/fights.sql Normal file
View File

@ -0,0 +1,103 @@
/*
@PvE
*/
DROP TABLE IF EXISTS pve;
CREATE TABLE pve (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`char_id` INTEGER NOT NULL,
`char_hp` INTEGER NOT NULL,
`char_m_hp` INTEGER NOT NULL,
`char_mp` INTEGER NOT NULL,
`char_m_mp` INTEGER NOT NULL,
`char_pow` INTEGER NOT NULL, -- Power
`char_acc` INTEGER NOT NULL, -- Accuracy
`char_pen` INTEGER NOT NULL, -- Penetration
`char_foc` INTEGER NOT NULL, -- Focus
`char_tou` INTEGER NOT NULL, -- Toughness
`char_arm` INTEGER NOT NULL, -- Armor
`char_res` INTEGER NOT NULL, -- Resist
`char_pre` INTEGER NOT NULL, -- Precision
`char_fer` INTEGER NOT NULL, -- Ferocity
`mob_id` INTEGER NOT NULL,
`mob_level` INTEGER NOT NULL,
`mob_rank` INTEGER NOT NULL,
`mob_hp` INTEGER NOT NULL,
`mob_m_hp` INTEGER NOT NULL,
`mob_mp` INTEGER NOT NULL,
`mob_m_mp` INTEGER NOT NULL,
`mob_pow` INTEGER NOT NULL, -- Power
`mob_acc` INTEGER NOT NULL, -- Accuracy
`mob_pen` INTEGER NOT NULL, -- Penetration
`mob_foc` INTEGER NOT NULL, -- Focus
`mob_tou` INTEGER NOT NULL, -- Toughness
`mob_arm` INTEGER NOT NULL, -- Armor
`mob_res` INTEGER NOT NULL, -- Resist
`mob_pre` INTEGER NOT NULL, -- Precision
`mob_fer` INTEGER NOT NULL, -- Ferocity
`first_turn` INTEGER NOT NULL,
`turn` INTEGER NOT NULL default 1,
`winner` INTEGER NOT NULL default 0,
`can_flee` INTEGER NOT NULL default 1,
`escaped` INTEGER NOT NULL default 0,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_pve_char_id ON pve (`char_id`);
DROP TABLE IF EXISTS pve_logs;
CREATE TABLE pve_logs (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`fight_id` INTEGER NOT NULL,
`info` TEXT NOT NULL
);
CREATE INDEX idx_pve_logs_fight_id ON pve_logs (`fight_id`);
/*
@PvP
*/
DROP TABLE IF EXISTS pvp;
CREATE TABLE pvp (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`char1_id` INTEGER NOT NULL,
`char1_hp` INTEGER NOT NULL,
`char1_max_hp` INTEGER NOT NULL,
`char1_mp` INTEGER NOT NULL,
`char1_max_mp` INTEGER NOT NULL,
`char1_pow` INTEGER NOT NULL, -- Power
`char1_acc` INTEGER NOT NULL, -- Accuracy
`char1_pen` INTEGER NOT NULL, -- Penetration
`char1_foc` INTEGER NOT NULL, -- Focus
`char1_tou` INTEGER NOT NULL, -- Toughness
`char1_arm` INTEGER NOT NULL, -- Armor
`char1_res` INTEGER NOT NULL, -- Resist
`char1_pre` INTEGER NOT NULL, -- Precision
`char1_fer` INTEGER NOT NULL, -- Ferocity
`char2_id` INTEGER NOT NULL,
`char2_hp` INTEGER NOT NULL,
`char2_m_hp` INTEGER NOT NULL,
`char2_mp` INTEGER NOT NULL,
`char2_m_mp` INTEGER NOT NULL,
`char2_pow` INTEGER NOT NULL, -- Power
`char2_acc` INTEGER NOT NULL, -- Accuracy
`char2_pen` INTEGER NOT NULL, -- Penetration
`char2_foc` INTEGER NOT NULL, -- Focus
`char2_tou` INTEGER NOT NULL, -- Toughness
`char2_arm` INTEGER NOT NULL, -- Armor
`char2_res` INTEGER NOT NULL, -- Resist
`char2_pre` INTEGER NOT NULL, -- Precision
`char2_fer` INTEGER NOT NULL, -- Ferocity
`first_turn` INTEGER NOT NULL,
`turn` INTEGER NOT NULL default 1,
`winner` INTEGER NOT NULL default 0,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_pvp_char1_id ON pvp (`char1_id`);
CREATE INDEX idx_pvp_char2_id ON pvp (`char2_id`);
CREATE TABLE pvp_logs (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`fight_id` INTEGER NOT NULL,
`info` TEXT NOT NULL
);
CREATE INDEX idx_pvp_logs_fight_id ON pvp_logs (`fight_id`);

329
database/create/live.sql Normal file
View File

@ -0,0 +1,329 @@
/*
@BLOG
*/
DROP TABLE IF EXISTS blog;
CREATE TABLE blog (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`author_id` INTEGER NOT NULL,
`title` TEXT NOT NULL,
`slug` TEXT NOT NULL UNIQUE,
`content` TEXT NOT NULL,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_blog_author_id ON blog (`author_id`);
CREATE INDEX idx_blog_slug ON blog (`slug`);
/*
@CHARS
*/
DROP TABLE IF EXISTS characters;
CREATE TABLE characters (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`user_id` INTEGER NOT NULL,
`name` TEXT NOT NULL UNIQUE,
`title_id` INTEGER NOT NULL DEFAULT 1,
`level` INTEGER NOT NULL DEFAULT 1,
`xp` INTEGER NOT NULL DEFAULT 0,
`xp_to_level` INTEGER NOT NULL DEFAULT 100,
`hp` INTEGER NOT NULL DEFAULT 20,
`m_hp` INTEGER NOT NULL DEFAULT 20,
`mp` INTEGER NOT NULL DEFAULT 10,
`m_mp` INTEGER NOT NULL DEFAULT 10,
`tp` INTEGER NOT NULL DEFAULT 1,
`m_tp` INTEGER NOT NULL DEFAULT 1,
`pow` INTEGER NOT NULL DEFAULT 0, -- Power
`acc` INTEGER NOT NULL DEFAULT 0, -- Accuracy
`pen` INTEGER NOT NULL DEFAULT 0, -- Penetration
`foc` INTEGER NOT NULL DEFAULT 0, -- Focus
`tou` INTEGER NOT NULL DEFAULT 0, -- Toughness
`arm` INTEGER NOT NULL DEFAULT 0, -- Armor
`res` INTEGER NOT NULL DEFAULT 0, -- Resist
`pre` INTEGER NOT NULL DEFAULT 0, -- Precision
`fer` INTEGER NOT NULL DEFAULT 0, -- Ferocity
`luck` INTEGER NOT NULL DEFAULT 0, -- Luck
`inv_slots` INTEGER NOT NULL DEFAULT 10,
`att_points` INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_characters_user_id ON characters (`user_id`);
/*
@CHARGEAR
*/
DROP TABLE IF EXISTS char_gear;
CREATE TABLE char_gear (
`char_id` INTEGER NOT NULL,
`head` INTEGER NOT NULL DEFAULT 0,
`chest` INTEGER NOT NULL DEFAULT 0,
`boots` INTEGER NOT NULL DEFAULT 0,
`hands` INTEGER NOT NULL DEFAULT 0,
`m_hand` INTEGER NOT NULL DEFAULT 0,
`o_hand` INTEGER NOT NULL DEFAULT 0,
`rune` INTEGER NOT NULL DEFAULT 0,
`ring` INTEGER NOT NULL DEFAULT 0,
`amulet` INTEGER NOT NULL DEFAULT 0,
`pow` INTEGER NOT NULL DEFAULT 0, -- Power
`acc` INTEGER NOT NULL DEFAULT 0, -- Accuracy
`pen` INTEGER NOT NULL DEFAULT 0, -- Penetration
`foc` INTEGER NOT NULL DEFAULT 0, -- Focus
`tou` INTEGER NOT NULL DEFAULT 0, -- Toughness
`arm` INTEGER NOT NULL DEFAULT 0, -- Armor
`res` INTEGER NOT NULL DEFAULT 0, -- Resist
`pre` INTEGER NOT NULL DEFAULT 0, -- Precision
`fer` INTEGER NOT NULL DEFAULT 0, -- Ferocity
`luck` INTEGER NOT NULL DEFAULT 0, -- Luck
`max_hp` INTEGER NOT NULL DEFAULT 0,
`max_mp` INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_char_gear_char_id ON char_gear (`char_id`);
/*
@CHARINV
*/
DROP TABLE IF EXISTS char_inventory;
CREATE TABLE char_inventory (
`char_id` INTEGER NOT NULL,
`item_id` INTEGER NOT NULL
);
CREATE INDEX idx_inventory_char_id ON char_inventory (`char_id`);
/*
@WALLETS
*/
DROP TABLE IF EXISTS wallets;
CREATE TABLE wallets (
`user_id` INTEGER NOT NULL,
`silver` INTEGER NOT NULL DEFAULT 10,
`stargem` INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_wallets_user_id ON wallets (`user_id`);
/*
@CHARBANK
*/
DROP TABLE IF EXISTS char_bank;
CREATE TABLE char_bank (
`char_id` INTEGER NOT NULL,
`slots` INTEGER NOT NULL DEFAULT 5,
`silver` INTEGER NOT NULL DEFAULT 0,
`tier` INTEGER NOT NULL DEFAULT 0,
`can_collect` INTEGER NOT NULL DEFAULT 1,
`last_collect` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_bank_char_id ON char_bank (`char_id`);
/*
@CHARBANKITEMS
*/
DROP TABLE IF EXISTS char_banked_items;
CREATE TABLE char_banked_items (
`char_id` INTEGER NOT NULL,
`item_id` INTEGER NOT NULL
);
CREATE INDEX idx_banked_items_char_id ON char_banked_items (`char_id`);
CREATE INDEX idx_banked_items_item_id ON char_banked_items (`item_id`);
/*
@TOWNS
*/
DROP TABLE IF EXISTS towns;
CREATE TABLE towns (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`x` INTEGER NOT NULL,
`y` INTEGER NOT NULL,
`type` INTEGER NOT NULL,
`lore` TEXT NOT NULL,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_towns_location ON towns (`x`, `y`);
/*
@SHOPS
*/
DROP TABLE IF EXISTS shops;
CREATE TABLE shops (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`type` INTEGER NOT NULL,
`lore` TEXT NOT NULL,
`x` INTEGER NOT NULL,
`y` INTEGER NOT NULL,
`items` TEXT NOT NULL,
`gear` TEXT NOT NULL,
`materials` TEXT NOT NULL,
`b_mod` INTEGER NOT NULL DEFAULT 100,
`s_mod` INTEGER NOT NULL DEFAULT 100,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_shops_location ON shops (`x`, `y`);
/*
@INNS
*/
DROP TABLE IF EXISTS inns;
CREATE TABLE inns (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`type` INTEGER NOT NULL,
`lore` TEXT NOT NULL,
`x` INTEGER NOT NULL,
`y` INTEGER NOT NULL,
`cost` INTEGER NOT NULL,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_inns_location ON inns (`x`, `y`);
/*
@GUILDS
*/
DROP TABLE IF EXISTS guilds;
CREATE TABLE guilds (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`lore` TEXT NOT NULL DEFAULT "",
`leader_id` INTEGER NOT NULL,
`silver` INTEGER NOT NULL DEFAULT 0,
`rep` INTEGER NOT NULL DEFAULT 0,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_guilds_leader_id ON guilds (`leader_id`);
/*
@GUILDRANKS
*/
DROP TABLE IF EXISTS guild_ranks;
CREATE TABLE guild_ranks (
`guild_id` INTEGER NOT NULL,
`order` INTEGER NOT NULL,
`name` TEXT NOT NULL,
`permissions` TEXT NOT NULL,
`leader` INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_guild_ranks_guild_id ON guild_ranks (`guild_id`);
/*
@GUILDMEMBERS
*/
DROP TABLE IF EXISTS guild_members;
CREATE TABLE guild_members (
`guild_id` INTEGER NOT NULL,
`char_id` INTEGER NOT NULL,
`rank` INTEGER NOT NULL,
`rep` INTEGER NOT NULL DEFAULT 0,
`donated` INTEGER NOT NULL DEFAULT 0,
`joined` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_guild_members_guild_id ON guild_members (`guild_id`);
CREATE INDEX idx_guild_members_char_id ON guild_members (`char_id`);
/*
@NPCS
*/
DROP TABLE IF EXISTS npcs;
CREATE TABLE npcs (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`type` INTEGER NOT NULL,
`lore` TEXT NOT NULL,
`conversation` TEXT NOT NULL,
`x` INTEGER NOT NULL,
`y` INTEGER NOT NULL,
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_npcs_location ON npcs (`x`, `y`);
/*
@TOWNREP
*/
DROP TABLE IF EXISTS char_town_rep;
CREATE TABLE char_town_rep (
`char_id` INTEGER NOT NULL,
`town_id` INTEGER NOT NULL,
`rep` INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_char_town_rep_char_id ON char_town_rep (`char_id`);
/*
@ITEMS
*/
DROP TABLE IF EXISTS items;
CREATE TABLE items (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`type` TEXT NOT NULL DEFAULT 0,
`rarity` INTEGER NOT NULL DEFAULT 0,
`forged` INTEGER NOT NULL DEFAULT 0,
`quality` INTEGER NOT NULL DEFAULT 0,
`value` INTEGER NOT NULL DEFAULT 0,
`consumable` INTEGER NOT NULL DEFAULT 0,
`duration` INTEGER NOT NULL DEFAULT 0,
`durability` INTEGER NOT NULL DEFAULT 0,
`m_durability` INTEGER NOT NULL DEFAULT 0,
`pow` INTEGER NOT NULL DEFAULT 0, -- Power
`acc` INTEGER NOT NULL DEFAULT 0, -- Accuracy
`pen` INTEGER NOT NULL DEFAULT 0, -- Penetration
`foc` INTEGER NOT NULL DEFAULT 0, -- Focus
`tou` INTEGER NOT NULL DEFAULT 0, -- Toughness
`arm` INTEGER NOT NULL DEFAULT 0, -- Armor
`res` INTEGER NOT NULL DEFAULT 0, -- Resist
`pre` INTEGER NOT NULL DEFAULT 0, -- Precision
`fer` INTEGER NOT NULL DEFAULT 0, -- Ferocity
`luck` INTEGER NOT NULL DEFAULT 0, -- Luck
`reqs` TEXT NOT NULL DEFAULT "",
`traits` TEXT NOT NULL DEFAULT "",
`lore` TEXT NOT NULL DEFAULT "",
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated` DATETIME DEFAULT CURRENT_TIMESTAMP
);
/*
@CHARTRAITS
*/
DROP TABLE IF EXISTS char_traits;
CREATE TABLE char_traits (
`char_id` INTEGER NOT NULL,
`trait_id` INTEGER NOT NULL,
`value` INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_char_traits_char_id ON char_traits (`char_id`);
/*
@CHARLOCATIONS
*/
DROP TABLE IF EXISTS char_locations;
CREATE TABLE char_locations (
`char_id` INTEGER NOT NULL,
`x` INTEGER NOT NULL,
`y` INTEGER NOT NULL,
`currently` INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_char_locations_char_id ON char_locations (`char_id`);
CREATE INDEX idx_char_locations_location ON char_locations (`x`, `y`);
/*
@TITLES
*/
DROP TABLE IF EXISTS titles;
CREATE TABLE titles (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL DEFAULT 'Title',
`lore` TEXT
);
/*
@OWNEDTITLES
*/
DROP TABLE IF EXISTS owned_titles;
CREATE TABLE owned_titles (
`title_id` INTEGER NOT NULL,
`char_id` INTEGER NOT NULL,
`awarded` DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_owned_titles_char_id ON owned_titles (`char_id`);
CREATE INDEX idx_owned_titles_owned ON owned_titles (`char_id`, `title_id`);

BIN
database/live.db-shm Normal file

Binary file not shown.

BIN
database/live.db-wal Normal file

Binary file not shown.

77
database/manage.sh Executable file
View File

@ -0,0 +1,77 @@
#!/bin/bash
# Directories for schema and population scripts
CREATE_DIR="create"
POPULATE_DIR="populate"
# List of databases
DATABASES=("auth" "blueprints" "fights" "live")
# Function to create a database and apply the schema
create_db() {
for db in "${DATABASES[@]}"; do
db_file="${db}.db"
schema_file="${CREATE_DIR}/${db}.sql"
if [[ -f "$schema_file" ]]; then
echo "Creating $db_file and applying schema from $schema_file..."
sqlite3 "$db_file" < "$schema_file"
else
echo "Schema file for $db not found. Skipping."
fi
done
}
# Function to populate the database with data
populate_db() {
for db in "${DATABASES[@]}"; do
db_file="${db}.db"
populate_file="${POPULATE_DIR}/${db}.sql"
if [[ -f "$populate_file" ]]; then
echo "Populating $db_file using data from $populate_file..."
sqlite3 "$db_file" < "$populate_file"
else
echo "Population file for $db not found. Skipping."
fi
done
}
# Function to drop (delete) the databases
drop_db() {
for db in "${DATABASES[@]}"; do
db_file="${db}.db"
if [[ -f "$db_file" ]]; then
echo "Dropping $db_file..."
rm "$db_file"
else
echo "$db_file does not exist. Skipping."
fi
done
}
# Function for a full reset (create and populate)
full_reset() {
create_db
populate_db
}
# Main script
case $1 in
create)
create_db
;;
populate)
populate_db
;;
reset)
full_reset
;;
drop)
drop_db
;;
*)
echo "Usage: $0 {create|populate|reset}"
;;
esac

View File

@ -0,0 +1 @@
INSERT INTO titles (`name`, `lore`) VALUES ('Adventurer', 'A risk-taker hunting for glory and loot!');

View File

@ -1,666 +0,0 @@
<?php
/*
This script is used to create the database and the tables for said database.
php create.php <database>
*/
require_once __DIR__ . '/../../color.php';
const AUTH = 'auth.db';
const LIVE = 'live.db';
const FIGHTS = 'fights.db';
const BPS = 'blueprints.db';
/**
* Echo a string with a newline.
*/
function eln($string)
{
echo $string . PHP_EOL;
}
// pick the database to create
if (!isset($argv[1])) {
eln(red('Missing database name.'));
eln(blue('Usage: ') . 'php create.php auth.db|live.db|fight.db|blueprints.db [-d]');
exit(1);
}
// make sure it's a valid database
if (!in_array($argv[1], [AUTH, LIVE, FIGHTS, BPS, 'reset'])) {
eln(red('Invalid database: ') . $argv[1]);
exit(1);
}
$database = $argv[1];
// whether the -d flag is set
$drop = isset($argv[2]) && $argv[2] === '-d';
/*
================================================================================
Databases
================================================================================
*/
/*
The Auth database is used to store user information - not player info, but user info.
Usernames, passwords, email, session tokens, etc.
*/
if ($database === AUTH || $database === 'reset') {
if ($drop || $database === 'reset') {
unlink(__DIR__ . '/../' . AUTH);
eln(red('Dropped database: ') . 'auth.db');
}
$db = new SQLite3(__DIR__ . '/../' . AUTH);
// Users table
$db->exec('DROP TABLE IF EXISTS users');
$r = $db->exec('CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
email TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
auth INT NOT NULL DEFAULT 0,
char_id INTEGER NOT NULL DEFAULT 0,
char_slots INTEGER NOT NULL DEFAULT 300,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
last_login DATETIME DEFAULT CURRENT_TIMESTAMP
)');
created_or_error($r, 'users');
// Sessions table
$db->exec('DROP TABLE IF EXISTS sessions');
$r = $db->exec('CREATE TABLE sessions (
user_id INTEGER NOT NULL,
token TEXT NOT NULL UNIQUE,
expires INTEGER NOT NULL
)');
$db->exec('CREATE INDEX idx_sessions_user_id ON sessions (user_id)');
created_or_error($r, 'sessions');
// Verification tokens
$db->exec('DROP TABLE IF EXISTS tokens');
$r = $db->exec('CREATE TABLE tokens (
user_id INTEGER NOT NULL,
token TEXT NOT NULL UNIQUE,
created INTEGER NOT NULL
)');
$db->exec('CREATE INDEX idx_tokens_user_id ON tokens (user_id)');
created_or_error($r, 'tokens');
eln(green('Created database: ') . 'auth.db');
if ($database !== 'reset') exit(0);
}
/*
The Fights database is used to store information about fights.
A fight is a battle between two characters; players or NPCs.
*/
if ($database === FIGHTS || $database === 'reset') {
if ($drop || $database === 'reset') {
unlink(__DIR__ . '/../' . FIGHTS);
eln(red('Dropped database: ') . 'fights.db');
}
$db = new SQLite3(__DIR__ . '/../' . FIGHTS);
// PvE fights
$db->exec('DROP TABLE IF EXISTS pve');
$r = $db->exec('CREATE TABLE pve (
id INTEGER PRIMARY KEY AUTOINCREMENT,
char_id INTEGER NOT NULL,
char_hp INTEGER NOT NULL,
char_max_hp INTEGER NOT NULL,
char_mp INTEGER NOT NULL,
char_max_mp INTEGER NOT NULL,
char_power INTEGER NOT NULL,
char_accuracy INTEGER NOT NULL,
char_penetration INTEGER NOT NULL DEFAULT 0,
char_focus INTEGER NOT NULL DEFAULT 0,
char_toughness INTEGER NOT NULL,
char_armor INTEGER NOT NULL,
char_resist INTEGER NOT NULL,
char_crit INTEGER NOT NULL,
char_precision INTEGER NOT NULL,
char_ferocity INTEGER NOT NULL,
mob_id INTEGER NOT NULL,
mob_level INTEGER NOT NULL,
mob_rank INTEGER NOT NULL,
mob_hp INTEGER NOT NULL,
mob_max_hp INTEGER NOT NULL,
mob_mp INTEGER NOT NULL,
mob_max_mp INTEGER NOT NULL,
mob_power INTEGER NOT NULL,
mob_toughness INTEGER NOT NULL,
mob_armor INTEGER NOT NULL,
mob_precision INTEGER NOT NULL,
mob_penetration INTEGER NOT NULL DEFAULT 0,
mob_focus INTEGER NOT NULL DEFAULT 0,
mob_crit INTEGER NOT NULL,
mob_ferocity INTEGER NOT NULL,
mob_vitality INTEGER NOT NULL,
first_turn INTEGER NOT NULL,
turn INTEGER NOT NULL default 1,
winner INTEGER NOT NULL default 0,
flee INTEGER NOT NULL default 1,
escaped INTEGER NOT NULL default 0,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// create an index for char_id
$db->exec('CREATE INDEX idx_pve_char_id ON pve (char_id)');
created_or_error($r, 'pve');
// PvP fights
$db->exec('DROP TABLE IF EXISTS pvp');
$r = $db->exec('CREATE TABLE pvp (
id INTEGER PRIMARY KEY AUTOINCREMENT,
char1_id INTEGER NOT NULL,
char1_hp INTEGER NOT NULL,
char1_max_hp INTEGER NOT NULL,
char1_mp INTEGER NOT NULL,
char1_max_mp INTEGER NOT NULL,
char1_power INTEGER NOT NULL,
char1_accuracy INTEGER NOT NULL,
char1_penetration INTEGER NOT NULL DEFAULT 0,
char1_focus INTEGER NOT NULL DEFAULT 0,
char1_toughness INTEGER NOT NULL,
char1_armor INTEGER NOT NULL,
char1_resist INTEGER NOT NULL,
char1_crit INTEGER NOT NULL,
char1_precision INTEGER NOT NULL,
char1_ferocity INTEGER NOT NULL,
char2_id INTEGER NOT NULL,
char2_hp INTEGER NOT NULL,
char2_max_hp INTEGER NOT NULL,
char2_mp INTEGER NOT NULL,
char2_max_mp INTEGER NOT NULL,
char2_power INTEGER NOT NULL,
char2_accuracy INTEGER NOT NULL,
char2_penetration INTEGER NOT NULL DEFAULT 0,
char2_focus INTEGER NOT NULL DEFAULT 0,
char2_toughness INTEGER NOT NULL,
char2_armor INTEGER NOT NULL,
char2_resist INTEGER NOT NULL,
char2_crit INTEGER NOT NULL,
char2_precision INTEGER NOT NULL,
char2_ferocity INTEGER NOT NULL,
first_turn INTEGER NOT NULL,
turn INTEGER NOT NULL default 1,
winner INTEGER NOT NULL default 0,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for char1_id
$db->exec('CREATE INDEX idx_pvp_char1_id ON pvp (char1_id)');
// Create an index for char2_id
$db->exec('CREATE INDEX idx_pvp_char2_id ON pvp (char2_id)');
created_or_error($r, 'pvp');
// PvE fight logs
$db->exec('DROP TABLE IF EXISTS pve_logs');
$r = $db->exec('CREATE TABLE pve_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
fight_id INTEGER NOT NULL,
info TEXT NOT NULL
)');
// Create an index for fight_id
$db->exec('CREATE INDEX idx_pve_logs_fight_id ON pve_logs (fight_id)');
created_or_error($r, 'pve_logs');
// PvP fight logs
$db->exec('DROP TABLE IF EXISTS pvp_logs');
$r = $db->exec('CREATE TABLE pvp_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
fight_id INTEGER NOT NULL,
info TEXT NOT NULL
)');
// Create an index for fight_id
$db->exec('CREATE INDEX idx_pvp_logs_fight_id ON pvp_logs (fight_id)');
created_or_error($r, 'pvp_logs');
eln(green('Created database: ') . 'fights.db');
if ($database !== 'reset') exit(0);
}
/*
The Blueprints database is used to store information about items, weapons, armor, etc.
*/
if ($database === BPS || $database === 'reset') {
if ($drop || $database === 'reset') {
unlink(__DIR__ . '/../' . BPS);
eln(red('Dropped database: ') . 'blueprints.db');
}
$db = new SQLite3(__DIR__ . '/../' . BPS);
// Items
$db->exec('DROP TABLE IF EXISTS items');
$r = $db->exec('CREATE TABLE items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type INTEGER NOT NULL DEFAULT 0,
subtype INTEGER NOT NULL DEFAULT 0,
slot INTEGER NOT NULL DEFAULT 0,
rarity INTEGER NOT NULL DEFAULT 0,
value INTEGER NOT NULL DEFAULT 0,
consumable INTEGER NOT NULL DEFAULT 0,
duration INTEGER NOT NULL DEFAULT 0,
durability INTEGER NOT NULL DEFAULT 0,
power INTEGER NOT NULL DEFAULT 0,
accuracy INTEGER NOT NULL DEFAULT 0,
penetration INTEGER NOT NULL DEFAULT 0,
focus INTEGER NOT NULL DEFAULT 0,
toughness INTEGER NOT NULL DEFAULT 0,
armor INTEGER NOT NULL DEFAULT 0,
resist INTEGER NOT NULL DEFAULT 0,
crit INTEGER NOT NULL DEFAULT 0,
precision INTEGER NOT NULL DEFAULT 0,
ferocity INTEGER NOT NULL DEFAULT 0,
luck INTEGER NOT NULL DEFAULT 0,
reqs TEXT NOT NULL DEFAULT "",
traits TEXT NOT NULL DEFAULT "",
lore TEXT NOT NULL DEFAULT "",
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
created_or_error($r, 'items');
// Mobs
$db->exec('DROP TABLE IF EXISTS mobs');
$r = $db->exec('CREATE TABLE mobs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type INTEGER NOT NULL,
rank INTEGER NOT NULL,
level INTEGER NOT NULL,
hp INTEGER NOT NULL,
max_hp INTEGER NOT NULL,
mp INTEGER NOT NULL,
max_mp INTEGER NOT NULL,
power INTEGER NOT NULL,
toughness INTEGER NOT NULL,
armor INTEGER NOT NULL,
precision INTEGER NOT NULL,
crit INTEGER NOT NULL,
ferocity INTEGER NOT NULL,
vitality INTEGER NOT NULL,
xp INTEGER NOT NULL,
silver INTEGER NOT NULL,
loot TEXT NOT NULL,
lore TEXT NOT NULL,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
created_or_error($r, 'mobs');
eln(green('Created database: ') . 'blueprints.db');
if ($database !== 'reset') exit(0);
}
/*
The Live database is used to store information about players, NPCs, guilds, etc.
*/
if ($database === LIVE || $database === 'reset') {
if ($drop || $database === 'reset') {
unlink(__DIR__ . '/../' . LIVE);
eln(red('Dropped database: ') . 'live.db');
}
$db = new SQLite3(__DIR__ . '/../' . LIVE);
// Blog posts
$db->exec('DROP TABLE IF EXISTS blog');
$r = $db->exec('CREATE TABLE blog (
id INTEGER PRIMARY KEY AUTOINCREMENT,
author_id INTEGER NOT NULL,
title TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
content TEXT NOT NULL,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for author_id
$db->exec('CREATE INDEX idx_blog_author_id ON blog (author_id)');
// Create an index for the slug
$db->exec('CREATE INDEX idx_blog_slug ON blog (slug)');
created_or_error($r, 'blog');
// Characters
$db->exec('DROP TABLE IF EXISTS characters');
$r = $db->exec('CREATE TABLE characters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
name TEXT NOT NULL UNIQUE,
title_id INTEGER NOT NULL DEFAULT 0,
level INTEGER NOT NULL DEFAULT 1,
xp INTEGER NOT NULL DEFAULT 0,
xp_to_level INTEGER NOT NULL DEFAULT 100,
current_hp INTEGER NOT NULL DEFAULT 20,
max_hp INTEGER NOT NULL DEFAULT 20,
current_mp INTEGER NOT NULL DEFAULT 10,
max_mp INTEGER NOT NULL DEFAULT 10,
current_tp INTEGER NOT NULL DEFAULT 1,
max_tp INTEGER NOT NULL DEFAULT 1,
power INTEGER NOT NULL DEFAULT 0,
accuracy INTEGER NOT NULL DEFAULT 0,
penetration INTEGER NOT NULL DEFAULT 0,
focus INTEGER NOT NULL DEFAULT 0,
toughness INTEGER NOT NULL DEFAULT 0,
armor INTEGER NOT NULL DEFAULT 0,
resist INTEGER NOT NULL DEFAULT 0,
precision INTEGER NOT NULL DEFAULT 0,
ferocity INTEGER NOT NULL DEFAULT 0,
luck INTEGER NOT NULL DEFAULT 0,
inv_slots INTEGER NOT NULL DEFAULT 10,
attrib_points INTEGER NOT NULL DEFAULT 0
)');
// Create an index for user_id
$db->exec('CREATE INDEX idx_characters_user_id ON characters (user_id)');
created_or_error($r, 'characters');
// Player gear
$db->exec('DROP TABLE IF EXISTS char_gear');
$r = $db->exec('CREATE TABLE char_gear (
char_id INTEGER NOT NULL,
head INTEGER NOT NULL DEFAULT 0,
chest INTEGER NOT NULL DEFAULT 0,
boots INTEGER NOT NULL DEFAULT 0,
hands INTEGER NOT NULL DEFAULT 0,
main_hand INTEGER NOT NULL DEFAULT 0,
off_hand INTEGER NOT NULL DEFAULT 0,
rune INTEGER NOT NULL DEFAULT 0,
ring INTEGER NOT NULL DEFAULT 0,
amulet INTEGER NOT NULL DEFAULT 0,
power INTEGER NOT NULL DEFAULT 0,
accuracy INTEGER NOT NULL DEFAULT 0,
penetration INTEGER NOT NULL DEFAULT 0,
focus INTEGER NOT NULL DEFAULT 0,
toughness INTEGER NOT NULL DEFAULT 0,
armor INTEGER NOT NULL DEFAULT 0,
resist INTEGER NOT NULL DEFAULT 0,
crit INTEGER NOT NULL DEFAULT 0,
precision INTEGER NOT NULL DEFAULT 0,
ferocity INTEGER NOT NULL DEFAULT 0,
luck INTEGER NOT NULL DEFAULT 0,
max_hp INTEGER NOT NULL DEFAULT 0,
max_mp INTEGER NOT NULL DEFAULT 0
)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_char_gear_char_id ON char_gear (char_id)');
created_or_error($r, 'char_gear');
// Player inventory
$db->exec('DROP TABLE IF EXISTS char_inventory');
$r = $db->exec('CREATE TABLE char_inventory (
char_id INTEGER NOT NULL,
item_id INTEGER NOT NULL
)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_inventory_char_id ON char_inventory (char_id)');
created_or_error($r, 'char_inventory');
// Player wallet
$db->exec('DROP TABLE IF EXISTS wallets');
$r = $db->exec('CREATE TABLE wallets (
user_id INTEGER NOT NULL,
silver INTEGER NOT NULL DEFAULT 10,
stargem INTEGER NOT NULL DEFAULT 0
)');
// Create an index for user_id
$db->exec('CREATE INDEX idx_wallets_user_id ON wallets (user_id)');
created_or_error($r, 'wallets');
// Player bank
$db->exec('DROP TABLE IF EXISTS char_bank');
$r = $db->exec('CREATE TABLE char_bank (
char_id INTEGER NOT NULL,
slots INTEGER NOT NULL DEFAULT 5,
silver INTEGER NOT NULL DEFAULT 0,
tier INTEGER NOT NULL DEFAULT 0,
can_collect INTEGER NOT NULL DEFAULT 1,
last_collected DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_bank_char_id ON char_bank (char_id)');
created_or_error($r, 'char_bank');
// Banked items
$db->exec('DROP TABLE IF EXISTS char_banked_items');
$r = $db->exec('CREATE TABLE char_banked_items (
char_id INTEGER NOT NULL,
item_id INTEGER NOT NULL
)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_banked_items_char_id ON char_banked_items (char_id)');
// Create an index for item_id
$db->exec('CREATE INDEX idx_banked_items_item_id ON char_banked_items (item_id)');
created_or_error($r, 'char_banked_items');
// Towns
$db->exec('DROP TABLE IF EXISTS towns');
$r = $db->exec('CREATE TABLE towns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
type INTEGER NOT NULL,
lore TEXT NOT NULL,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for the x, y location
$db->exec('CREATE INDEX idx_towns_location ON towns (x, y)');
created_or_error($r, 'towns');
// Shops
$db->exec('DROP TABLE IF EXISTS shops');
$r = $db->exec('CREATE TABLE shops (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type INTEGER NOT NULL,
lore TEXT NOT NULL,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
items TEXT NOT NULL,
gear TEXT NOT NULL,
materials TEXT NOT NULL,
buy_modifier INTEGER NOT NULL DEFAULT 100,
sell_modifier INTEGER NOT NULL DEFAULT 100,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for the x, y location
$db->exec('CREATE INDEX idx_shops_location ON shops (x, y)');
created_or_error($r, 'shops');
// Inns
$db->exec('DROP TABLE IF EXISTS inns');
$r = $db->exec('CREATE TABLE inns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type INTEGER NOT NULL,
lore TEXT NOT NULL,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
cost INTEGER NOT NULL,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for the x, y location
$db->exec('CREATE INDEX idx_inns_location ON inns (x, y)');
created_or_error($r, 'inns');
// Guilds
$db->exec('DROP TABLE IF EXISTS guilds');
$r = $db->exec('CREATE TABLE guilds (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
lore TEXT NOT NULL DEFAULT "",
leader_id INTEGER NOT NULL,
silver INTEGER NOT NULL DEFAULT 0,
rep INTEGER NOT NULL DEFAULT 0,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for leader_id
$db->exec('CREATE INDEX idx_guilds_leader_id ON guilds (leader_id)');
created_or_error($r, 'guilds');
// Guild ranks
$db->exec('DROP TABLE IF EXISTS guild_ranks');
$r = $db->exec('CREATE TABLE guild_ranks (
guild_id INTEGER NOT NULL,
rank INTEGER NOT NULL,
name TEXT NOT NULL,
permissions TEXT NOT NULL
)');
// Create an index for guild_id
$db->exec('CREATE INDEX idx_guild_ranks_guild_id ON guild_ranks (guild_id)');
created_or_error($r, 'guild_ranks');
// Guild members
$db->exec('DROP TABLE IF EXISTS guild_members');
$r = $db->exec('CREATE TABLE guild_members (
guild_id INTEGER NOT NULL,
char_id INTEGER NOT NULL,
rank INTEGER NOT NULL,
rep INTEGER NOT NULL DEFAULT 0,
donated INTEGER NOT NULL DEFAULT 0,
joined DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for guild_id
$db->exec('CREATE INDEX idx_guild_members_guild_id ON guild_members (guild_id)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_guild_members_char_id ON guild_members (char_id)');
created_or_error($r, 'guild_members');
// NPCs
$db->exec('DROP TABLE IF EXISTS npcs');
$r = $db->exec('CREATE TABLE npcs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type INTEGER NOT NULL,
lore TEXT NOT NULL,
conversation TEXT NOT NULL,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
// Create an index for the x, y location
$db->exec('CREATE INDEX idx_npcs_location ON npcs (x, y)');
created_or_error($r, 'npcs');
// Town reputation
$db->exec('DROP TABLE IF EXISTS char_town_rep');
$r = $db->exec('CREATE TABLE char_town_rep (
char_id INTEGER NOT NULL,
town_id INTEGER NOT NULL,
rep INTEGER NOT NULL DEFAULT 0
)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_char_town_rep_char_id ON char_town_rep (char_id)');
created_or_error($r, 'char_town_rep');
// Items
$db->exec('DROP TABLE IF EXISTS items');
$r = $db->exec('CREATE TABLE items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 0,
rarity INTEGER NOT NULL DEFAULT 0,
forged INTEGER NOT NULL DEFAULT 0,
quality INTEGER NOT NULL DEFAULT 0,
value INTEGER NOT NULL DEFAULT 0,
consumable INTEGER NOT NULL DEFAULT 0,
duration INTEGER NOT NULL DEFAULT 0,
durability INTEGER NOT NULL DEFAULT 0,
max_durability INTEGER NOT NULL DEFAULT 0,
power INTEGER NOT NULL DEFAULT 0,
accuracy INTEGER NOT NULL DEFAULT 0,
penetration INTEGER NOT NULL DEFAULT 0,
focus INTEGER NOT NULL DEFAULT 0,
toughness INTEGER NOT NULL DEFAULT 0,
armor INTEGER NOT NULL DEFAULT 0,
resist INTEGER NOT NULL DEFAULT 0,
crit INTEGER NOT NULL DEFAULT 0,
precision INTEGER NOT NULL DEFAULT 0,
ferocity INTEGER NOT NULL DEFAULT 0,
luck INTEGER NOT NULL DEFAULT 0,
reqs TEXT NOT NULL DEFAULT "",
traits TEXT NOT NULL DEFAULT "",
lore TEXT NOT NULL DEFAULT "",
created DATETIME DEFAULT CURRENT_TIMESTAMP,
updated DATETIME DEFAULT CURRENT_TIMESTAMP
)');
created_or_error($r, 'items');
// Player traits
$db->exec('DROP TABLE IF EXISTS char_traits');
$r = $db->exec('CREATE TABLE char_traits (
char_id INTEGER NOT NULL,
trait_id INTEGER NOT NULL,
value INTEGER NOT NULL DEFAULT 0
)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_char_traits_char_id ON char_traits (char_id)');
created_or_error($r, 'char_traits');
// Character location
$db->exec('DROP TABLE IF EXISTS char_locations');
$r = $db->exec('CREATE TABLE char_locations (
char_id INTEGER NOT NULL,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
currently INTEGER NOT NULL DEFAULT 0
)');
// Create an index for char_id
$db->exec('CREATE INDEX idx_char_locations_char_id ON char_locations (char_id)');
// Create an index for x, y location
$db->exec('CREATE INDEX idx_char_locations_location ON char_locations (x, y)');
created_or_error($r, 'char_locations');
eln(green('Created database: ') . 'live.db');
if ($database !== 'reset') exit(0);
}
function created_or_error($result, $table)
{
if ($result === false) {
eln(red('Failed to create table: ') . $table);
exit(1);
}
eln(yellow('Created table: ') . $table);
}

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,7 @@
display: inline-block;
border: none;
font-size: 1rem;
font-family: var(--main-font);
background: #f7f8fa linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));
box-shadow: 0 1px 0 1px rgba(255, 255, 255, 0.3) inset, 0 0 0 1px #adb2bb inset;
color: #111111;

View File

@ -1,6 +1,7 @@
@import 'utilities.css';
@import 'buttons.css';
@import 'forms.css';
@import 'profile.css';
body {
background-color: #bcc6cf;
@ -10,10 +11,10 @@ body {
background-repeat: no-repeat;
max-width: 1640px;
margin: 0px auto;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
font-family: var(--main-font);
}
header {
header#main-header {
height: 76px;
color: white;
display: flex;
@ -315,7 +316,7 @@ span.badge {
font-family: monospace;
}
#center section {
#center > section {
&:not(:last-child) {
padding-bottom: 1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);

View File

@ -0,0 +1,49 @@
section.profile {
header {
text-align: center;
margin-bottom: 2rem;
h3 {
color: rgba(0, 0, 0, 0.3);
text-transform: uppercase;
font-size: 1rem;
}
}
div.grid {
display: flex;
gap: 1rem;
& > section {
width: 50%;
& > div:not(:last-child) {
margin-bottom: 1rem;
}
}
}
div.avatar {
display: flex;
align-items: center;
justify-content: center;
img {
max-width: 250px;
}
}
h4 {
text-align: center;
text-transform: uppercase;
color: rgba(0, 0, 0, 0.3);
}
div.stats {
& > div {
color: white;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 0.15rem;
padding: 0.25rem;
}
}
}

View File

@ -1,5 +1,6 @@
:root {
font-size: 16px;
--main-font: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
}
* {

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -41,6 +41,12 @@ router_post($r, '/character/delete', 'char_controller_delete_post');
router_get($r, '/world', 'world_controller_get');
router_post($r, '/move', 'world_controller_move_post');
/*
Profile
*/
router_get($r, '/profile', 'profile_controller_get');
router_get($r, '/profile/:id', 'profile_controller_show_get');
/*
Settings
*/

View File

@ -25,6 +25,7 @@ require_once SRC . '/controller/auth.php';
require_once SRC . '/controller/world.php';
require_once SRC . '/controller/settings.php';
require_once SRC . '/controller/auctions.php';
require_once SRC . '/controller/profile.php';
// Track the start time of the request
define('START_TIME', microtime(true));

View File

@ -164,6 +164,9 @@ function char_controller_create_post()
char_location_create($char);
char_gear_create($char);
// Award the Adventurer title.
char_award_title(1, $char);
// Set the character as the user's selected character
change_user_character($char);

View File

@ -0,0 +1,24 @@
<?php
/**
* View your current character's profile.
*/
function profile_controller_get()
{
auth_only_and_must_have_character();
$GLOBALS['active_nav_tab'] = "profile";
echo page('profile/main');
}
/**
* View another character's profile.
*/
function profile_controller_show_get($id)
{
auth_only_and_must_have_character();
if (($char = char_find($id)) == false) router_error(999);
if (user('char_id') == $id) redirect('/profile');
echo page('profile/show', ['char' => $char]);
}

View File

@ -279,3 +279,11 @@ function json_response($data)
echo json_encode($data);
exit;
}
/**
* Return a title's [name, lore].
*/
function title($title_id)
{
return db_query(db_live(), 'SELECT * FROM titles WHERE id = :i', [':i' => $title_id])->fetchArray();
}

View File

@ -73,11 +73,11 @@ function char_gear_create($char_id, $initialGear = [])
}
/**
* Get a charcter by their ID. Returns the character's data as an associative array, or false if not found.
* Get a charcter by their ID or name. Returns the character's data as an associative array, or false if not found.
*/
function char_find($char_id)
{
$char = db_query(db_live(), "SELECT * FROM characters WHERE id = :id", [':id' => $char_id])->fetchArray(SQLITE3_ASSOC);
$char = db_query(db_live(), "SELECT * FROM characters WHERE id = :id OR name = :id", [':id' => $char_id])->fetchArray(SQLITE3_ASSOC);
return $char === false ? false : $char;
}
@ -235,3 +235,43 @@ function char_delete($char_id)
}
}
}
/**
* Award a character a title.
*/
function char_award_title($title_id, $char_id)
{
$r = db_query(
db_live(),
'INSERT INTO owned_titles (`title_id`, `char_id`) VALUES (:t, :c)',
[':t' => $title_id, ':c' => $char_id]
);
if ($r === false) throw new Exception("Failed to award $char_id the title $title_id. (cat)");
}
/**
* Get the character's title's info and award date. Will use the currently logged in character's ID if $char_id is 0.
*/
function char_get_title($char_id = 0)
{
$char = $char_id === 0 ? char() : char_find($char_id);
$title = title($char['title_id']);
$stmt = db_query(
db_live(),
'SELECT awarded FROM owned_titles WHERE char_id = :c AND title_id = :t LIMIT 1',
[':c' => $char['id'], ':t' => $char['title_id']]
);
// If the query failed, send back an array with only an error.
if ($stmt === false) return ['error' => "owned titles query failed {$char['id']} (cat) (1)"];
$award = $stmt->fetchArray(SQLITE3_ASSOC);
// If no title, send back an empty array
if (!$award) return [];
$title['awarded'] = $award['awarded'];
return $title;
}

View File

@ -3,29 +3,29 @@
<div>
<img class="icon" src="/assets/img/icons/user1.png" alt="User">
<?= $char['name'] ?> <span class="badge ml-2 tooltip-hover" data-tooltip-content="Level"><?= $char['level'] ?></span>
<?php if ($char['attrib_points'] > 0): ?>
<span class="ui button primary badge ml-2 tooltip-hover" data-tooltip-content="Attribute Points"><?= $char['attrib_points'] ?></span>
<?php if ($char['att_points'] > 0): ?>
<span class="ui button primary badge ml-2 tooltip-hover" data-tooltip-content="Attribute Points"><?= $char['att_points'] ?></span>
<?php endif; ?>
</div>
<div>
<div class="char-meter">
<div class="hp" style="width: <?= percent($char['current_hp'], $char['max_hp']) ?>%"></div>
<div class="tooltip-trigger tooltip-hover" data-tooltip-content="Health<br><?= $char['current_hp'] ?> / <?= $char['max_hp'] ?>"></div>
<div class="hp" style="width: <?= percent($char['hp'], $char['m_hp']) ?>%"></div>
<div class="tooltip-trigger tooltip-hover" data-tooltip-content="Health<br><?= $char['hp'] ?> / <?= $char['m_hp'] ?>"></div>
</div>
</div>
<div>
<div class="char-meter">
<div class="mp" style="width: <?= percent($char['current_mp'], $char['max_mp']) ?>%"></div>
<div class="tooltip-trigger tooltip-hover" data-tooltip-content="Mana<br><?= $char['current_mp'] ?> / <?= $char['max_mp'] ?>"></div>
<div class="mp" style="width: <?= percent($char['mp'], $char['m_mp']) ?>%"></div>
<div class="tooltip-trigger tooltip-hover" data-tooltip-content="Mana<br><?= $char['mp'] ?> / <?= $char['m_mp'] ?>"></div>
</div>
</div>
<div>
<div class="char-meter">
<div class="tp" style="width: <?= percent($char['current_tp'], $char['max_tp']) ?>%"></div>
<div class="tooltip-trigger tooltip-hover" data-tooltip-content="Travel Points<br><?= $char['current_tp'] ?> / <?= $char['max_tp'] ?>"></div>
<div class="tp" style="width: <?= percent($char['tp'], $char['m_tp']) ?>%"></div>
<div class="tooltip-trigger tooltip-hover" data-tooltip-content="Travel Points<br><?= $char['tp'] ?> / <?= $char['m_tp'] ?>"></div>
</div>
</div>

View File

@ -8,7 +8,7 @@
<script src="/assets/scripts/htmx.js"></script>
</head>
<body>
<header>
<header id="main-header">
<div class="left">
<h1>Dragon Knight</h1>
</div>

View File

@ -0,0 +1,25 @@
<section class="profile">
<header>
<h1><?= char('name') ?></h1>
<h3>Level <?= char('level') ?> <?= char_get_title()['name'] ?></h2>
</header>
<div class="grid">
<section class="left">
<div class="avatar">
<img src="/assets/img/rathalos.webp">
</div>
<div class="stats">
<h4>Stats</h4>
<div>Power: <?= char('power') ?></div>
</div>
</section>
<section class="right">
<div class="bio">
HELLO THERE MY FRIEND.
</div>
</section>
</div>
</section>

View File

@ -0,0 +1,2 @@
<h1><?= $char['name'] ?><?php if ($char['user_id'] == user('id')): ?><span class="badge">Owned</span><?php endif; ?></h1>
other