wynnbuilder-forked-for-changes/js/load.js
2022-01-24 13:28:23 -08:00

271 lines
8 KiB
JavaScript

const DB_VERSION = 90;
// @See https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/video-store/index.jsA
let db;
let reload = false;
let load_complete = false;
let load_in_progress = false;
let items;
let sets;
let itemMap;
let idMap;
let redirectMap;
let itemLists = new Map();
/*
* Load item set from local DB. Calls init() on success.
*/
async function load_local(init_func) {
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) {
console.log("Could not read local item db...");
}
request.onsuccess = function(event) {
console.log("Successfully read local item db.");
items = request.result;
//console.log(items);
let request2 = sets_store.openCursor();
sets = {};
request2.onerror = function(event) {
console.log("Could not read local set db...");
}
request2.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
sets[cursor.primaryKey] = cursor.value;
cursor.continue();
}
else {
console.log("Successfully read local set db.");
//console.log(sets);
init_maps();
init_func();
load_complete = true;
}
}
}
await get_tx.complete;
db.close();
}
/*
* 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.
*/
function clean_item(item) {
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];
item.has_negstat = false;
for (let i = 0; i < 5; ++i) {
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; }
}
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;
}
}
}
}
}
/*
* Load item set from remote DB (aka a big json file). Calls init() on success.
*/
async function load(init_func) {
let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1];
// "Random" string to prevent caching!
let url = baseUrl + "/compress.json?"+new Date();
let result = await (await fetch(url)).json();
items = result.items;
sets = result.sets;
// let clear_tx = db.transaction(['item_db', 'set_db'], 'readwrite');
// let clear_items = clear_tx.objectStore('item_db');
// let clear_sets = clear_tx.objectStore('item_db');
//
// await clear_items.clear();
// await clear_sets.clear();
// await clear_tx.complete;
let add_tx = db.transaction(['item_db', 'set_db'], 'readwrite');
add_tx.onabort = function(e) {
console.log(e);
console.log("Not enough space...");
};
let items_store = add_tx.objectStore('item_db');
let add_promises = [];
for (const item of items) {
clean_item(item);
let req = items_store.add(item, item.name);
req.onerror = function() {
console.log("ADD ITEM ERROR? " + item.name);
};
add_promises.push(req);
}
let sets_store = add_tx.objectStore('set_db');
for (const set in sets) {
add_promises.push(sets_store.add(sets[set], set));
}
add_promises.push(add_tx.complete);
Promise.all(add_promises).then((values) => {
init_maps();
init_func();
load_complete = true;
});
// DB not closed? idfk man
}
function load_init(init_func) {
if (load_complete) {
console.log("Item db already loaded, skipping load sequence");
init_func();
return;
}
let request = window.indexedDB.open('item_db', DB_VERSION);
request.onerror = function() {
console.log("DB failed to open...");
};
request.onsuccess = function() {
(async function() {
db = request.result;
if (!reload) {
console.log("Using stored data...")
load_local(init_func);
}
else {
if (load_in_progress) {
while (!load_complete) {
await sleep(100);
}
console.log("Skipping load...")
init_func();
}
else {
// Not 100% safe... whatever!
load_in_progress = true
console.log("Using new data...")
load(init_func);
}
}
})()
}
request.onupgradeneeded = function(e) {
reload = true;
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");
}
db.createObjectStore('item_db');
db.createObjectStore('set_db');
console.log("DB setup complete...");
}
}
function init_maps() {
//warp
itemMap = new Map();
/* Mapping from item names to set names. */
idMap = new Map();
redirectMap = new Map();
for (const it of itemTypes) {
itemLists.set(it, []);
}
let noneItems = [
["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"],
["tome", "weaponTome", "No Weapon Tome"],
["tome", "armorTome", "No Armour Tome"],
["tome", "guildTome", "No Guild Tome"]
];
for (let i = 0; i < 12; i++) {
let item = Object();
item.slots = 0;
item.category = noneItems[i][0];
item.type = noneItems[i][1];
item.name = noneItems[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";//do not get rid of this @hpp
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);
noneItems[i] = item;
}
items = items.concat(noneItems);
//console.log(items);
for (const item of items) {
if (item.remapID === undefined) {
itemLists.get(item.type).push(item.displayName);
itemMap.set(item.displayName, item);
if (noneItems.includes(item)) {
idMap.set(item.id, "");
}
else {
idMap.set(item.id, item.displayName);
}
}
else {
redirectMap.set(item.id, item.remapID);
}
}
console.log(itemMap);
}