New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@xmcl/nbt

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@xmcl/nbt - npm Package Compare versions

Comparing version 0.1.1 to 1.0.0

index.module.d.ts

206

index.d.ts

@@ -1,205 +0,3 @@

/// <reference types="node" />
import ByteBuffer from "bytebuffer";
import Long from "long";
import { Optional } from "typescript-optional";
export declare namespace NBT {
type TagType = TagTypePrimitive | typeof TagType.List | typeof TagType.Compound;
type TagTypePrimitive = typeof TagType.End | typeof TagType.Byte | typeof TagType.Short | typeof TagType.Int | typeof TagType.Long | typeof TagType.Float | typeof TagType.Double | typeof TagType.ByteArray | typeof TagType.String | typeof TagType.IntArray | typeof TagType.LongArray;
namespace TagType {
const End: 0;
const Byte: 1;
const Short: 2;
const Int: 3;
const Long: 4;
const Float: 5;
const Double: 6;
const ByteArray: 7;
const String: 8;
const List: 9;
const Compound: 10;
const IntArray: 11;
const LongArray: 12;
function name(tagType: TagType): string;
}
interface Tag<T extends TagType, V> {
readonly type: T;
readonly value: V;
}
type TagEnd = Tag<typeof TagType.End, null>;
type TagByte = Tag<typeof TagType.Byte, number>;
type TagShort = Tag<typeof TagType.Short, number>;
type TagInt = Tag<typeof TagType.Int, number>;
type TagLong = Tag<typeof TagType.Long, Long>;
type TagFloat = Tag<typeof TagType.Float, number>;
type TagDouble = Tag<typeof TagType.Double, number>;
type TagByteArray = Tag<typeof TagType.ByteArray, Uint8Array>;
type TagString = Tag<typeof TagType.String, string>;
type TagIntArray = Tag<typeof TagType.IntArray, Int32Array>;
type TagLongArray = Tag<typeof TagType.LongArray, Long[]>;
type Tags = TagPrimitive | TagCompound | TagLists;
type TagPrimitive = TagEnd | TagByte | TagShort | TagInt | TagLong | TagFloat | TagDouble | TagByteArray | TagString | TagIntArray | TagLongArray;
type TagLists = TagList<TagByte> | TagList<TagShort> | TagList<TagInt> | TagList<TagLong> | TagList<TagFloat> | TagList<TagDouble> | TagList<TagByteArray> | TagList<TagString> | TagList<TagIntArray> | TagList<TagLongArray> | TagList<TagCompound> | TagListList | TagListTag;
interface TagListList extends TagList<TagLists> {
}
interface TagListTag extends TagList<Tags> {
}
interface TagList<T extends Tags> extends Tag<typeof TagType.List, void>, Array<T> {
elementType: T["type"];
}
interface TagCompound<T = any> extends Tag<typeof TagType.Compound, {
[P in keyof T]: Tags;
}> {
get(key: string): Tags;
set(key: string, tag: Tags): boolean;
has(key: string): boolean;
setByte(key: string, value: number): this;
setShort(key: string, value: number): this;
setInt(key: string, value: number): this;
setLong(key: string, value: Long): this;
setFloat(key: string, value: number): this;
setDouble(key: string, value: number): this;
setByteArray(key: string, value: Uint8Array): this;
setString(key: string, value: string): this;
setIntArray(key: string, value: Int32Array): this;
setLongArray(key: string, value: Long[]): this;
getByte(key: string): Optional<number>;
getShort(key: string): Optional<number>;
getInt(key: string): Optional<number>;
getLong(key: string): Optional<Long>;
getFloat(key: string): Optional<number>;
getDouble(key: string): Optional<number>;
getByteArray(key: string): Optional<Uint8Array>;
getString(key: string): Optional<string>;
getIntArray(key: string): Optional<Int32Array>;
getLongArray(key: string): Optional<Long[]>;
}
function tagPrimitive(type: TagTypePrimitive, value: any): TagPrimitive;
function tagCompound<T extends {
[key: string]: Tags;
}>(v: T): TagCompound<T>;
function tagList<T extends Tags>(elementType: T["type"], items: T[]): TagList<T>;
function tagByte(value: number): TagByte;
function tagShort(value: number): TagShort;
function tagInt(value: number): TagInt;
function tagLong(value: Long): TagLong;
function tagFloat(value: number): TagFloat;
function tagDouble(value: number): TagDouble;
function tagByteArray(value: Uint8Array): TagByteArray;
function tagString(value: string): TagString;
function tagIntArray(value: Int32Array): TagIntArray;
function tagLongArray(value: Long[]): TagLongArray;
namespace Persistence {
interface TypedObject {
readonly __nbtPrototype__: CompoundSchema;
[key: string]: any;
}
type Schema = ListSchema | CompoundSchema;
interface CompoundSchema {
[key: string]: TagType | string | Schema;
}
interface ListSchema extends Array<TagType | string | Schema> {
}
type TypeIdentity = Schema | string | TagType;
export class ReadContext {
private scopeType;
private reg;
constructor(scopeType: TypeIdentity, reg: {
[name: string]: string;
});
type: TypeIdentity;
findSchemaId(schema: Schema): string | undefined;
fork(tagType: number): ReadContext;
}
export class WriteContext {
readonly type: Schema;
private reg;
constructor(type: Schema, reg: {
[id: string]: Schema;
});
findSchema(id: string): Schema | undefined;
fork(type?: Schema): WriteContext;
}
export interface IO {
read(buf: ByteBuffer, context: ReadContext): any;
write(buf: ByteBuffer, value: any, context: WriteContext): void;
}
export interface SerializationOption {
compressed?: boolean;
/**
* IO override for serialization
*/
io?: {
[tagType: number]: IO;
};
}
/**
* Serialzie an nbt typed json object into NBT binary
* @param object The json
* @param compressed Should we compress it
*/
export function serialize(object: TypedObject, option?: SerializationOption): Promise<Buffer>;
/**
* Deserialize the nbt binary into json
* @param fileData The nbt binary
* @param compressed Should we compress it
*/
export function deserialize(fileData: Buffer, option?: SerializationOption): Promise<TypedObject>;
/**
* Serialzie an nbt typed json object into NBT binary
* @param object The json
* @param compressed Should we compress it
*/
export function serializeSync(object: TypedObject, option?: SerializationOption): Buffer;
/**
* Deserialize the nbt binary into json
* @param fileData The nbt binary
* @param compressed Should we compress it
*/
export function deserializeSync(fileData: Buffer, option?: SerializationOption): TypedObject;
export function createSerializer(): Serializer;
export class Serializer {
private registry;
private reversedRegistry;
/**
* Register a new type nbt schema to the serializer
* @param type The type name
* @param schema The schema
*/
register(type: string, schema: CompoundSchema): this;
/**
* Serialize the object into the specific type
* @param object The json object
* @param type The registered nbt type
* @param option The serialize option
*/
serialize(object: object, type: string, option?: SerializationOption): Promise<Buffer>;
/**
* Serialize the object into the specific type
* @param object The json object
* @param type The registered nbt type
* @param compressed Should compress this nbt
*/
serializeSync(object: object, type: string, option?: SerializationOption): any;
/**
* Deserialize the nbt to json object directly
* @param fileData The nbt data
* @param compressed Does the data compressed
*/
deserialize(fileData: Buffer, option?: SerializationOption): Promise<{
value: any;
type: any | string;
}>;
/**
* Deserialize the nbt to json object directly
* @param fileData The nbt data
* @param compressed Does the data compressed
*/
deserializeSync(fileData: Buffer, option?: SerializationOption): {
value: any;
type: any | string;
};
}
export {};
}
}
import NBT from "./nbt";
export { NBT };
export default NBT;

@@ -1,612 +0,16 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bytebuffer_1 = __importDefault(require("bytebuffer"));
const file_type_1 = __importDefault(require("file-type"));
const long_1 = __importDefault(require("long"));
const typescript_optional_1 = require("typescript-optional");
const utils_1 = require("./utils");
var NBT;
(function (NBT) {
let TagType;
(function (TagType) {
TagType.End = 0;
TagType.Byte = 1;
TagType.Short = 2;
TagType.Int = 3;
TagType.Long = 4;
TagType.Float = 5;
TagType.Double = 6;
TagType.ByteArray = 7;
TagType.String = 8;
TagType.List = 9;
TagType.Compound = 10;
TagType.IntArray = 11;
TagType.LongArray = 12;
function name(tagType) {
return [
"End",
"Byte",
"Short",
"Int",
"Long",
"Float",
"Double",
"ByteArray",
"String",
"List",
"Compound",
"IntArray",
"LongArray",
][tagType];
}
TagType.name = name;
})(TagType = NBT.TagType || (NBT.TagType = {}));
function badTag(tag) {
if (typeof tag.type !== "number") {
return true;
}
if (!Number.isInteger(tag.type) || tag.type > 12 || tag.type < 0) {
return true;
}
const tagType = tag.type;
const value = tag.value;
switch (tagType) {
case TagType.Byte:
return typeof value !== "number" || !Number.isInteger(value) || value < -0x80 || value > 0x7F;
case TagType.Short:
return typeof value !== "number" || !Number.isInteger(value) || value < -0x8000 || value > 0x7FFF;
case TagType.Int:
return typeof value !== "number" || !Number.isInteger(value) || value < -0x80000000 || value > 0x7FFFFFFF;
case TagType.Long:
return typeof value !== "object" || !(value instanceof long_1.default) || value.unsigned;
case TagType.Float:
case TagType.Double:
return typeof value !== "number";
case TagType.ByteArray:
return typeof value !== "object" || !(value instanceof Uint8Array);
case TagType.String:
return typeof value !== "string";
case TagType.IntArray:
return typeof value !== "object" || !(value instanceof Int32Array);
case TagType.LongArray:
return typeof value !== "object" || !(value instanceof Array);
}
return true;
}
function badElementTag(v, etype) {
if (badTag(v)) {
return true;
}
if (v.type !== etype) {
return true;
}
return false;
}
class TagListImpl extends Array {
constructor(elementType, items) {
super(...items);
this.elementType = elementType;
this.type = 9;
return new Proxy(this, {
set(target, k, v) {
if (badElementTag(v, target.elementType)) {
return false;
}
return Reflect.set(target, k, v);
},
});
}
push(...items) {
if (items.some((v) => badElementTag(v, this.elementType))) {
return this.length;
}
return super.push(...items);
}
unshift(...items) {
if (items.some((v) => badElementTag(v, this.elementType))) {
return this.length;
}
return super.unshift(...items);
}
}
class TagCompoundImpl {
constructor(value) {
this.type = 10;
this.value = new Proxy(value, {
set(target, k, v) {
if (badTag(v)) {
return false;
}
Reflect.set(target, k, v);
return true;
},
});
}
getByte(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Byte)
.map((v) => v.value);
}
getShort(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Short)
.map((v) => v.value);
}
getInt(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Int)
.map((v) => v.value);
}
getLong(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Long)
.map((v) => v.value);
}
getFloat(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Float)
.map((v) => v.value);
}
getDouble(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Double)
.map((v) => v.value);
}
getByteArray(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.ByteArray)
.map((v) => v.value);
}
getString(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.String)
.map((v) => v.value);
}
getIntArray(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.IntArray)
.map((v) => v.value);
}
getLongArray(key) {
return typescript_optional_1.Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.LongArray)
.map((v) => v.value);
}
get(key) { return Reflect.get(this.value, key); }
set(key, tag) { return Reflect.set(this.value, key, tag); }
has(key) { return Reflect.has(this.value, key); }
setByte(key, value) { this.set(key, tagByte(value)); return this; }
setShort(key, value) { this.set(key, tagShort(value)); return this; }
setInt(key, value) { this.set(key, tagInt(value)); return this; }
setLong(key, value) { this.set(key, tagLong(value)); return this; }
setFloat(key, value) { this.set(key, tagFloat(value)); return this; }
setDouble(key, value) { this.set(key, tagDouble(value)); return this; }
setByteArray(key, value) { this.set(key, tagByteArray(value)); return this; }
setString(key, value) { this.set(key, tagString(value)); return this; }
setIntArray(key, value) { this.set(key, tagIntArray(value)); return this; }
setLongArray(key, value) { this.set(key, tagLongArray(value)); return this; }
}
function tagPrimitive(type, value) {
return { type, value };
}
NBT.tagPrimitive = tagPrimitive;
function tagCompound(v) { return new TagCompoundImpl(v); }
NBT.tagCompound = tagCompound;
function tagList(elementType, items) { return new TagListImpl(elementType, items); }
NBT.tagList = tagList;
function tagByte(value) { return { type: 1, value }; }
NBT.tagByte = tagByte;
function tagShort(value) { return { type: 2, value }; }
NBT.tagShort = tagShort;
function tagInt(value) { return { type: 3, value }; }
NBT.tagInt = tagInt;
function tagLong(value) { return { type: 4, value }; }
NBT.tagLong = tagLong;
function tagFloat(value) { return { type: 5, value }; }
NBT.tagFloat = tagFloat;
function tagDouble(value) { return { type: 6, value }; }
NBT.tagDouble = tagDouble;
function tagByteArray(value) { return { type: 7, value }; }
NBT.tagByteArray = tagByteArray;
function tagString(value) { return { type: 8, value }; }
NBT.tagString = tagString;
function tagIntArray(value) { return { type: 11, value }; }
NBT.tagIntArray = tagIntArray;
function tagLongArray(value) { return { type: 12, value }; }
NBT.tagLongArray = tagLongArray;
let Persistence;
(function (Persistence) {
class ReadContext {
constructor(scopeType, reg) {
this.scopeType = scopeType;
this.reg = reg;
}
set type(s) { this.scopeType = s; }
get type() { return this.scopeType; }
findSchemaId(schema) { return this.reg[JSON.stringify(schema)]; }
fork(tagType) {
if (tagType < TagType.End || tagType > TagType.LongArray) {
throw new Error(`Illegal Tag Type ${tagType}`);
}
return new ReadContext(tagType, this.reg);
}
}
Persistence.ReadContext = ReadContext;
class WriteContext {
constructor(type, reg) {
this.type = type;
this.reg = reg;
}
findSchema(id) { return this.reg[id]; }
fork(type = {}) { return new WriteContext(type, this.reg); }
}
Persistence.WriteContext = WriteContext;
const handlers = [
{ read: (buf) => undefined, write(buf, v) { } },
{ read: (buf) => buf.readByte(), write(buf, v) { buf.writeByte(v ? v : 0); } },
{ read: (buf) => buf.readShort(), write(buf, v) { buf.writeShort(v ? v : 0); } },
{ read: (buf) => buf.readInt(), write(buf, v) { buf.writeInt(v ? v : 0); } },
{ read: (buf) => buf.readInt64(), write(buf, v) { buf.writeInt64(v ? v : 0); } },
{ read: (buf) => buf.readFloat(), write(buf, v) { buf.writeFloat(v ? v : 0); } },
{ read: (buf) => buf.readDouble(), write(buf, v) { buf.writeDouble(v ? v : 0); } },
{
read(buf) {
const arr = new Array(buf.readInt());
for (let i = 0; i < arr.length; i++) {
arr[i] = buf.readByte();
}
return arr;
},
write(buf, arr = []) {
buf.writeInt(arr.length);
for (let i = 0; i < arr.length; i++) {
buf.writeByte(arr[i]);
}
},
},
{ read: (buf) => utils_1.readUTF8(buf), write: (buf, v) => utils_1.writeUTF8(buf, v ? v : "") },
{
read(buf, context) {
const listType = buf.readByte();
const len = buf.readInt();
const list = new Array(len);
const child = context.fork(listType);
for (let i = 0; i < len; i++) {
const value = handlers[listType].read(buf, child);
list[i] = value;
}
context.type = [child.type];
return list;
},
write(buf, value = [], context) {
const type = context.type[0];
switch (typeof type) {
case "number": // type enum
buf.writeByte(type);
buf.writeInt(value.length);
for (const v of value) {
handlers[type].write(buf, v, context);
}
break;
case "string": // custom registered type
const customScope = context.findSchema(type);
if (!customScope) {
throw new Error(`Unknown custom type [${type}]`);
}
buf.writeByte(customScope instanceof Array ? TagType.List : TagType.Compound);
buf.writeInt(value.length);
value.forEach((v) => handlers[TagType.Compound].write(buf, v, context.fork(customScope)));
break;
case "object": // custom type
buf.writeByte(TagType.Compound);
buf.writeInt(value.length);
value.forEach((v) => handlers[TagType.Compound].write(buf, v, context.fork(type)));
break;
default:
if (value.length !== 0) {
throw new Error(`Unknown list type [${type}].`);
}
buf.writeByte(TagType.End);
buf.writeInt(0);
}
},
},
{
read(buf, context) {
const object = {};
const scope = {};
for (let tag = 0; (tag = buf.readByte()) !== TagType.End;) {
const name = utils_1.readUTF8(buf);
const visitor = handlers[tag];
if (!visitor) {
throw new Error("No such tag id: " + tag);
}
const child = context.fork(tag);
const value = visitor.read(buf, child);
object[name] = value;
scope[name] = child.type;
}
const existedType = context.findSchemaId(scope);
context.type = existedType ? existedType : scope;
return object;
},
write(buf, object = {}, context) {
for (const [key, value] of Object.entries(object)) {
if (key === "___nbtPrototype___") {
continue;
}
const type = context.type[key];
let tagType;
let nextScope;
if (typeof type === "number") { // common enum type
tagType = type;
}
else if (type instanceof Array) { // array type
tagType = TagType.List;
nextScope = type;
}
else if (typeof type === "string") { // custom type
tagType = TagType.Compound;
nextScope = context.findSchema(type);
if (!nextScope) {
throw new Error(`Unknown custom type [${type}]`);
}
}
else if (typeof type === "object") { // tagged compund type
tagType = TagType.Compound;
nextScope = type;
}
else {
continue; // just ignore it if it's not on definition
}
const writer = handlers[tagType];
if (!writer) {
throw new Error("Unknown type " + type);
}
buf.writeByte(tagType);
utils_1.writeUTF8(buf, key);
try {
writer.write(buf, value, context.fork(nextScope));
}
catch (e) {
if (e instanceof TypeError) {
throw {
type: "IllegalInputType",
message: `Require ${TagType.name(tagType)} but found ${typeof value}`,
};
}
}
}
buf.writeByte(TagType.End);
},
},
{
read(buf) {
const arr = new Array(buf.readInt());
for (let i = 0; i < arr.length; i++) {
arr[i] = buf.readInt();
}
return arr;
},
write(buf, v = []) {
buf.writeInt(v.length);
for (let i = 0; i < v.length; i++) {
buf.writeInt(v[i]);
}
},
},
{
read(buf) {
const len = buf.readInt();
const arr = new Array(len);
for (let i = 0; i < len; i++) {
arr[i] = buf.readInt64();
}
return arr;
},
write(buf, v = []) {
buf.writeInt(v.length);
for (let i = 0; i < v.length; i++) {
buf.writeInt64(v[i]);
}
},
},
];
/**
* Serialzie an nbt typed json object into NBT binary
* @param object The json
* @param compressed Should we compress it
*/
async function serialize(object, option = {}) {
const buff = writeRootTag(object, object.__nbtPrototype__, {}, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return utils_1.zlib.gzip(buff);
}
Persistence.serialize = serialize;
/**
* Deserialize the nbt binary into json
* @param fileData The nbt binary
* @param compressed Should we compress it
*/
async function deserialize(fileData, option = {}) {
const doUnzip = shouldUnzip(fileData, option.compressed);
const bb = bytebuffer_1.default.wrap(doUnzip ? await utils_1.zlib.unzip(fileData) : fileData);
const { value, type } = readRootTag(bb, undefined, Object.assign({}, handlers, option.io));
deepFreeze(type);
Object.defineProperty(value, "__nbtPrototype__", { value: type });
return value;
}
Persistence.deserialize = deserialize;
/**
* Serialzie an nbt typed json object into NBT binary
* @param object The json
* @param compressed Should we compress it
*/
function serializeSync(object, option = {}) {
const buff = writeRootTag(object, object.__nbtPrototype__, {}, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return utils_1.zlib.gzipSync(buff);
}
Persistence.serializeSync = serializeSync;
/**
* Deserialize the nbt binary into json
* @param fileData The nbt binary
* @param compressed Should we compress it
*/
function deserializeSync(fileData, option = {}) {
const doUnzip = shouldUnzip(fileData, option.compressed);
const bb = bytebuffer_1.default.wrap(doUnzip ? utils_1.zlib.unzipSync(fileData) : fileData);
const { value, type } = readRootTag(bb, undefined, Object.assign({}, handlers, option.io));
deepFreeze(type);
Object.defineProperty(value, "__nbtPrototype__", { value: type });
return value;
}
Persistence.deserializeSync = deserializeSync;
function shouldUnzip(fileData, compressed) {
let doUnzip;
if (typeof compressed === "undefined") {
const ft = file_type_1.default(fileData);
doUnzip = ft !== undefined && ft.ext === "gz";
}
else {
doUnzip = compressed;
}
return doUnzip;
}
function readRootTag(buffer, reg = {}, io = handlers) {
const rootType = buffer.readByte();
if (rootType === TagType.End) {
throw new Error("NBTEnd");
}
if (rootType !== TagType.Compound) {
throw new Error("Root tag must be a named compound tag. " + rootType);
}
const name = utils_1.readUTF8(buffer); // I think this is the nameProperty of the file...
const context = new ReadContext(TagType.Compound, reg);
const value = io[TagType.Compound].read(buffer, context);
return { type: context.type, value, name };
}
function writeRootTag(value, type, reg, filename, io) {
const buffer = new bytebuffer_1.default();
buffer.writeByte(NBT.TagType.Compound);
utils_1.writeUTF8(buffer, filename || "");
const context = new WriteContext(type, reg);
io[NBT.TagType.Compound].write(buffer, value, context);
return buffer.flip().buffer.slice(0, buffer.limit);
}
function createSerializer() {
return new Serializer();
}
Persistence.createSerializer = createSerializer;
class Serializer {
constructor() {
this.registry = {};
this.reversedRegistry = {};
}
/**
* Register a new type nbt schema to the serializer
* @param type The type name
* @param schema The schema
*/
register(type, schema) {
if (typeof schema !== "object" || schema === null) {
throw new Error();
}
this.registry[type] = schema;
this.reversedRegistry[JSON.stringify(schema)] = type;
return this;
}
/**
* Serialize the object into the specific type
* @param object The json object
* @param type The registered nbt type
* @param option The serialize option
*/
async serialize(object, type, option = {}) {
const schema = this.registry[type];
if (!schema) {
throw new Error(`Unknown type [${schema}]`);
}
const buff = writeRootTag(object, schema, this.registry, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return utils_1.zlib.gzip(buff);
}
/**
* Serialize the object into the specific type
* @param object The json object
* @param type The registered nbt type
* @param compressed Should compress this nbt
*/
serializeSync(object, type, option = {}) {
const schema = this.registry[type];
if (!schema) {
throw new Error(`Unknown type [${schema}]`);
}
const buff = writeRootTag(object, schema, this.registry, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return utils_1.zlib.gzipSync(buff);
}
/**
* Deserialize the nbt to json object directly
* @param fileData The nbt data
* @param compressed Does the data compressed
*/
async deserialize(fileData, option = {}) {
const doUnzip = shouldUnzip(fileData, option.compressed);
let bytebuffer;
if (doUnzip) {
bytebuffer = bytebuffer_1.default.wrap(await utils_1.zlib.unzip(fileData));
}
else {
bytebuffer = bytebuffer_1.default.wrap(fileData);
}
return readRootTag(bytebuffer, this.reversedRegistry, Object.assign({}, handlers, option.io));
}
/**
* Deserialize the nbt to json object directly
* @param fileData The nbt data
* @param compressed Does the data compressed
*/
deserializeSync(fileData, option = {}) {
const doUnzip = shouldUnzip(fileData, option.compressed);
let bytebuffer;
if (doUnzip) {
bytebuffer = bytebuffer_1.default.wrap(utils_1.zlib.unzipSync(fileData));
}
else {
bytebuffer = bytebuffer_1.default.wrap(fileData);
}
return readRootTag(bytebuffer, this.reversedRegistry, Object.assign({}, handlers, option.io));
}
}
Persistence.Serializer = Serializer;
})(Persistence = NBT.Persistence || (NBT.Persistence = {}));
})(NBT = exports.NBT || (exports.NBT = {}));
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
function deepFreeze(obj) {
// Retrieve the property names defined on obj
const propNames = Object.getOwnPropertyNames(obj);
// Freeze properties before freezing self
propNames.forEach((name) => {
const prop = obj[name];
// Freeze prop if it is an object
if (typeof prop === "object" && prop !== null) {
deepFreeze(prop);
}
});
// Freeze self (no-op if already frozen)
return Object.freeze(obj);
}
exports.default = NBT;
import { deflate, deflateSync, gunzip, gunzipSync, gzip, gzipSync, inflate, inflateSync } from "zlib";
import NBT, { setZlib } from "./nbt";
import { promisify } from "util";
setZlib({
gzip: promisify(gzip),
ungzip: promisify(gunzip),
inflate: promisify(inflate),
deflate: promisify(deflate),
gzipSync,
gunzipSync,
inflateSync,
deflateSync,
});
export { NBT };
export default NBT;
//# sourceMappingURL=index.js.map

@@ -1,671 +0,18 @@

import ByteBuffer from "bytebuffer";
import fileType from "file-type";
import Long from "long";
import { Optional } from "typescript-optional";
import { readUTF8, writeUTF8, zlib } from "./utils";
import { deflate, deflateSync, gunzip, gunzipSync, gzip, gzipSync, inflate, inflateSync } from "zlib";
import NBT, { setZlib } from "./nbt";
import { promisify } from "util";
export namespace NBT {
setZlib({
gzip: promisify(gzip),
ungzip: promisify(gunzip),
inflate: promisify(inflate),
deflate: promisify(deflate),
gzipSync,
gunzipSync,
inflateSync,
deflateSync,
});
export type TagType =
TagTypePrimitive |
typeof TagType.List |
typeof TagType.Compound;
export { NBT };
export type TagTypePrimitive =
typeof TagType.End |
typeof TagType.Byte |
typeof TagType.Short |
typeof TagType.Int |
typeof TagType.Long |
typeof TagType.Float |
typeof TagType.Double |
typeof TagType.ByteArray |
typeof TagType.String |
typeof TagType.IntArray |
typeof TagType.LongArray;
export namespace TagType {
export const End = 0 as const;
export const Byte = 1 as const;
export const Short = 2 as const;
export const Int = 3 as const;
export const Long = 4 as const;
export const Float = 5 as const;
export const Double = 6 as const;
export const ByteArray = 7 as const;
export const String = 8 as const;
export const List = 9 as const;
export const Compound = 10 as const;
export const IntArray = 11 as const;
export const LongArray = 12 as const;
export function name(tagType: TagType) {
return [
"End",
"Byte",
"Short",
"Int",
"Long",
"Float",
"Double",
"ByteArray",
"String",
"List",
"Compound",
"IntArray",
"LongArray",
][tagType];
}
}
export interface Tag<T extends TagType, V> {
readonly type: T;
readonly value: V;
}
export type TagEnd = Tag<typeof TagType.End, null>;
export type TagByte = Tag<typeof TagType.Byte, number>;
export type TagShort = Tag<typeof TagType.Short, number>;
export type TagInt = Tag<typeof TagType.Int, number>;
export type TagLong = Tag<typeof TagType.Long, Long>;
export type TagFloat = Tag<typeof TagType.Float, number>;
export type TagDouble = Tag<typeof TagType.Double, number>;
export type TagByteArray = Tag<typeof TagType.ByteArray, Uint8Array>;
export type TagString = Tag<typeof TagType.String, string>;
export type TagIntArray = Tag<typeof TagType.IntArray, Int32Array>;
export type TagLongArray = Tag<typeof TagType.LongArray, Long[]>;
export type Tags =
TagPrimitive |
TagCompound |
TagLists;
export type TagPrimitive =
TagEnd |
TagByte |
TagShort |
TagInt |
TagLong |
TagFloat |
TagDouble |
TagByteArray |
TagString |
TagIntArray |
TagLongArray;
export type TagLists =
TagList<TagByte> |
TagList<TagShort> |
TagList<TagInt> |
TagList<TagLong> |
TagList<TagFloat> |
TagList<TagDouble> |
TagList<TagByteArray> |
TagList<TagString> |
TagList<TagIntArray> |
TagList<TagLongArray> |
TagList<TagCompound> |
TagListList |
TagListTag;
export interface TagListList extends TagList<TagLists> { }
export interface TagListTag extends TagList<Tags> { }
export interface TagList<T extends Tags> extends Tag<typeof TagType.List, void>, Array<T> {
elementType: T["type"];
}
export interface TagCompound<T = any> extends Tag<typeof TagType.Compound, { [P in keyof T]: Tags }> {
get(key: string): Tags;
set(key: string, tag: Tags): boolean;
has(key: string): boolean;
setByte(key: string, value: number): this;
setShort(key: string, value: number): this;
setInt(key: string, value: number): this;
setLong(key: string, value: Long): this;
setFloat(key: string, value: number): this;
setDouble(key: string, value: number): this;
setByteArray(key: string, value: Uint8Array): this;
setString(key: string, value: string): this;
setIntArray(key: string, value: Int32Array): this;
setLongArray(key: string, value: Long[]): this;
getByte(key: string): Optional<number>;
getShort(key: string): Optional<number>;
getInt(key: string): Optional<number>;
getLong(key: string): Optional<Long>;
getFloat(key: string): Optional<number>;
getDouble(key: string): Optional<number>;
getByteArray(key: string): Optional<Uint8Array>;
getString(key: string): Optional<string>;
getIntArray(key: string): Optional<Int32Array>;
getLongArray(key: string): Optional<Long[]>;
}
function badTag(tag: any): boolean {
if (typeof tag.type !== "number") { return true; }
if (!Number.isInteger(tag.type) || tag.type > 12 || tag.type < 0) { return true; }
const tagType = tag.type;
const value = tag.value;
switch (tagType) {
case TagType.Byte:
return typeof value !== "number" || !Number.isInteger(value) || value < -0x80 || value > 0x7F;
case TagType.Short:
return typeof value !== "number" || !Number.isInteger(value) || value < -0x8000 || value > 0x7FFF;
case TagType.Int:
return typeof value !== "number" || !Number.isInteger(value) || value < -0x80000000 || value > 0x7FFFFFFF;
case TagType.Long:
return typeof value !== "object" || !(value instanceof Long) || value.unsigned;
case TagType.Float:
case TagType.Double:
return typeof value !== "number";
case TagType.ByteArray:
return typeof value !== "object" || !(value instanceof Uint8Array);
case TagType.String:
return typeof value !== "string";
case TagType.IntArray:
return typeof value !== "object" || !(value instanceof Int32Array);
case TagType.LongArray:
return typeof value !== "object" || !(value instanceof Array);
}
return true;
}
function badElementTag(v: any, etype: TagType) {
if (badTag(v)) { return true; }
if (v.type !== etype) { return true; }
return false;
}
class TagListImpl<T extends Tags> extends Array<T> implements TagList<T> {
type: 9 = 9;
value: void;
constructor(readonly elementType: T["type"], items: T[]) {
super(...items);
return new Proxy(this, {
set(target, k, v) {
if (badElementTag(v, target.elementType)) { return false; }
return Reflect.set(target, k, v);
},
});
}
push(...items: T[]) {
if (items.some((v) => badElementTag(v, this.elementType))) { return this.length; }
return super.push(...items);
}
unshift(...items: T[]) {
if (items.some((v) => badElementTag(v, this.elementType))) { return this.length; }
return super.unshift(...items);
}
}
class TagCompoundImpl<T extends { [key: string]: Tags; }> implements TagCompound<T> {
type: 10 = 10;
readonly value: T;
constructor(value: T) {
this.value = new Proxy(value, {
set(target, k, v) {
if (badTag(v)) { return false; }
Reflect.set(target, k, v);
return true;
},
});
}
getByte(key: string): Optional<number> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Byte)
.map((v) => v.value as number);
}
getShort(key: string): Optional<number> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Short)
.map((v) => v.value as number);
}
getInt(key: string): Optional<number> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Int)
.map((v) => v.value as number);
}
getLong(key: string): Optional<Long> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Long)
.map((v) => v.value as Long);
}
getFloat(key: string): Optional<number> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Float)
.map((v) => v.value as number);
}
getDouble(key: string): Optional<number> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.Double)
.map((v) => v.value as number);
}
getByteArray(key: string): Optional<Uint8Array> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.ByteArray)
.map((v) => v.value as Uint8Array);
}
getString(key: string): Optional<string> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.String)
.map((v) => v.value as string);
}
getIntArray(key: string): Optional<Int32Array> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.IntArray)
.map((v) => v.value as Int32Array);
}
getLongArray(key: string): Optional<Long[]> {
return Optional.ofNullable(this.value[key])
.filter((v) => v.type === TagType.LongArray)
.map((v) => v.value as Long[]);
}
get(key: string): Tags { return Reflect.get(this.value, key); }
set(key: string, tag: Tags): boolean { return Reflect.set(this.value, key, tag); }
has(key: string): boolean { return Reflect.has(this.value, key); }
setByte(key: string, value: number): this { this.set(key, tagByte(value)); return this; }
setShort(key: string, value: number): this { this.set(key, tagShort(value)); return this; }
setInt(key: string, value: number): this { this.set(key, tagInt(value)); return this; }
setLong(key: string, value: Long): this { this.set(key, tagLong(value)); return this; }
setFloat(key: string, value: number): this { this.set(key, tagFloat(value)); return this; }
setDouble(key: string, value: number): this { this.set(key, tagDouble(value)); return this; }
setByteArray(key: string, value: Uint8Array): this { this.set(key, tagByteArray(value)); return this; }
setString(key: string, value: string): this { this.set(key, tagString(value)); return this; }
setIntArray(key: string, value: Int32Array): this { this.set(key, tagIntArray(value)); return this; }
setLongArray(key: string, value: Long[]): this { this.set(key, tagLongArray(value)); return this; }
}
export function tagPrimitive(type: TagTypePrimitive, value: any): TagPrimitive {
return { type, value } as any;
}
export function tagCompound<T extends { [key: string]: Tags; }>(v: T): TagCompound<T> { return new TagCompoundImpl<T>(v); }
export function tagList<T extends Tags>(elementType: T["type"], items: T[]): TagList<T> { return new TagListImpl<T>(elementType, items); }
export function tagByte(value: number): TagByte { return { type: 1, value }; }
export function tagShort(value: number): TagShort { return { type: 2, value }; }
export function tagInt(value: number): TagInt { return { type: 3, value }; }
export function tagLong(value: Long): TagLong { return { type: 4, value }; }
export function tagFloat(value: number): TagFloat { return { type: 5, value }; }
export function tagDouble(value: number): TagDouble { return { type: 6, value }; }
export function tagByteArray(value: Uint8Array): TagByteArray { return { type: 7, value }; }
export function tagString(value: string): TagString { return { type: 8, value }; }
export function tagIntArray(value: Int32Array): TagIntArray { return { type: 11, value }; }
export function tagLongArray(value: Long[]): TagLongArray { return { type: 12, value }; }
export namespace Persistence {
interface TypedObject {
readonly __nbtPrototype__: CompoundSchema;
[key: string]: any;
}
type Schema = ListSchema | CompoundSchema;
interface CompoundSchema { [key: string]: TagType | string | Schema; }
interface ListSchema extends Array<TagType | string | Schema> { }
type TypeIdentity = Schema | string | TagType;
export class ReadContext {
constructor(private scopeType: TypeIdentity, private reg: { [name: string]: string }) { }
set type(s: TypeIdentity) { this.scopeType = s; }
get type(): TypeIdentity { return this.scopeType; }
findSchemaId(schema: Schema): string | undefined { return this.reg[JSON.stringify(schema)]; }
fork(tagType: number): ReadContext {
if (tagType < TagType.End || tagType > TagType.LongArray) { throw new Error(`Illegal Tag Type ${tagType}`); }
return new ReadContext(tagType as TagType, this.reg);
}
}
export class WriteContext {
constructor(readonly type: Schema, private reg: { [id: string]: Schema }) { }
findSchema(id: string): Schema | undefined { return this.reg[id]; }
fork(type: Schema = {}): WriteContext { return new WriteContext(type, this.reg); }
}
export interface IO {
read(buf: ByteBuffer, context: ReadContext): any;
write(buf: ByteBuffer, value: any, context: WriteContext): void;
// readTag?(buf: ByteBuffer): Tags;
// writeTag?(buf: ByteBuffer, tags: Tags): void;
}
const handlers: IO[] = [
{ read: (buf) => undefined, write(buf, v) { } }, // end
{ read: (buf) => buf.readByte(), write(buf, v) { buf.writeByte(v ? v : 0); } }, // byte
{ read: (buf) => buf.readShort(), write(buf, v) { buf.writeShort(v ? v : 0); } }, // short
{ read: (buf) => buf.readInt(), write(buf, v) { buf.writeInt(v ? v : 0); } }, // int
{ read: (buf) => buf.readInt64(), write(buf, v) { buf.writeInt64(v ? v : 0); } }, // long
{ read: (buf) => buf.readFloat(), write(buf, v) { buf.writeFloat(v ? v : 0); } }, // float
{ read: (buf) => buf.readDouble(), write(buf, v) { buf.writeDouble(v ? v : 0); } }, // double
{ // byte array
read(buf) {
const arr = new Array(buf.readInt());
for (let i = 0; i < arr.length; i++) { arr[i] = buf.readByte(); }
return arr;
},
write(buf, arr = []) {
buf.writeInt(arr.length);
for (let i = 0; i < arr.length; i++) { buf.writeByte(arr[i]); }
},
},
{ read: (buf) => readUTF8(buf), write: (buf, v) => writeUTF8(buf, v ? v : "") }, // string
{ // list
read(buf, context) {
const listType = buf.readByte();
const len = buf.readInt();
const list = new Array(len);
const child = context.fork(listType);
for (let i = 0; i < len; i++) {
const value = handlers[listType].read(buf, child);
list[i] = value;
}
context.type = [child.type];
return list;
},
write(buf, value: any[] = [], context) {
const type = (context.type as ListSchema)[0];
switch (typeof type) {
case "number": // type enum
buf.writeByte(type);
buf.writeInt(value.length);
for (const v of value) { handlers[type as number].write(buf, v, context); }
break;
case "string": // custom registered type
const customScope = context.findSchema(type);
if (!customScope) { throw new Error(`Unknown custom type [${type}]`); }
buf.writeByte(customScope instanceof Array ? TagType.List : TagType.Compound);
buf.writeInt(value.length);
value.forEach((v) => handlers[TagType.Compound].write(buf, v, context.fork(customScope)));
break;
case "object": // custom type
buf.writeByte(TagType.Compound);
buf.writeInt(value.length);
value.forEach((v) => handlers[TagType.Compound].write(buf, v, context.fork(type)));
break;
default:
if (value.length !== 0) { throw new Error(`Unknown list type [${type}].`); }
buf.writeByte(TagType.End);
buf.writeInt(0);
}
},
},
{// tag compound
read(buf, context) {
const object: any = {};
const scope: CompoundSchema = {};
for (let tag = 0; (tag = buf.readByte()) !== TagType.End;) {
const name = readUTF8(buf);
const visitor = handlers[tag];
if (!visitor) { throw new Error("No such tag id: " + tag); }
const child = context.fork(tag);
const value = visitor.read(buf, child);
object[name] = value;
scope[name] = child.type;
}
const existedType = context.findSchemaId(scope);
context.type = existedType ? existedType : scope;
return object;
},
write(buf, object = {}, context) {
for (const [key, value] of Object.entries(object)) {
if (key === "___nbtPrototype___") { continue; }
const type = (context.type as CompoundSchema)[key];
let tagType: TagType;
let nextScope: Schema | undefined;
if (typeof type === "number") { // common enum type
tagType = type;
} else if (type instanceof Array) { // array type
tagType = TagType.List;
nextScope = type;
} else if (typeof type === "string") { // custom type
tagType = TagType.Compound;
nextScope = context.findSchema(type);
if (!nextScope) { throw new Error(`Unknown custom type [${type}]`); }
} else if (typeof type === "object") { // tagged compund type
tagType = TagType.Compound;
nextScope = type;
} else {
continue; // just ignore it if it's not on definition
}
const writer = handlers[tagType];
if (!writer) { throw new Error("Unknown type " + type); }
buf.writeByte(tagType);
writeUTF8(buf, key);
try {
writer.write(buf, value, context.fork(nextScope));
} catch (e) {
if (e instanceof TypeError) {
throw {
type: "IllegalInputType",
message: `Require ${TagType.name(tagType)} but found ${typeof value}`,
};
}
}
}
buf.writeByte(TagType.End);
},
},
{ // int array
read(buf) {
const arr = new Array(buf.readInt());
for (let i = 0; i < arr.length; i++) { arr[i] = buf.readInt(); }
return arr;
},
write(buf, v = []) {
buf.writeInt(v.length);
for (let i = 0; i < v.length; i++) { buf.writeInt(v[i]); }
},
},
{ // long array
read(buf) {
const len = buf.readInt();
const arr: Long[] = new Array(len);
for (let i = 0; i < len; i++) { arr[i] = buf.readInt64(); }
return arr;
},
write(buf, v = []) {
buf.writeInt(v.length);
for (let i = 0; i < v.length; i++) { buf.writeInt64(v[i]); }
},
},
];
export interface SerializationOption {
compressed?: boolean;
/**
* IO override for serialization
*/
io?: { [tagType: number]: IO };
}
/**
* Serialzie an nbt typed json object into NBT binary
* @param object The json
* @param compressed Should we compress it
*/
export async function serialize(object: TypedObject, option: SerializationOption = {}): Promise<Buffer> {
const buff = writeRootTag(object, object.__nbtPrototype__, {}, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return zlib.gzip(buff) as any;
}
/**
* Deserialize the nbt binary into json
* @param fileData The nbt binary
* @param compressed Should we compress it
*/
export async function deserialize(fileData: Buffer, option: SerializationOption = {}): Promise<TypedObject> {
const doUnzip: boolean = shouldUnzip(fileData, option.compressed);
const bb = ByteBuffer.wrap(doUnzip ? await zlib.unzip(fileData) : fileData);
const { value, type } = readRootTag(bb, undefined, Object.assign({}, handlers, option.io));
deepFreeze(type);
Object.defineProperty(value, "__nbtPrototype__", { value: type });
return value;
}
/**
* Serialzie an nbt typed json object into NBT binary
* @param object The json
* @param compressed Should we compress it
*/
export function serializeSync(object: TypedObject, option: SerializationOption = {}): Buffer {
const buff = writeRootTag(object, object.__nbtPrototype__, {}, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return zlib.gzipSync(buff);
}
/**
* Deserialize the nbt binary into json
* @param fileData The nbt binary
* @param compressed Should we compress it
*/
export function deserializeSync(fileData: Buffer, option: SerializationOption = {}): TypedObject {
const doUnzip: boolean = shouldUnzip(fileData, option.compressed);
const bb = ByteBuffer.wrap(doUnzip ? zlib.unzipSync(fileData) : fileData);
const { value, type } = readRootTag(bb, undefined, Object.assign({}, handlers, option.io));
deepFreeze(type);
Object.defineProperty(value, "__nbtPrototype__", { value: type });
return value;
}
function shouldUnzip(fileData: Buffer, compressed?: boolean) {
let doUnzip: boolean;
if (typeof compressed === "undefined") {
const ft = fileType(fileData);
doUnzip = ft !== undefined && ft.ext === "gz";
} else {
doUnzip = compressed;
}
return doUnzip;
}
function readRootTag(buffer: ByteBuffer, reg: { [id: string]: string } = {}, io: IO[] = handlers) {
const rootType = buffer.readByte();
if (rootType === TagType.End) { throw new Error("NBTEnd"); }
if (rootType !== TagType.Compound) { throw new Error("Root tag must be a named compound tag. " + rootType); }
const name = readUTF8(buffer); // I think this is the nameProperty of the file...
const context = new ReadContext(TagType.Compound, reg);
const value = io[TagType.Compound].read(buffer, context);
return { type: context.type, value, name };
}
function writeRootTag(value: any, type: Schema, reg: { [id: string]: Schema }, filename: string, io: IO[]): Buffer {
const buffer = new ByteBuffer();
buffer.writeByte(NBT.TagType.Compound);
writeUTF8(buffer, filename || "");
const context = new WriteContext(type, reg);
io[NBT.TagType.Compound].write(buffer, value, context);
return buffer.flip().buffer.slice(0, buffer.limit);
}
export function createSerializer() {
return new Serializer();
}
export class Serializer {
private registry: { [id: string]: CompoundSchema } = {};
private reversedRegistry: { [shape: string]: string } = {};
/**
* Register a new type nbt schema to the serializer
* @param type The type name
* @param schema The schema
*/
register(type: string, schema: CompoundSchema): this {
if (typeof schema !== "object" || schema === null) { throw new Error(); }
this.registry[type] = schema;
this.reversedRegistry[JSON.stringify(schema)] = type;
return this;
}
/**
* Serialize the object into the specific type
* @param object The json object
* @param type The registered nbt type
* @param option The serialize option
*/
async serialize(object: object, type: string, option: SerializationOption = {}) {
const schema = this.registry[type];
if (!schema) { throw new Error(`Unknown type [${schema}]`); }
const buff = writeRootTag(object, schema, this.registry, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return zlib.gzip(buff) as Promise<Buffer>;
}
/**
* Serialize the object into the specific type
* @param object The json object
* @param type The registered nbt type
* @param compressed Should compress this nbt
*/
serializeSync(object: object, type: string, option: SerializationOption = {}) {
const schema = this.registry[type];
if (!schema) { throw new Error(`Unknown type [${schema}]`); }
const buff = writeRootTag(object, schema, this.registry, "", Object.assign({}, handlers, option.io));
if (!option.compressed) {
return buff;
}
return zlib.gzipSync(buff);
}
/**
* Deserialize the nbt to json object directly
* @param fileData The nbt data
* @param compressed Does the data compressed
*/
async deserialize(fileData: Buffer, option: SerializationOption = {}): Promise<{ value: any, type: any | string }> {
const doUnzip: boolean = shouldUnzip(fileData, option.compressed);
let bytebuffer: ByteBuffer;
if (doUnzip) {
bytebuffer = ByteBuffer.wrap(await zlib.unzip(fileData));
} else {
bytebuffer = ByteBuffer.wrap(fileData);
}
return readRootTag(bytebuffer, this.reversedRegistry, Object.assign({}, handlers, option.io));
}
/**
* Deserialize the nbt to json object directly
* @param fileData The nbt data
* @param compressed Does the data compressed
*/
deserializeSync(fileData: Buffer, option: SerializationOption = {}): { value: any, type: any | string } {
const doUnzip: boolean = shouldUnzip(fileData, option.compressed);
let bytebuffer: ByteBuffer;
if (doUnzip) {
bytebuffer = ByteBuffer.wrap(zlib.unzipSync(fileData));
} else {
bytebuffer = ByteBuffer.wrap(fileData);
}
return readRootTag(bytebuffer, this.reversedRegistry, Object.assign({}, handlers, option.io));
}
}
}
}
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
function deepFreeze(obj: any) {
// Retrieve the property names defined on obj
const propNames = Object.getOwnPropertyNames(obj);
// Freeze properties before freezing self
propNames.forEach((name) => {
const prop = obj[name];
// Freeze prop if it is an object
if (typeof prop === "object" && prop !== null) {
deepFreeze(prop);
}
});
// Freeze self (no-op if already frozen)
return Object.freeze(obj);
}
export default NBT;
{
"name": "@xmcl/nbt",
"version": "0.1.1",
"version": "1.0.0",
"main": "./index.js",
"module": "./index.module.js",
"description": "NBT serialization and deserialization",

@@ -42,3 +43,3 @@ "engines": {

"homepage": "https://github.com/Voxelum/minecraft-launcher-core-node#readme",
"gitHead": "b1b29753ab0261fb9e6ca9058df3c9a6868b27b5"
"gitHead": "7babb4628dd072c266a30697d9104aef38215403"
}

@@ -18,10 +18,12 @@ # Nbt Module

const fileData: Buffer;
const compressed: boolean;
const readed: NBT.Persistence.TypedObject = await NBT.Persistence.deserialize(fileData, { compressed });
// compressed = undefined will not perform compress algorithm
// compressed = true will use gzip algorithm
const compressed: true | "gzip" | "deflate" | undefined;
const readed: NBT.TypedObject = await NBT.deserialize(fileData, { compressed });
// NBT.Persistence.TypedObject is just a object with __nbtPrototype__ defining its nbt type
// After you do the modification on it, you can serialize it back to NBT
const buf: Buffer = await NBT.Persistence.serialize(readed, { compressed });
const buf: Buffer = await NBT.serialize(readed, { compressed });
// or use serializer style
const serial = NBT.Persistence.createSerializer()
const serial = NBT.createSerializer()
.register("server", {

@@ -28,0 +30,0 @@ name: NBT.TagType.String,

{
"files": [
"index.ts",
"index.module.ts",
"nbt.ts",
"utils.ts"

@@ -5,0 +7,0 @@ ],

@@ -1,13 +0,3 @@

/// <reference types="node" />
/// <reference types="bytebuffer" />
export declare type ZippingData = Uint8Array | number[] | string | Buffer;
export declare let zlib: ZLib<any>;
export declare function setZlib<BUF>(lib: ZLib<BUF>): void;
export interface ZLib<BUF> {
gzip(buffer: BUF): Promise<BUF>;
gzipSync(buffer: BUF): BUF;
unzip(buffer: BUF): Promise<BUF>;
unzipSync(buffer: BUF): BUF;
}
export declare function writeUTF8(out: ByteBuffer, str: string): number;
export declare function readUTF8(buff: ByteBuffer): string;

@@ -1,43 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function setZlib(lib) { exports.zlib = lib; }
exports.setZlib = setZlib;
try {
// tslint:disable-next-line: no-var-requires
const lib = require("zlib");
setZlib({
gzip(buf) {
return new Promise((resolve, reject) => {
lib.gzip(buf, (e, r) => {
if (e) {
reject(e);
}
else {
resolve(r);
}
});
});
},
unzip(buff) {
return new Promise((resolve, reject) => {
lib.gunzip(buff, (err, r) => {
if (err) {
reject(err);
}
else {
resolve(r);
}
});
});
},
gzipSync(buff) { return lib.gzipSync(buff); },
unzipSync(buff) { return lib.unzipSync(buff); },
});
}
catch (e) {
console.error(e);
// tslint:disable-next-line: no-var-requires
require("pako");
}
function writeUTF8(out, str) {
export function writeUTF8(out, str) {
const strlen = str.length;

@@ -93,4 +52,3 @@ let utflen = 0;

}
exports.writeUTF8 = writeUTF8;
function readUTF8(buff) {
export function readUTF8(buff) {
const utflen = buff.readUint16();

@@ -165,3 +123,2 @@ const bytearr = new Array(utflen);

}
exports.readUTF8 = readUTF8;
//# sourceMappingURL=utils.js.map

@@ -1,42 +0,1 @@

export type ZippingData = Uint8Array | number[] | string | Buffer;
export let zlib: ZLib<any>;
export function setZlib<BUF>(lib: ZLib<BUF>) { zlib = lib; }
export interface ZLib<BUF> {
gzip(buffer: BUF): Promise<BUF>;
gzipSync(buffer: BUF): BUF;
unzip(buffer: BUF): Promise<BUF>;
unzipSync(buffer: BUF): BUF;
}
try {
// tslint:disable-next-line: no-var-requires
const lib: typeof import("zlib") = require("zlib");
setZlib({
gzip(buf) {
return new Promise((resolve, reject) => {
lib.gzip(buf, (e, r) => {
if (e) { reject(e); } else { resolve(r); }
});
});
},
unzip(buff) {
return new Promise((resolve, reject) => {
lib.gunzip(buff, (err, r) => {
if (err) { reject(err); } else { resolve(r); }
});
});
},
gzipSync(buff) { return lib.gzipSync(buff); },
unzipSync(buff) { return lib.unzipSync(buff); },
} as ZLib<Buffer>);
} catch (e) {
console.error(e);
// tslint:disable-next-line: no-var-requires
require("pako");
}
export function writeUTF8(out: ByteBuffer, str: string) {

@@ -43,0 +2,0 @@ const strlen = str.length;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc