pw-js-world
Version:
An optional package for PW-JS-Api, aims to serve world purposes.
201 lines • 14.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.compareObjs = compareObjs;
exports.uint8ArrayEquals = uint8ArrayEquals;
exports.map = map;
exports.find = find;
exports.findIndex = findIndex;
exports.createBlockPacket = createBlockPacket;
exports.createBlockPackets = createBlockPackets;
exports.read7BitEncodedInt = read7BitEncodedInt;
exports.listedFieldTypeToGameType = listedFieldTypeToGameType;
const tslib_1 = require("tslib");
const Constants_js_1 = require("../Constants.js");
const Block_js_1 = tslib_1.__importDefault(require("../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?
*/
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;
}
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;
}
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;
}
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;
}
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;
}
function createBlockPacket(blockId, layer, pos, args) {
if (blockId instanceof Block_js_1.default) {
args = blockId.args;
blockId = blockId.bId;
}
else if (typeof blockId !== "number") {
blockId = Block_js_1.default.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_js_1.default.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.
*/
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 < Constants_js_1.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
*/
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.
*/
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlzYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi91dGlsL01pc2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFtQkEsa0NBdUNDO0FBRUQsNENBZ0JDO0FBRUQsa0JBV0M7QUFFRCxvQkFPQztBQUVELDhCQU9DO0FBT0QsOENBc0JDO0FBTUQsZ0RBbUNDO0FBT0QsZ0RBV0M7QUFPRCw4REFlQzs7QUF6TkQsa0RBQThGO0FBRTlGLG1FQUFnQztBQUloQyxnQkFBZ0I7QUFDaEIsWUFBWTtBQUNaLEtBQUs7QUFFTCx5QkFBeUI7QUFDekIsOEJBQThCO0FBQzlCLFlBQVk7QUFFWjs7OztHQUlHO0FBQ0gsU0FBZ0IsV0FBVyxDQUErRCxJQUFPLEVBQUUsSUFBTztJQUN0RyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFaEMsMkJBQTJCO0lBRTNCLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBRWhELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDcEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU1QixJQUFJLE9BQU8sSUFBSSxLQUFLLE9BQU8sSUFBSTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBRTlDLHFDQUFxQztRQUNyQyxJQUFJLElBQUksS0FBSyxJQUFJO1lBQUUsU0FBUztRQUU1QixJQUFJLElBQUksS0FBSyxTQUFTO1lBQUUsT0FBTyxL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