Skip to content

Commit

Permalink
Save action bars, support NBT chat parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
retrixe committed Apr 14, 2024
1 parent e56f8fc commit 174c968
Show file tree
Hide file tree
Showing 8 changed files with 388 additions and 90 deletions.
292 changes: 292 additions & 0 deletions .yarn/patches/mcnbt-npm-2.0.3-610b3f38d1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
diff --git a/lib/base_tag.js b/lib/base_tag.js
index 33d85b7cbb3d66350136df9ec624688c166983e7..2b74fc903124ff3fcdda86f82509103486d471fc 100644
--- a/lib/base_tag.js
+++ b/lib/base_tag.js
@@ -194,8 +194,8 @@ class BaseTag {
return val;
}

- if (val instanceof Long) {
- return val;
+ if (typeof val === 'bigint') {
+ return val.toString();
}

if (this.type === 'TAG_Int_Array' || this.type === 'TAG_Byte_Array') {
diff --git a/lib/bvffer.js b/lib/bvffer.js
deleted file mode 100644
index a89ee51038caed485e71afca0619d31340a362c4..0000000000000000000000000000000000000000
--- a/lib/bvffer.js
+++ /dev/null
@@ -1,104 +0,0 @@
-'use strict';
-
-const defaultPoolSize = 64 * 1024;
-if (Buffer.poolSize < defaultPoolSize) {
- Buffer.poolSize = defaultPoolSize;
-}
-
-class Bvffer {
- constructor(buffByteLength) {
- /**
- * Buffer store data
- */
- this.buffer = Buffer.allocUnsafe(buffByteLength);
- /**
- * data length in buffer
- */
- this.dataByteLength = 0;
- }
-
- get dataLength() {
- return this.dataByteLength;
- }
-
- get buff() {
- return this.buffer;
- }
-
- /**
- * write buffer data to buffer
- * @param {Buffer} value data to write
- */
- writeBuffer(value) {
- this.writeUInt16BE(value.length);
-
- value.copy(this.buffer, this.dataByteLength);
- this.dataByteLength += value.length;
- }
-
- /**
- * @param {number} value value
- */
- writeUInt8(value) {
- this.buff[this.dataByteLength] = value;
- this.dataByteLength += 1;
- }
-
- /**
- * @param {number} value value
- */
- writeInt8(value) {
- this.buff[this.dataByteLength] = value;
- this.dataByteLength += 1;
- }
-
- /**
- * @param {number} value value
- */
- writeUInt16BE(value) {
- this.buffer.writeUInt16BE(value, this.dataByteLength);
- this.dataByteLength += 2;
- }
-
- /**
- * @param {number} value value
- */
- writeInt16BE(value) {
- this.buffer.writeInt16BE(value, this.dataByteLength);
- this.dataByteLength += 2;
- }
-
- /**
- * @param {number} value value
- */
- writeUInt32BE(value) {
- this.buffer.writeUInt32BE(value, this.dataByteLength);
- this.dataByteLength += 4;
- }
-
- /**
- * @param {number} value value
- */
- writeInt32BE(value) {
- this.buffer.writeInt32BE(value, this.dataByteLength);
- this.dataByteLength += 4;
- }
-
- /**
- * @param {number} value value
- */
- writeDoubleBE(value) {
- this.buffer.writeDoubleBE(value, this.dataByteLength);
- this.dataByteLength += 8;
- }
-
- /**
- * @param {number} value value
- */
- writeFloatBE(value) {
- this.buffer.writeFloatBE(value, this.dataByteLength);
- this.dataByteLength += 4;
- }
-}
-
-exports.Bvffer = Bvffer;
diff --git a/lib/tags/long.js b/lib/tags/long.js
index f90f7ebc49778c0b8046c5dd463ca6922b714b3a..ffe5ac6d7ee7b06e55849395942c2f12c754e5bd 100644
--- a/lib/tags/long.js
+++ b/lib/tags/long.js
@@ -1,11 +1,10 @@
'use strict';

const BaseTag = require('../base_tag');
-const Long = require('long');

const LONG_BOUND = {
- MIN: Long.fromString('-9223372036854775808'),
- MAX: Long.fromString('9223372036854775807'),
+ MIN: BigInt('-9223372036854775808'),
+ MAX: BigInt('9223372036854775807'),
};

class TAGLong extends BaseTag {
@@ -15,16 +14,12 @@ class TAGLong extends BaseTag {
}

_readBodyFromBuffer(buff, offset) {
- const sliced = buff.slice(offset, offset + 8);
- this.value = Long.fromBytesBE(sliced, true);
+ this.value = buff.readBigInt64BE(offset);
return 8;
}

writeBuffer(buff) {
- const bytes = this.value.toBytesBE();
- for (let i = 0; i < 8; i++) {
- buff.writeUInt8(bytes[i]);
- }
+ buff.writeBigInt64BE(this.value);
}

toJSON() {
@@ -32,20 +27,20 @@ class TAGLong extends BaseTag {
}

setValue(value) {
- let temp = -1;
+ let temp = -1n;
if (typeof value === 'string') {
- temp = new Long(value);
- } else if (value instanceof Long) {
- temp = Long.fromString(value.toString());
+ temp = BigInt(value);
+ } else if (typeof value === 'bigint') {
+ temp = value;
} else if (typeof value === 'number' && !isNaN(value)) {
- temp = Long.fromNumber(value);
+ temp = BigInt(value);
}

- if (temp === -1) {
+ if (temp === -1n) {
throw new Error('Wrong type to set TAG_Long\'s value.');
}

- if (temp.lessThan(LONG_BOUND.MIN) || temp.greaterThan(LONG_BOUND.MAX)) {
+ if (temp < LONG_BOUND.MIN || temp > LONG_BOUND.MAX) {
throw new RangeError(
'Value of TAG_Long should between -9223372036854775808 and ' +
'9223372036854775807');
diff --git a/nbt.js b/nbt.js
index 2c21c7c4f620958a169186510c36044252f7284c..17ee42a0b27d47889b904412ea565e3a4770cd60 100644
--- a/nbt.js
+++ b/nbt.js
@@ -1,10 +1,6 @@
'use strict';

-const fs = require('fs');
-const zlib = require('zlib');
-
const Tag = require('./lib/base_tag');
-const { Bvffer } = require('./lib/bvffer');

/**
* The NBT class
@@ -18,25 +14,19 @@ class NBT {
/**
* Load from buffer
* @param {Buffer} buff The buffer to load from
- * @param {(err?: Error) => void} callback The callback to call when done
*/
- loadFromBuffer(buff, callback) {
- try {
- this._buff = buff;
- let offset = 0;
- while (offset < buff.length) {
- const wrapper = Tag.getNextTag(buff, offset);
- const tag = wrapper.tag;
- const len = wrapper.length;
-
- this.root[tag.id] = tag;
- offset += len;
- }
- } catch (e) {
- return callback(e);
- }
+ loadFromBuffer(buff) {
+ this._buff = buff;
+ let offset = 0;
+ // Removal of this allows for deserialising of network NBT
+ // while (offset < buff.length) {
+ const wrapper = Tag.getNextTag(buff, offset);
+ const tag = wrapper.tag;
+ const len = wrapper.length;

- callback();
+ this.root[tag.id] = tag;
+ offset += len;
+ // }
}

/**
@@ -73,7 +63,7 @@ class NBT {
* @return {Buffer} The buffer
*/
writeToBuffer() {
- const buff = new Bvffer(this.calcBufferLength());
+ const buff = new Buffer(this.calcBufferLength());
for (const key in this.root) {
if (!this.root.hasOwnProperty(key)) continue;

@@ -214,7 +204,7 @@ class NBT {

// child type id for 1 byte, child name length for 2 bytes and child
// name for (child name length) byte(s).
- len += 3;
+ len += key === '' ? 1 : 3; // Anonymous NBT fix
len += Buffer.byteLength(this.root[key].id, 'utf8');

// add the child body's length
diff --git a/package.json b/package.json
index 29b0d595a67f16f1cae50ae6a5ce18496a25ef47..148abdf0248a30e982a0d66753e3a39dc1666515 100644
--- a/package.json
+++ b/package.json
@@ -21,12 +21,8 @@
"url": "https://github.com/XadillaX/mcnbt/issues"
},
"homepage": "https://github.com/XadillaX/mcnbt",
- "dependencies": {
- "long": "^4.0.0"
- },
"types": "types/nbt.d.ts",
"devDependencies": {
- "@types/long": "^4.0.1",
"@types/node": "^17.0.18",
"eslint": "^8.9.0",
"eslint-config-egg": "^11.0.0",
diff --git a/types/nbt.d.ts b/types/nbt.d.ts
index 8ee6cd1454e6b9ff7583830c1e21b5375550864d..a7a5871cc8e18aa3352b3fcb7c1ea4bcacae240a 100644
--- a/types/nbt.d.ts
+++ b/types/nbt.d.ts
@@ -9,9 +9,8 @@ declare class NBT {
/**
* Load from buffer
* @param {Buffer} buff The buffer to load from
- * @param {(err?: Error) => void} callback The callback to call when done
*/
- loadFromBuffer(buff: Buffer, callback: (err?: Error) => void): void;
+ loadFromBuffer(buff: Buffer): void;
_buff: Buffer;
/**
* Load from compressed buffer
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"mcnbt": "patch:mcnbt@npm%3A2.0.3#~/.yarn/patches/mcnbt-npm-2.0.3-610b3f38d1.patch",
"react": "18.2.0",
"react-native": "0.74.0-rc.5",
"react-native-crypto": "^2.2.0",
Expand Down
25 changes: 0 additions & 25 deletions src/minecraft/chatToJsx.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from 'react'
import { type StyleProp, type TextProps, type TextStyle } from 'react-native'
// import nbt from 'prismarine-nbt'
import translationsJson from './translations.json'
import { protocolMap } from './utils'

const translations: Record<string, string> = translationsJson

Expand Down Expand Up @@ -311,27 +309,4 @@ export const ChatToJsx = (props: {
props.trim
)

export const parseChat = (
chat: string | Buffer,
version: number
): BaseChat | string => {
if (typeof chat === 'string') return parseJsonChat(chat)
if (version < protocolMap['1.20.3'])
return parseJsonChat(chat.toString('utf8'))
try {
throw new Error('NBT parsing is disabled.')
// FIXME: return nbt.simplify(nbt.parseUncompressed(chat))
} catch (e) {
return parseJsonChat(chat.toString('utf8'))
}
}

export const parseJsonChat = (chat: string): MinecraftChat => {
try {
return JSON.parse(chat)
} catch (e) {
return chat
}
}

export default parseChatToJsx
31 changes: 31 additions & 0 deletions src/minecraft/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Other crypto libraries: simple-crypto, sha256, aes-crypto and rsa-native
import { randomBytes } from 'react-native-randombytes'
import { Buffer } from 'buffer'
import NBT from 'mcnbt'
import { type MinecraftChat } from './chatToJsx'

export const protocolMap = {
'1.16.4': 754,
Expand Down Expand Up @@ -164,3 +166,32 @@ export const writeVarInt = (value: number): Buffer => {
} while (value !== 0)
return result
}

export const parseChat = (
data: string | Buffer,
version?: number
): [MinecraftChat | string, number] => {
if (typeof data === 'string') {
return [parseJsonChat(data), data.length]
} else if (!version || version < protocolMap['1.20.3']) {
const [chatLen, chatViLength] = readVarInt(data)
const chat = data.slice(chatViLength, chatViLength + chatLen)
return [parseJsonChat(chat.toString('utf8')), chatViLength + chatLen]
} else {
const nbt = new NBT()
nbt.loadFromBuffer(
data.length >= 2 && data.readInt8(0) === 0x0a // Add anonymous name because lib isn't updated
? Buffer.concat([Buffer.from([0x0a, 0x00, 0x00]), data.slice(1)])
: data
)
return [nbt.toJSON()[''], nbt.calcBufferLength()]
}
}

export const parseJsonChat = (chat: string): MinecraftChat => {
try {
return JSON.parse(chat)
} catch (e) {
return chat
}
}
Loading

0 comments on commit 174c968

Please sign in to comment.