parse hash
This commit is contained in:
parent
7b295e4e46
commit
420e66842d
2 changed files with 214 additions and 9 deletions
|
@ -4,6 +4,195 @@ let build_powders;
|
|||
function getItemNameFromID(id) { return idMap.get(id); }
|
||||
function getTomeNameFromID(id) { return tomeIDMap.get(id); }
|
||||
|
||||
/*
|
||||
* Populate fields based on url, and calculate build.
|
||||
* TODO: THIS CODE IS GOD AWFUL result of being lazy
|
||||
* fix all the slice() and break into functions or do something about it... its inefficient, ugly and error prone
|
||||
*/
|
||||
async function parse_hash(url_tag) {
|
||||
const default_load_promises = [ load_atree_data(wynn_version_names[WYNN_VERSION_LATEST]),
|
||||
load_init(), load_ing_init(), load_tome_init() ];
|
||||
if (!url_tag) {
|
||||
await Promise.all(default_load_promises);
|
||||
return;
|
||||
}
|
||||
//default values
|
||||
let equipment = [null, null, null, null, null, null, null, null, null];
|
||||
let tomes = [null, null, null, null, null, null, null];
|
||||
let powdering = ["", "", "", "", ""];
|
||||
let info = url_tag.split("_");
|
||||
let version = info[0];
|
||||
let save_skp = false;
|
||||
let skillpoints = [0, 0, 0, 0, 0];
|
||||
let level = 106;
|
||||
|
||||
let version_number = parseInt(version);
|
||||
let data_str = info[1];
|
||||
if (version_number >= 8) {
|
||||
// parse query parameters
|
||||
// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
|
||||
const url_params = new URLSearchParams(window.location.search);
|
||||
const version_id = url_params.get('v');
|
||||
wynn_version_id = parseInt(version_id);
|
||||
if (isNaN(wynn_version_id) || wynn_version_id > WYNN_VERSION_LATEST || wynn_version_id < 0) {
|
||||
// TODO: maybe make the NAN try to use the human readable version?
|
||||
// NOTE: Failing silently... do we want to raise a loud error?
|
||||
console.log("Explicit version not found or invalid, using latest version");
|
||||
wynn_version_id = WYNN_VERSION_LATEST;
|
||||
}
|
||||
else {
|
||||
console.log(`Build link for wynn version ${wynn_version_id} (${wynn_version_names[wynn_version_id]})`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Change the default to oldest. (A time before v8)
|
||||
wynn_version_id = 0;
|
||||
}
|
||||
|
||||
// the deal with this is because old versions should default to 0 (oldest wynn item version), and v8+ defaults to latest.
|
||||
// its ugly... but i think this is the behavior we want...
|
||||
if (wynn_version_id != WYNN_VERSION_LATEST) {
|
||||
// force reload item database and such.
|
||||
// TODO MUST: display a warning showing older version!
|
||||
const msg = 'This build was created in an older version of wynncraft '
|
||||
+ `(${wynn_version_names[wynn_version_id]} < ${wynn_version_names[WYNN_VERSION_LATEST]}). `
|
||||
+ 'Would you like to update to the latest version? Updating may break the build and ability tree.';
|
||||
|
||||
if (confirm(msg)) {
|
||||
wynn_version_id = WYNN_VERSION_LATEST;
|
||||
}
|
||||
else {
|
||||
version_name = wynn_version_names[wynn_version_id];
|
||||
const load_promises = [ load_atree_data(version_name),
|
||||
load_old_version(version_name),
|
||||
load_ings_old_version(version_name),
|
||||
load_tome_old_version(version_name) ];
|
||||
console.log("Loading old version data...", version_name)
|
||||
await Promise.all(load_promises);
|
||||
}
|
||||
}
|
||||
if (wynn_version_id == WYNN_VERSION_LATEST) {
|
||||
await Promise.all(default_load_promises);
|
||||
}
|
||||
|
||||
//equipment (items)
|
||||
// TODO: use filters
|
||||
if (version_number < 4) {
|
||||
let equipments = info[1];
|
||||
for (let i = 0; i < 9; ++i ) {
|
||||
let equipment_str = equipments.slice(i*3,i*3+3);
|
||||
equipment[i] = getItemNameFromID(Base64.toInt(equipment_str));
|
||||
}
|
||||
data_str = equipments.slice(27);
|
||||
}
|
||||
else if (version_number == 4) {
|
||||
let info_str = data_str;
|
||||
let start_idx = 0;
|
||||
for (let i = 0; i < 9; ++i ) {
|
||||
if (info_str.charAt(start_idx) === "-") {
|
||||
equipment[i] = "CR-"+info_str.slice(start_idx+1, start_idx+18);
|
||||
start_idx += 18;
|
||||
}
|
||||
else {
|
||||
let equipment_str = info_str.slice(start_idx, start_idx+3);
|
||||
equipment[i] = getItemNameFromID(Base64.toInt(equipment_str));
|
||||
start_idx += 3;
|
||||
}
|
||||
}
|
||||
data_str = info_str.slice(start_idx);
|
||||
}
|
||||
else if (version_number <= 8) {
|
||||
let info_str = data_str;
|
||||
let start_idx = 0;
|
||||
for (let i = 0; i < 9; ++i ) {
|
||||
if (info_str.slice(start_idx,start_idx+3) === "CR-") {
|
||||
equipment[i] = info_str.slice(start_idx, start_idx+20);
|
||||
start_idx += 20;
|
||||
} else if (info_str.slice(start_idx+3,start_idx+6) === "CI-") {
|
||||
let len = Base64.toInt(info_str.slice(start_idx,start_idx+3));
|
||||
equipment[i] = info_str.slice(start_idx+3,start_idx+3+len);
|
||||
start_idx += (3+len);
|
||||
} else {
|
||||
let equipment_str = info_str.slice(start_idx, start_idx+3);
|
||||
equipment[i] = getItemNameFromID(Base64.toInt(equipment_str));
|
||||
start_idx += 3;
|
||||
}
|
||||
}
|
||||
data_str = info_str.slice(start_idx);
|
||||
}
|
||||
//constant in all versions
|
||||
for (let i in equipment) {
|
||||
setValue(equipment_inputs[i], equipment[i]);
|
||||
}
|
||||
|
||||
//level, skill point assignments, and powdering
|
||||
if (version_number == 1) {
|
||||
let powder_info = data_str;
|
||||
let res = parsePowdering(powder_info);
|
||||
powdering = res[0];
|
||||
} else if (version_number == 2) {
|
||||
save_skp = true;
|
||||
let skillpoint_info = data_str.slice(0, 10);
|
||||
for (let i = 0; i < 5; ++i ) {
|
||||
skillpoints[i] = Base64.toIntSigned(skillpoint_info.slice(i*2,i*2+2));
|
||||
}
|
||||
|
||||
let powder_info = data_str.slice(10);
|
||||
let res = parsePowdering(powder_info);
|
||||
powdering = res[0];
|
||||
} else if (version_number <= 8){
|
||||
level = Base64.toInt(data_str.slice(10,12));
|
||||
setValue("level-choice",level);
|
||||
save_skp = true;
|
||||
let skillpoint_info = data_str.slice(0, 10);
|
||||
for (let i = 0; i < 5; ++i ) {
|
||||
skillpoints[i] = Base64.toIntSigned(skillpoint_info.slice(i*2,i*2+2));
|
||||
}
|
||||
|
||||
let powder_info = data_str.slice(12);
|
||||
|
||||
let res = parsePowdering(powder_info);
|
||||
powdering = res[0];
|
||||
data_str = res[1];
|
||||
}
|
||||
// Tomes.
|
||||
if (version_number >= 6) {
|
||||
//tome values do not appear in anything before v6.
|
||||
if (version_number < 8) {
|
||||
for (let i in tomes) {
|
||||
let tome_str = data_str.charAt(i);
|
||||
let tome_name = getTomeNameFromID(Base64.toInt(tome_str));
|
||||
setValue(tomeInputs[i], tome_name);
|
||||
}
|
||||
data_str = data_str.slice(7);
|
||||
}
|
||||
else {
|
||||
// 2chr tome encoding to allow for more tomes.
|
||||
for (let i in tomes) {
|
||||
let tome_str = data_str.slice(2*i, 2*i+2);
|
||||
let tome_name = getTomeNameFromID(Base64.toInt(tome_str));
|
||||
setValue(tomeInputs[i], tome_name);
|
||||
}
|
||||
data_str = data_str.slice(14);
|
||||
}
|
||||
}
|
||||
|
||||
if (version_number >= 7) {
|
||||
// ugly af. only works since its the last thing. will be fixed with binary decode
|
||||
atree_data = new BitVector(data_str);
|
||||
}
|
||||
else {
|
||||
atree_data = null;
|
||||
}
|
||||
|
||||
for (let i in powder_inputs) {
|
||||
setValue(powder_inputs[i], powdering[i]);
|
||||
}
|
||||
for (let i in skillpoints) {
|
||||
setValue(skp_order[i] + "-skp", skillpoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function parsePowdering(powder_info) {
|
||||
// TODO: Make this run in linear instead of quadratic time... ew
|
||||
let powdering = [];
|
||||
|
|
32
js/utils.js
32
js/utils.js
|
@ -172,7 +172,13 @@ Base64 = (function () {
|
|||
}
|
||||
}
|
||||
} else if (typeof data === "number") {
|
||||
if (typeof length === "undefined")
|
||||
if (typeof length === "undefined") {
|
||||
if (data == 0) {
|
||||
length = 0;
|
||||
} else {
|
||||
length = Math.ceil(Math.log(data) / Math.log(2));
|
||||
}
|
||||
}
|
||||
if (length < 0) {
|
||||
throw new RangeError("BitVector must have nonnegative length.");
|
||||
}
|
||||
|
@ -333,13 +339,9 @@ Base64 = (function () {
|
|||
let new_length = this.length + length;
|
||||
if (this.bits.length * this.bits.BYTES_PER_ELEMENT * 8 < new_length) {
|
||||
//resize the internal repr by a factor of 2 before recursive calling
|
||||
let bit_vec = [];
|
||||
for (const int of this.bits) {
|
||||
bit_vec.push(int);
|
||||
}
|
||||
//effectively double size - TODO 1-line this
|
||||
for (const int of this.bits) {
|
||||
bit_vec.push(0);
|
||||
let bit_vec = Array(2 * this.bits.length).fill(0);
|
||||
for (let i = 0; i < this.bits.length; i++) {
|
||||
bit_vec[i] = this.bits[i];
|
||||
}
|
||||
|
||||
this.bits = new Uint32Array(bit_vec);
|
||||
|
@ -403,6 +405,18 @@ Base64 = (function () {
|
|||
}
|
||||
};
|
||||
|
||||
function test_bv() {
|
||||
//empty array
|
||||
let bv = new BitVector(0);
|
||||
bv.append(10, 4);
|
||||
console.log(bv);
|
||||
|
||||
bv = new BitVector(0);
|
||||
bv.append(10, 5);
|
||||
console.log(bv);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Turns a raw stat and a % stat into a final stat on the basis that - raw and >= 100% becomes 0 and + raw and <=-100% becomes negative.
|
||||
|
@ -1040,3 +1054,5 @@ if (screen.width < 992) {
|
|||
scrollPos = document.documentElement.scrollTop;
|
||||
});
|
||||
}
|
||||
|
||||
test_bv();
|
Loading…
Reference in a new issue