diff --git a/js/builder/build_encode_decode.js b/js/builder/build_encode_decode.js index d67cf64..0823c4e 100644 --- a/js/builder/build_encode_decode.js +++ b/js/builder/build_encode_decode.js @@ -4,6 +4,37 @@ let build_powders; function getItemNameFromID(id) { return idMap.get(id); } function getTomeNameFromID(id) { return tomeIDMap.get(id); } +function parsePowdering(powder_info) { + // TODO: Make this run in linear instead of quadratic time... ew + let powdering = []; + for (let i = 0; i < 5; ++i) { + let powders = ""; + let n_blocks = Base64.toInt(powder_info.charAt(0)); + // console.log(n_blocks + " blocks"); + powder_info = powder_info.slice(1); + for (let j = 0; j < n_blocks; ++j) { + let block = powder_info.slice(0,5); + let six_powders = Base64.toInt(block); + for (let k = 0; k < 6 && six_powders != 0; ++k) { + powders += powderNames.get((six_powders & 0x1f) - 1); + six_powders >>>= 5; + } + powder_info = powder_info.slice(5); + } + powdering[i] = powders; + } + return [powdering, powder_info]; +} + +let atree_data = null; +const wynn_version_names = [ + '2.0.1.1', + '2.0.1.2' +]; +const WYNN_VERSION_LATEST = wynn_version_names.length - 1; +// Default to the newest version. +let wynn_version_id = WYNN_VERSION_LATEST; + /* * Populate fields based on url, and calculate build. * TODO: THIS CODE IS GOD AWFUL result of being lazy @@ -193,154 +224,6 @@ async function parse_hash(url_tag) { } } -function parsePowdering(powder_info) { - // TODO: Make this run in linear instead of quadratic time... ew - let powdering = []; - for (let i = 0; i < 5; ++i) { - let powders = ""; - let n_blocks = Base64.toInt(powder_info.charAt(0)); - // console.log(n_blocks + " blocks"); - powder_info = powder_info.slice(1); - for (let j = 0; j < n_blocks; ++j) { - let block = powder_info.slice(0,5); - let six_powders = Base64.toInt(block); - for (let k = 0; k < 6 && six_powders != 0; ++k) { - powders += powderNames.get((six_powders & 0x1f) - 1); - six_powders >>>= 5; - } - powder_info = powder_info.slice(5); - } - powdering[i] = powders; - } - return [powdering, powder_info]; -} - -let atree_data = null; - -/* - * Populate fields based on url, and calculate build. - */ -function decodeBuild(url_tag) { - if (url_tag) { - //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) - //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)); - } - info[1] = equipments.slice(27); - } - else if (version_number == 4) { - let info_str = info[1]; - 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; - } - } - info[1] = info_str.slice(start_idx); - } - else if (version_number <= 7) { - let info_str = info[1]; - 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; - } - } - info[1] = 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 = info[1]; - let res = parsePowdering(powder_info); - powdering = res[0]; - } else if (version_number == 2) { - save_skp = true; - let skillpoint_info = info[1].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 = info[1].slice(10); - let res = parsePowdering(powder_info); - powdering = res[0]; - } else if (version_number <= 7){ - level = Base64.toInt(info[1].slice(10,12)); - setValue("level-choice",level); - save_skp = true; - let skillpoint_info = info[1].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 = info[1].slice(12); - - let res = parsePowdering(powder_info); - powdering = res[0]; - info[1] = res[1]; - } - // Tomes. - if (version >= 6 && version < 8) { - //tome values do not appear in anything before v6. - for (let i in tomes) { - let tome_str = info[1].charAt(i); - let tome_name = getTomeNameFromID(Base64.toInt(tome_str)); - setValue(tomeInputs[i], tome_name); - } - info[1] = info[1].slice(7); - } - - if (version == 7) { - // ugly af. only works since its the last thing. will be fixed with binary decode - atree_data = new BitVector(info[1]); - } - 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]); - } - } -} - /* Stores the entire build in a string using B64 encoding and adds it to the URL. */ function encodeBuild(build, powders, skillpoints, atree, atree_state) { diff --git a/js/utils.js b/js/utils.js index c432812..d3211cf 100644 --- a/js/utils.js +++ b/js/utils.js @@ -176,7 +176,7 @@ Base64 = (function () { if (data == 0) { length = 0; } else { - length = Math.ceil(Math.log(data) / Math.log(2)); + length = Math.ceil(Math.log(data + 1) / Math.log(2)); //+1 to account for powers of 2 } } if (length < 0) { @@ -211,7 +211,7 @@ Base64 = (function () { */ read_bit(idx) { if (idx < 0 || idx >= this.length) { - throw new RangeError("Cannot read bit outside the range of the BitVector. ("+idx+" > "+this.length+")"); + throw new RangeError("Cannot read bit outside the range of the BitVector. ("+idx+" >= "+this.length+")"); } return ((this.bits[Math.floor(idx / 32)] & (1 << idx)) == 0 ? 0 : 1); } @@ -369,7 +369,7 @@ Base64 = (function () { } } else if (typeof data === "number") { //convert to int just in case - let int = Math.round(data); + let int = Math.round(data); //range of numbers that "could" fit in a uint32 -> [0, 2^32) U [-2^31, 2^31) if (data > 2**32 - 1 || data < -(2 ** 31)) { @@ -377,13 +377,19 @@ Base64 = (function () { } //could be split between multiple new ints //reminder that shifts implicitly mod 32 - this.bits[curr_idx] |= ((int & ~((~0) << length)) << (this.length)); - if (((this.length - 1) % 32 + 1) + length > 32) { + if (length == 32) { + this.bits[curr_idx] |= int << (this.length); + } else { + this.bits[curr_idx] |= ((int & ~((~0) << length)) << (this.length)); + } + + //overflow part + if ((pos % 32) + length > 32) { this.bits[curr_idx + 1] = (int >>> (32 - this.length)); } } else if (data instanceof BitVector) { //fill to end of curr int of existing bv - let other_pos = (32 - (pos % 32)) % 32; + let other_pos = (32 - (pos % 32)); this.bits[curr_idx] |= data.slice(0, other_pos); curr_idx += 1; @@ -405,18 +411,6 @@ 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. @@ -1054,5 +1048,3 @@ if (screen.width < 992) { scrollPos = document.documentElement.scrollTop; }); } - -test_bv(); \ No newline at end of file diff --git a/unit_tests/index.html b/unit_tests/index.html new file mode 100644 index 0000000..7298b7d --- /dev/null +++ b/unit_tests/index.html @@ -0,0 +1,26 @@ + +
+ + + + + + + + + + + + + +