2022-12-20 01:16:29 +00:00
|
|
|
const DB_VERSION = 120;
|
2021-03-01 21:57:39 +00:00
|
|
|
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
|
2021-01-07 00:08:19 +00:00
|
|
|
|
|
|
|
let db;
|
|
|
|
let reload = false;
|
2021-04-02 22:19:22 +00:00
|
|
|
let load_complete = false;
|
2021-06-19 07:02:53 +00:00
|
|
|
let load_in_progress = false;
|
2021-01-07 00:08:19 +00:00
|
|
|
let items;
|
2022-06-19 16:49:04 +00:00
|
|
|
let sets = new Map();
|
2021-03-14 07:55:08 +00:00
|
|
|
let itemMap;
|
|
|
|
let idMap;
|
|
|
|
let redirectMap;
|
|
|
|
let itemLists = new Map();
|
2021-01-07 00:08:19 +00:00
|
|
|
/*
|
|
|
|
* Load item set from local DB. Calls init() on success.
|
|
|
|
*/
|
2022-06-12 14:45:48 +00:00
|
|
|
async function load_local() {
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
let get_tx = db.transaction(['item_db', 'set_db'], 'readonly');
|
|
|
|
let sets_store = get_tx.objectStore('set_db');
|
|
|
|
let get_store = get_tx.objectStore('item_db');
|
|
|
|
let request = get_store.getAll();
|
|
|
|
request.onerror = function(event) {
|
|
|
|
reject("Could not read local item db...");
|
|
|
|
}
|
|
|
|
request.onsuccess = function(event) {
|
|
|
|
console.log("Successfully read local item db.");
|
|
|
|
}
|
2021-04-02 21:53:18 +00:00
|
|
|
|
2022-06-19 16:49:04 +00:00
|
|
|
// key-value iteration (hpp don't break this again)
|
|
|
|
// https://stackoverflow.com/questions/47931595/indexeddb-getting-all-data-with-keys
|
|
|
|
let request2 = sets_store.openCursor();
|
2021-04-02 21:53:18 +00:00
|
|
|
request2.onerror = function(event) {
|
2022-06-12 14:45:48 +00:00
|
|
|
reject("Could not read local set db...");
|
2021-01-10 02:16:19 +00:00
|
|
|
}
|
2021-04-02 21:53:18 +00:00
|
|
|
request2.onsuccess = function(event) {
|
2022-06-19 16:49:04 +00:00
|
|
|
let cursor = event.target.result;
|
|
|
|
if (cursor) {
|
|
|
|
let key = cursor.primaryKey;
|
|
|
|
let value = cursor.value;
|
|
|
|
sets.set(key, value);
|
|
|
|
cursor.continue();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// no more results
|
|
|
|
console.log("Successfully read local set db.");
|
|
|
|
}
|
|
|
|
};
|
2022-06-12 14:45:48 +00:00
|
|
|
get_tx.oncomplete = function(event) {
|
|
|
|
items = request.result;
|
|
|
|
init_maps();
|
|
|
|
load_complete = true;
|
|
|
|
db.close();
|
|
|
|
resolve();
|
|
|
|
}
|
|
|
|
});
|
2021-01-07 00:08:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2022-01-05 19:35:14 +00:00
|
|
|
* Clean bad item data.
|
|
|
|
* Assigns `displayName` to equal `name` if it is undefined.
|
|
|
|
* String values default to empty string.
|
|
|
|
* Numeric values default to 0.
|
|
|
|
* Major ID defaults to empty list.
|
2021-01-07 00:08:19 +00:00
|
|
|
*/
|
|
|
|
function clean_item(item) {
|
2021-01-23 10:53:24 +00:00
|
|
|
if (item.remapID === undefined) {
|
|
|
|
if (item.displayName === undefined) {
|
|
|
|
item.displayName = item.name;
|
|
|
|
}
|
|
|
|
item.skillpoints = [item.str, item.dex, item.int, item.def, item.agi];
|
|
|
|
item.reqs = [item.strReq, item.dexReq, item.intReq, item.defReq, item.agiReq];
|
2021-06-19 07:44:20 +00:00
|
|
|
item.has_negstat = false;
|
2021-06-19 07:02:53 +00:00
|
|
|
for (let i = 0; i < 5; ++i) {
|
2021-06-19 07:44:20 +00:00
|
|
|
if (item.reqs[i] === undefined) { item.reqs[i] = 0; }
|
|
|
|
if (item.skillpoints[i] === undefined) { item.skillpoints[i] = 0; }
|
|
|
|
if (item.skillpoints[i] < 0) { item.has_negstat = true; }
|
2021-06-19 07:02:53 +00:00
|
|
|
}
|
2021-07-19 21:04:56 +00:00
|
|
|
for (let key of item_fields) {
|
|
|
|
if (item[key] === undefined) {
|
|
|
|
if (key in str_item_fields) {
|
|
|
|
item[key] = "";
|
|
|
|
}
|
|
|
|
else if (key == "majorIds") {
|
|
|
|
item[key] = [];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
item[key] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-07 00:08:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-16 10:29:01 +00:00
|
|
|
async function load_old_version(version_str) {
|
|
|
|
load_in_progress = true;
|
|
|
|
let getUrl = window.location;
|
|
|
|
let baseUrl = `${getUrl.protocol}//${getUrl.host}/`;
|
|
|
|
// No random string -- we want to use caching
|
|
|
|
let url = `${baseUrl}/data/${version_str}/items.json`;
|
|
|
|
let result = await (await fetch(url)).json();
|
|
|
|
items = result.items;
|
|
|
|
for (const item of items) {
|
|
|
|
clean_item(item);
|
|
|
|
}
|
|
|
|
let sets_ = result.sets;
|
2022-12-17 09:11:19 +00:00
|
|
|
sets = new Map();
|
2022-12-16 10:29:01 +00:00
|
|
|
for (const set in sets_) {
|
|
|
|
sets.set(set, sets_[set]);
|
|
|
|
}
|
|
|
|
init_maps();
|
|
|
|
load_complete = true;
|
|
|
|
}
|
|
|
|
|
2021-01-07 00:08:19 +00:00
|
|
|
/*
|
|
|
|
* Load item set from remote DB (aka a big json file). Calls init() on success.
|
|
|
|
*/
|
2022-06-12 14:45:48 +00:00
|
|
|
async function load() {
|
2021-01-10 22:48:37 +00:00
|
|
|
let getUrl = window.location;
|
2022-12-16 10:29:01 +00:00
|
|
|
let baseUrl = `${getUrl.protocol}//${getUrl.host}/`;
|
2021-02-04 10:55:15 +00:00
|
|
|
// "Random" string to prevent caching!
|
|
|
|
let url = baseUrl + "/compress.json?"+new Date();
|
2021-01-07 00:08:19 +00:00
|
|
|
let result = await (await fetch(url)).json();
|
|
|
|
items = result.items;
|
2022-06-26 12:18:23 +00:00
|
|
|
let sets_ = result.sets;
|
2021-03-14 07:55:08 +00:00
|
|
|
|
2021-01-10 02:16:19 +00:00
|
|
|
let add_tx = db.transaction(['item_db', 'set_db'], 'readwrite');
|
2021-01-23 11:36:38 +00:00
|
|
|
add_tx.onabort = function(e) {
|
|
|
|
console.log(e);
|
2021-01-19 21:07:10 +00:00
|
|
|
console.log("Not enough space...");
|
|
|
|
};
|
2021-01-10 02:16:19 +00:00
|
|
|
let items_store = add_tx.objectStore('item_db');
|
2021-01-07 00:08:19 +00:00
|
|
|
let add_promises = [];
|
|
|
|
for (const item of items) {
|
|
|
|
clean_item(item);
|
2021-01-19 21:07:10 +00:00
|
|
|
let req = items_store.add(item, item.name);
|
|
|
|
req.onerror = function() {
|
|
|
|
console.log("ADD ITEM ERROR? " + item.name);
|
|
|
|
};
|
|
|
|
add_promises.push(req);
|
2021-01-10 02:16:19 +00:00
|
|
|
}
|
|
|
|
let sets_store = add_tx.objectStore('set_db');
|
2022-06-26 12:18:23 +00:00
|
|
|
for (const set in sets_) {
|
|
|
|
add_promises.push(sets_store.add(sets_[set], set));
|
|
|
|
sets.set(set, sets_[set]);
|
2021-01-07 00:08:19 +00:00
|
|
|
}
|
|
|
|
add_promises.push(add_tx.complete);
|
2022-06-12 14:45:48 +00:00
|
|
|
|
|
|
|
await Promise.all(add_promises);
|
|
|
|
init_maps();
|
|
|
|
load_complete = true;
|
|
|
|
db.close();
|
2021-01-07 00:08:19 +00:00
|
|
|
}
|
|
|
|
|
2022-06-12 14:45:48 +00:00
|
|
|
async function load_init() {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
let request = window.indexedDB.open('item_db', DB_VERSION);
|
2021-01-18 12:10:28 +00:00
|
|
|
|
2022-06-12 14:45:48 +00:00
|
|
|
request.onerror = function() {
|
|
|
|
reject("DB failed to open...");
|
|
|
|
};
|
2021-01-07 00:08:19 +00:00
|
|
|
|
2022-06-12 14:45:48 +00:00
|
|
|
request.onsuccess = async function() {
|
2021-06-19 07:51:07 +00:00
|
|
|
db = request.result;
|
2022-06-12 14:45:48 +00:00
|
|
|
if (load_in_progress) {
|
|
|
|
while (!load_complete) {
|
|
|
|
await sleep(100);
|
|
|
|
}
|
|
|
|
console.log("Skipping load...")
|
2021-06-19 07:02:53 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-12-16 10:29:01 +00:00
|
|
|
load_in_progress = true;
|
2022-06-12 14:45:48 +00:00
|
|
|
if (reload) {
|
|
|
|
console.log("Using new data...")
|
|
|
|
await load();
|
2021-06-19 07:51:07 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-06-12 14:45:48 +00:00
|
|
|
console.log("Using stored data...")
|
|
|
|
await load_local();
|
2021-06-19 07:51:07 +00:00
|
|
|
}
|
2021-06-19 07:02:53 +00:00
|
|
|
}
|
2022-06-12 14:45:48 +00:00
|
|
|
resolve();
|
|
|
|
};
|
2021-01-07 00:08:19 +00:00
|
|
|
|
2022-06-12 14:45:48 +00:00
|
|
|
request.onupgradeneeded = function(e) {
|
|
|
|
reload = true;
|
2021-01-07 00:08:19 +00:00
|
|
|
|
2022-06-12 14:45:48 +00:00
|
|
|
let db = e.target.result;
|
|
|
|
|
|
|
|
try {
|
|
|
|
db.deleteObjectStore('item_db');
|
|
|
|
}
|
|
|
|
catch (error) {
|
|
|
|
console.log("Could not delete item DB. This is probably fine");
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
db.deleteObjectStore('set_db');
|
|
|
|
}
|
|
|
|
catch (error) {
|
|
|
|
console.log("Could not delete set DB. This is probably fine");
|
|
|
|
}
|
2021-01-18 12:10:28 +00:00
|
|
|
|
2022-06-12 14:45:48 +00:00
|
|
|
db.createObjectStore('item_db');
|
|
|
|
db.createObjectStore('set_db');
|
2021-01-07 00:08:19 +00:00
|
|
|
|
2022-06-12 14:45:48 +00:00
|
|
|
console.log("DB setup complete...");
|
|
|
|
};
|
|
|
|
});
|
2021-01-07 00:08:19 +00:00
|
|
|
}
|
2021-03-14 07:55:08 +00:00
|
|
|
|
2022-05-22 10:21:34 +00:00
|
|
|
let none_items = [
|
|
|
|
["armor", "helmet", "No Helmet"],
|
|
|
|
["armor", "chestplate", "No Chestplate"],
|
|
|
|
["armor", "leggings", "No Leggings"],
|
|
|
|
["armor", "boots", "No Boots"],
|
|
|
|
["accessory", "ring", "No Ring 1"],
|
|
|
|
["accessory", "ring", "No Ring 2"],
|
|
|
|
["accessory", "bracelet", "No Bracelet"],
|
|
|
|
["accessory", "necklace", "No Necklace"],
|
|
|
|
["weapon", "dagger", "No Weapon"],
|
|
|
|
];
|
|
|
|
for (let i = 0; i < none_items.length; i++) {
|
|
|
|
let item = Object();
|
|
|
|
item.slots = 0;
|
|
|
|
item.category = none_items[i][0];
|
|
|
|
item.type = none_items[i][1];
|
|
|
|
item.name = none_items[i][2];
|
|
|
|
item.displayName = item.name;
|
|
|
|
item.set = null;
|
|
|
|
item.quest = null;
|
|
|
|
item.skillpoints = [0, 0, 0, 0, 0];
|
|
|
|
item.has_negstat = false;
|
|
|
|
item.reqs = [0, 0, 0, 0, 0];
|
|
|
|
item.fixID = true;
|
|
|
|
item.tier = "Normal";
|
|
|
|
item.id = 10000 + i;
|
|
|
|
item.nDam = "0-0";
|
|
|
|
item.eDam = "0-0";
|
|
|
|
item.tDam = "0-0";
|
|
|
|
item.wDam = "0-0";
|
|
|
|
item.fDam = "0-0";
|
|
|
|
item.aDam = "0-0";
|
|
|
|
clean_item(item);
|
|
|
|
|
|
|
|
none_items[i] = item;
|
|
|
|
}
|
|
|
|
|
2021-03-14 07:55:08 +00:00
|
|
|
function init_maps() {
|
2022-12-20 21:34:11 +00:00
|
|
|
// List of 'raw' "none" items (No Helmet, etc), in order helmet, chestplate... ring1, ring2, brace, neck, weapon.
|
|
|
|
for (const it of item_types) {
|
|
|
|
itemLists.set(it, []);
|
|
|
|
}
|
|
|
|
|
2021-03-14 07:55:08 +00:00
|
|
|
itemMap = new Map();
|
|
|
|
/* Mapping from item names to set names. */
|
|
|
|
idMap = new Map();
|
|
|
|
redirectMap = new Map();
|
2022-05-22 10:21:34 +00:00
|
|
|
items = items.concat(none_items);
|
2021-03-14 07:55:08 +00:00
|
|
|
//console.log(items);
|
|
|
|
for (const item of items) {
|
|
|
|
if (item.remapID === undefined) {
|
|
|
|
itemLists.get(item.type).push(item.displayName);
|
|
|
|
itemMap.set(item.displayName, item);
|
2022-05-22 10:21:34 +00:00
|
|
|
if (none_items.includes(item)) {
|
2021-03-14 07:55:08 +00:00
|
|
|
idMap.set(item.id, "");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
idMap.set(item.id, item.displayName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
redirectMap.set(item.id, item.remapID);
|
|
|
|
}
|
|
|
|
}
|
2022-09-16 05:54:36 +00:00
|
|
|
for (const [set_name, set_data] of sets) {
|
|
|
|
for (const item_name of set_data.items) {
|
|
|
|
itemMap.get(item_name).set = set_name;
|
|
|
|
}
|
|
|
|
}
|
2021-04-01 06:52:43 +00:00
|
|
|
}
|