pw-js-world
Version:
An optional package for PW-JS-Api, aims to serve world purposes.
189 lines • 14.3 kB
JavaScript
import { MAX_WORLD_BLOCK_PLACED_PACKET_POSITION_SIZE } from "../Constants.js";
import Block from "../Block.js";
// const aaa = {
// hi: 0
// };
// // setInterval(() => {
// // console.log(aaa.hi);
// // }, 1);
/**
* True if objA matches the contents to that of objB
*
* TODO: proper array support?
*/
export function compareObjs(objA, objB) {
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
// console.log(objA, objB);
if (keysA.length !== keysB.length)
return false;
for (let i = 0; i < keysA.length; i++) {
const valA = objA[keysA[i]];
const valB = objB[keysA[i]];
if (typeof valA !== typeof valB)
return false;
// in case they're both undefined...?
if (valA === valB)
continue;
if (valB === undefined)
return false;
if (typeof valA === "object" && typeof valB === "object") {
const isArray = [Array.isArray(valA), Array.isArray(valB)];
if (isArray[0] && !isArray[1])
return false;
if (!isArray[0] && isArray[1])
return false;
// TODO: proper array support?
if (isArray[0] && isArray[1]) {
if (valA.length !== valB.length)
return false;
for (let j = 0; j < valA.length; j++) {
if (valA[j] !== valB[j])
return false;
}
}
else {
if (!compareObjs(valA, valB))
return false;
}
}
else if (valA !== valB)
return false;
}
return true;
}
export function uint8ArrayEquals(a, b) {
if (a === b) {
return true;
}
if (a.byteLength !== b.byteLength) {
return false;
}
for (let i = 0; i < a.byteLength; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
export function map(arr, cb) {
const res = [];
if (!Array.isArray(arr))
arr = Array.from(arr.values());
for (let i = 0, len = arr.length; i < len; i++) {
res[i] = cb(arr[i], i, arr);
// if (pred(arr[i], i, arr)) res.push(arr[i]);
}
return res;
}
export function find(arr, pred) {
if (!Array.isArray(arr))
arr = Array.from(arr.values());
for (let i = 0, len = arr.length; i < len; i++) {
if (pred(arr[i], i, arr))
return arr[i];
}
return undefined;
}
export function findIndex(arr, pred) {
if (!Array.isArray(arr))
arr = Array.from(arr.values());
for (let i = 0, len = arr.length; i < len; i++) {
if (pred(arr[i], i, arr))
return i;
}
return -1;
}
export function createBlockPacket(blockId, layer, pos, args) {
if (blockId instanceof Block) {
args = blockId.args;
blockId = blockId.bId;
}
else if (typeof blockId !== "number") {
blockId = Block.getIdByName(blockId);
}
if (blockId === undefined)
throw Error("Unknown block ID");
if (layer === undefined || layer < 0 || layer > 2)
throw Error("Unknown layer type");
if (!Array.isArray(pos))
pos = [pos];
return {
isFillOperation: false,
blockId,
layer,
positions: pos,
fields: Block.getArgsAsFields(blockId, args)
// extraFields: Block.serializeArgs(blockId, args, { endian: "big", writeId: false, readTypeByte: true })
};
}
/**
* Creates sendable packets from given blocks. Attempts to minimise packet count, so it's preferable
* to use it over creating packets with createBlockPacket multiple times.
*/
export function createBlockPackets(blocks) {
// Exact max packet position size is unknown, but it was noticed, it works correctly with this size
const list = [];
for (let i = 0, len = blocks.length; i < len; i++) {
const block = blocks[i];
const packet = createBlockPacket(block.block, block.layer, block.pos);
let existingPacket;
for (let j = 0, jen = list.length; j < jen; j++) {
if (list[j].blockId === block.block.bId &&
list[j].layer === block.layer &&
list[j].positions.length < MAX_WORLD_BLOCK_PLACED_PACKET_POSITION_SIZE &&
compareObjs(list[j].fields, packet.fields)) {
existingPacket = list[j];
break;
}
}
if (existingPacket) {
const pos = existingPacket.positions;
for (let j = 0, jen = pos.length; j < jen; j++) {
if (block.pos.x !== pos[j].x || block.pos.y !== pos[j].y) {
existingPacket.positions.push(block.pos);
break;
}
}
}
else
list.push(packet);
}
return list;
}
/**
* Since this is literally the only function related to dealing with binary stuff, a file would be redundant.
*
* Credits: Priddle / NVD https://discord.com/channels/534079923573489667/1230093943941758977/1431632635645530234
*/
export function read7BitEncodedInt(reader, offset) {
let value = 0;
let shift = 0;
let byte;
do {
byte = reader.readUInt8(offset.val++);
value |= (byte & 0x7F) << shift;
shift += 7;
} while ((byte & 0x80) != 0);
return value;
}
/**
* I don't know what else to call this.
*
* This will convert the type from getListedBlocks#fields to match the one from the game.
*/
export function listedFieldTypeToGameType(type) {
switch (type) {
case "String": return "stringValue";
case "Int32": return "int32Value";
case "UInt32": return "uint32Value";
case "Boolean": return "boolValue";
case "DrumNote[]":
case "PianoNote[]":
case "GuitarNote[]":
return "byteArrayValue";
default:
throw Error("Unknown field type (" + type + ") - PLEASE CONTACT LIBRARY MAINTAINER (Doomester)");
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlzYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91dGlsL01pc2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFrQiwyQ0FBMkMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTlGLE9BQU8sS0FBSyxNQUFNLGFBQWEsQ0FBQztBQUloQyxnQkFBZ0I7QUFDaEIsWUFBWTtBQUNaLEtBQUs7QUFFTCx5QkFBeUI7QUFDekIsOEJBQThCO0FBQzlCLFlBQVk7QUFFWjs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBK0QsSUFBTyxFQUFFLElBQU87SUFDdEcsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWhDLDJCQUEyQjtJQUUzQixJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLE1BQU07UUFBRSxPQUFPLEtBQUssQ0FBQztJQUVoRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFNUIsSUFBSSxPQUFPLElBQUksS0FBSyxPQUFPLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUU5QyxxQ0FBcUM7UUFDckMsSUFBSSxJQUFJLEtBQUssSUFBSTtZQUFFLFNBQVM7UUFFNUIsSUFBSSxJQUFJLEtBQUssU0FBUztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRXJDLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sSUFB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