sock encoding build.encode started, bitvec append allow appending bitvecs started
This commit is contained in:
parent
99d2b8273a
commit
c65da33ccd
2 changed files with 94 additions and 49 deletions
|
@ -125,7 +125,7 @@ function decodeBuild(url_tag) {
|
|||
info[1] = res[1];
|
||||
}
|
||||
// Tomes.
|
||||
if (version >= 6) {
|
||||
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);
|
||||
|
@ -135,7 +135,7 @@ function decodeBuild(url_tag) {
|
|||
info[1] = info[1].slice(7);
|
||||
}
|
||||
|
||||
if (version >= 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]);
|
||||
}
|
||||
|
@ -155,63 +155,100 @@ function decodeBuild(url_tag) {
|
|||
/* Stores the entire build in a string using B64 encoding and adds it to the URL.
|
||||
*/
|
||||
function encodeBuild(build, powders, skillpoints, atree, atree_state) {
|
||||
|
||||
//currently on version 8 - a unified version for all build types using bit-level encoding
|
||||
if (build) {
|
||||
let build_string;
|
||||
|
||||
//V6 encoding - Tomes
|
||||
//V7 encoding - ATree
|
||||
build_version = 5;
|
||||
build_string = "";
|
||||
tome_string = "";
|
||||
//final link will be [build_vers]_[len_string]_[build_string]
|
||||
build_version = 8;
|
||||
let len_string = "";
|
||||
let build_string = "";
|
||||
let build_bits = new BitVector(0, 0);
|
||||
|
||||
//ITEMS
|
||||
for (const item of build.items) {
|
||||
if (item.statMap.get("custom")) {
|
||||
let custom = "CI-"+encodeCustom(item, true);
|
||||
build_string += Base64.fromIntN(custom.length, 3) + custom;
|
||||
build_version = Math.max(build_version, 5);
|
||||
if (item.statMap.get("NONE") && item.statMap.get("NONE") === true) {
|
||||
build_bits.append(0, 2); //00
|
||||
} else if (item.statMap.get("custom")) {
|
||||
build_bits.append(3, 2); //11
|
||||
//BitVector CI encoding TODO
|
||||
|
||||
// let custom = "CI-"+encodeCustom(item, true);
|
||||
// build_string += Base64.fromIntN(custom.length, 3) + custom;
|
||||
// build_version = Math.max(build_version, 5);
|
||||
} else if (item.statMap.get("crafted")) {
|
||||
build_string += "CR-"+encodeCraft(item);
|
||||
} else if (item.statMap.get("category") === "tome") {
|
||||
let tome_id = item.statMap.get("id");
|
||||
if (tome_id <= 60) {
|
||||
// valid normal tome. ID 61-63 is for NONE tomes.
|
||||
build_version = Math.max(build_version, 6);
|
||||
}
|
||||
tome_string += Base64.fromIntN(tome_id, 1);
|
||||
build_bits.append(2, 2); //10
|
||||
//BitVector CR encoding TODO
|
||||
|
||||
// build_string += "CR-"+encodeCraft(item);
|
||||
} else {
|
||||
build_string += Base64.fromIntN(item.statMap.get("id"), 3);
|
||||
}
|
||||
}
|
||||
if (item.statMap.get("category") === "tome") {
|
||||
//we will encode tomes later
|
||||
continue;
|
||||
} else {
|
||||
build_bits.append(1, 2); //01
|
||||
build_bits.append(item.statMap.get("id"), 13);
|
||||
|
||||
for (const skp of skillpoints) {
|
||||
build_string += Base64.fromIntN(skp, 2); // Maximum skillpoints: 2048
|
||||
}
|
||||
build_string += Base64.fromIntN(build.level, 2);
|
||||
for (const _powderset of powders) {
|
||||
let n_bits = Math.ceil(_powderset.length / 6);
|
||||
build_string += Base64.fromIntN(n_bits, 1); // Hard cap of 378 powders.
|
||||
// Slice copy.
|
||||
let powderset = _powderset.slice();
|
||||
while (powderset.length != 0) {
|
||||
let firstSix = powderset.slice(0,6).reverse();
|
||||
let powder_hash = 0;
|
||||
for (const powder of firstSix) {
|
||||
powder_hash = (powder_hash << 5) + 1 + powder; // LSB will be extracted first.
|
||||
//powderable
|
||||
if (powderable_keys.includes(item.statMap.get("type"))) {
|
||||
if (item.statMap.get("powders") && item.statMap.get("powders").length !== 0) {
|
||||
//has powders
|
||||
build_bits.append(1, 1);
|
||||
|
||||
//num of powders in 8 bits, then each powder (6 bits)
|
||||
//Having more than 256 powders on a vanilla item is NOT HANDLED.
|
||||
build_bits.append(item.statMap.get("powders").length, 8);
|
||||
for (const powder of item.statMap.get("powders")) {
|
||||
build_bits.append(powder, 6);
|
||||
}
|
||||
} else {
|
||||
//no powders
|
||||
build_bits.append(0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
build_string += Base64.fromIntN(powder_hash, 5);
|
||||
powderset = powderset.slice(6);
|
||||
}
|
||||
}
|
||||
build_string += tome_string;
|
||||
|
||||
if (atree.length > 0 && atree_state.get(atree[0].ability.id).active) {
|
||||
build_version = Math.max(build_version, 7);
|
||||
const bitvec = encode_atree(atree, atree_state);
|
||||
build_string += bitvec.toB64();
|
||||
//SKILL POINTS
|
||||
|
||||
//the original schema included a flag to indicate whether or not skill points are included.
|
||||
//any reason for having a flag isn't implemented yet, so for now every build will have the skill point flag set.
|
||||
build_bits.append(1, 1);
|
||||
|
||||
for (const skp of build.base_skillpoints) {
|
||||
build_bits.append(skp, 8); // Maximum skillpoints: 255 (allows for manual assign up to 150)
|
||||
}
|
||||
|
||||
return build_version.toString() + "_" + build_string;
|
||||
//BUILD LEVEL
|
||||
|
||||
// [flag to indicate if level is not 106 (0/1)]
|
||||
// [else: level (7 bits, allows for lv 1->127)]
|
||||
if (player_build.level != 106) {
|
||||
build_bits.append(1, 1);
|
||||
build_bits.append(player_build.level, 7);
|
||||
} else {
|
||||
build_bits.append(0, 1);
|
||||
}
|
||||
|
||||
// TOMES
|
||||
|
||||
// [flag to indicate if tomes are included (0/1)]
|
||||
// [if set: 7 sequential tome IDs, each 6 bits unsigned]
|
||||
|
||||
|
||||
// ATREE
|
||||
|
||||
// [flag to indicate if atree data is present]
|
||||
// [atree data: see existing encoding impl] //idk the impl
|
||||
if (atree.length > 0 && atree_state.get(atree[0].ability.id).active) {
|
||||
build_bits.append(1, 1);
|
||||
const atree_bitvec = encode_atree(atree, atree_state);
|
||||
build_bits.append(atree_bitvec);
|
||||
} else {
|
||||
build_bits.append(0, 1);
|
||||
}
|
||||
|
||||
//compute length and return final build hash
|
||||
return build_version.toString() + "_" + len_string + "_" + build_string;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
js/utils.js
12
js/utils.js
|
@ -204,7 +204,7 @@ Base64 = (function () {
|
|||
|
||||
/** Returns an integer value (if possible) made from the range of bits [start, end). Undefined behavior if the range to read is too big.
|
||||
*
|
||||
* @param {Number} start - The index to start slicing from. Inclusive.
|
||||
* @param {Number} start - The index to start slicing from. Inclusive.
|
||||
* @param {Number} end - The index to end slicing at. Exclusive.
|
||||
*
|
||||
* @returns An integer representation of the sliced bits.
|
||||
|
@ -307,7 +307,7 @@ Base64 = (function () {
|
|||
|
||||
/** Appends data to the BitVector.
|
||||
*
|
||||
* @param {Number | String} data - The data to append.
|
||||
* @param {Number | String | BitVector} data - The data to append.
|
||||
* @param {Number} length - The length, in bits, of the new data. This is ignored if data is a string. Defaults to 32 for numbers.
|
||||
*/
|
||||
append(data, length = 32) {
|
||||
|
@ -318,6 +318,8 @@ Base64 = (function () {
|
|||
//actual new data length is needed for resizing purposes
|
||||
if (typeof data === "string") {
|
||||
length = data.length * 6;
|
||||
} else if (data instanceof BitVector) {
|
||||
length = data.length;
|
||||
}
|
||||
|
||||
let new_length = this.length + length;
|
||||
|
@ -369,6 +371,12 @@ Base64 = (function () {
|
|||
if (((this.length - 1) % 32 + 1) + 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
|
||||
|
||||
//fill full ints
|
||||
|
||||
//fill from "rest of" length/bv
|
||||
} else {
|
||||
throw new TypeError("BitVector must be appended with a Number or a B64 String");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue