Skip to content

Commit bcfc732

Browse files
committed
update snbt. add notebook for a rough test case
1 parent 1d6349e commit bcfc732

File tree

3 files changed

+96860
-177
lines changed

3 files changed

+96860
-177
lines changed

src/util/SNBT.ts

Lines changed: 106 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,21 @@ export class SNBTTag {
242242
case SNBTTagType.FLOAT:
243243
return this.value.toString() + (exclude_type ? '' : 'f')
244244
case SNBTTagType.DOUBLE:
245-
return this.value.toString()
246-
case SNBTTagType.BYTE_ARRAY:
247-
return '[' + this.value.join(',') + ']'
245+
return this.value.toString() + Number.isInteger(this.value)
246+
? '.0'
247+
: ''
248248
case SNBTTagType.STRING:
249249
return SNBTUtil.stringify(this.value)
250+
251+
case SNBTTagType.LONG_ARRAY:
252+
case SNBTTagType.BYTE_ARRAY:
250253
case SNBTTagType.LIST:
251254
return '[' + this.value.join(',') + ']'
252255
case SNBTTagType.COMPOUND:
253256
return (
254257
'{' +
255258
Object.entries(this.value as Record<any, SNBTTag>)
256-
.map(([key, value]) => `${key}:${value}`)
259+
.map(([key, value]) => `${key}:${value.toString()}`)
257260
.join(',') +
258261
'}'
259262
)
@@ -267,8 +270,71 @@ export class SNBTTag {
267270
.join(',') +
268271
']'
269272
)
270-
case SNBTTagType.LONG_ARRAY:
271-
return '[' + this.value.join(',') + ']'
273+
case SNBTTagType.BOOLEAN:
274+
return this.value ? 'true' : 'false'
275+
}
276+
}
277+
toPrettyString(exclude_type?: true) {
278+
switch (this.type) {
279+
case SNBTTagType.END:
280+
throw new Error('Cannot convert END tag to string')
281+
case SNBTTagType.BYTE:
282+
return this.value.toString() + (exclude_type ? '' : 'b')
283+
case SNBTTagType.SHORT:
284+
return this.value.toString() + (exclude_type ? '' : 's')
285+
case SNBTTagType.INT:
286+
return this.value.toString()
287+
case SNBTTagType.LONG:
288+
return this.value.toString()
289+
case SNBTTagType.FLOAT:
290+
return this.value.toString()
291+
case SNBTTagType.DOUBLE:
292+
return this.value.toString() + Number.isInteger(this.value)
293+
? '.0'
294+
: ''
295+
case SNBTTagType.STRING:
296+
return SNBTUtil.stringify(this.value)
297+
case SNBTTagType.COMPOUND:
298+
return (
299+
'{\n' +
300+
Object.entries(this.value as Record<any, SNBTTag>)
301+
.map(([key, value]) =>
302+
`${key}:${value.toPrettyString()}`
303+
.split('\n')
304+
.map((_) => ` ${_}`)
305+
.join('\n')
306+
)
307+
.join(',\n') +
308+
'\n}'
309+
)
310+
case SNBTTagType.INT_ARRAY: {
311+
let items = this.value.map((item) => item.toPrettyString())
312+
let combined = items.join(',')
313+
let isIndented = items.indexOf('\n') > -1
314+
if (combined.length > 16) isIndented = true
315+
if (isIndented) {
316+
return `[I;\n${items.map((_) => ` ${_}`).join(',\n')}\n]`
317+
}
318+
return '[I;' + combined + ']'
319+
}
320+
case SNBTTagType.BYTE_ARRAY:
321+
case SNBTTagType.LIST:
322+
case SNBTTagType.LONG_ARRAY: {
323+
let items = this.value.map((item) => item.toPrettyString())
324+
let combined = items.join(', ')
325+
let isIndented = combined.indexOf('\n') > -1
326+
if (combined.length > 16) isIndented = true
327+
if (isIndented) {
328+
return `[\n${items
329+
.map((_) =>
330+
_.split('\n')
331+
.map((i) => ` ${i}`)
332+
.join('\n')
333+
)
334+
.join(',\n')}\n]`
335+
}
336+
return '[' + combined + ']'
337+
}
272338
case SNBTTagType.BOOLEAN:
273339
return this.value ? 'true' : 'false'
274340
}
@@ -599,7 +665,10 @@ class SNBTParser {
599665
let dict: Record<string, SNBTTag> = {}
600666
while (!reader.isEnd()) {
601667
if (reader.hasCharInRest(':')) {
602-
const name = reader.readUntil(':')
668+
let name = reader.readUntil(':')
669+
if (name.startsWith('"') && name.endsWith('"')) {
670+
name = name.substring(1, name.length - 1)
671+
}
603672
const value = new SNBTParser(
604673
reader.readUntilNextLogicalBreakOrEnd()
605674
).parse()
@@ -612,41 +681,35 @@ class SNBTParser {
612681
}
613682
return SNBT.Compound(dict)
614683
}
615-
parseByteArray(): any {
616-
this.reader.skip(3)
684+
parseTypedArray(readerFn: (value: string) => any) {
617685
const contents = this.reader.readUntilMatchingBracket('[', ']')
618-
const reader = new StringReader(contents)
686+
const reader = new StringReader(
687+
contents.substring(3, contents.length - 1)
688+
)
619689
const result = []
620-
while (reader.hasCharInRest('b') && reader.remaining() > 0) {
621-
result.push(parseInt(reader.readUntil('b')))
622-
if (reader.peek(1) === ',') {
623-
reader.skip(1)
624-
}
690+
while (reader.hasCharInRest(',') && reader.remaining() > 0) {
691+
result.push(readerFn(reader.readUntil(',')))
625692
}
626-
return SNBT.Byte_Array(result)
693+
if (reader.remaining() > 0)
694+
result.push(readerFn(reader.read(reader.remaining())))
695+
return result
696+
}
697+
parseByteArray(): any {
698+
return SNBT.Byte_Array(
699+
this.parseTypedArray((v) =>
700+
parseInt(v.endsWith('b') ? v.substring(0, v.length - 1) : v)
701+
)
702+
)
627703
}
628704
parseIntArray(): any {
629-
this.reader.skip(3)
630-
const contents = this.reader.readUntilMatchingBracket('[', ']')
631-
const reader = new StringReader(contents)
632-
const result = []
633-
while (reader.hasCharInRest(',') && reader.remaining() > 0) {
634-
result.push(parseInt(reader.readUntil(',')))
635-
}
636-
return SNBT.Int_Array(result)
705+
return SNBT.Int_Array(this.parseTypedArray(parseInt))
637706
}
638707
parseLongArray(): any {
639-
this.reader.skip(3)
640-
const contents = this.reader.readUntilMatchingBracket('[', ']')
641-
const reader = new StringReader(contents)
642-
const result = []
643-
while (reader.hasCharInRest('l') && reader.remaining() > 0) {
644-
result.push(parseInt(reader.readUntil('l')))
645-
if (reader.peek(1) === ',') {
646-
reader.skip(1)
647-
}
648-
}
649-
return SNBT.Long_Array(result)
708+
return SNBT.Long_Array(
709+
this.parseTypedArray((v) =>
710+
parseInt(v.endsWith('l') ? v.substring(0, v.length - 1) : v)
711+
)
712+
)
650713
}
651714
parseList(): any {
652715
let contents = this.reader
@@ -708,33 +771,33 @@ class SNBTParser {
708771
parseNumber(): any {
709772
let int = this.reader.readNumber()
710773
let dec
711-
if (this.reader.peek(1) === '.') {
774+
if (this.reader.peek(1).toLowerCase() === '.') {
712775
this.reader.skip(1)
713776
dec = this.reader.readNumber()
714777
}
715-
if (this.reader.peek(1) === 'f') {
778+
if (this.reader.peek(1).toLowerCase() === 'f') {
716779
this.reader.skip(1)
717780
return SNBT.Float(parseFloat(int + '.' + dec))
718781
}
719-
if (this.reader.peek(1) === 'd') {
782+
if (this.reader.peek(1).toLowerCase() === 'd') {
720783
this.reader.skip(1)
721784
return SNBT.Double(parseFloat(int + '.' + dec))
722785
}
723-
if (this.reader.peek(1) === 'l') {
786+
if (this.reader.peek(1).toLowerCase() === 'l') {
724787
this.reader.skip(1)
725788
return SNBT.Long(parseInt(int + '.' + dec))
726789
}
727-
if (this.reader.peek(1) === 's') {
790+
if (this.reader.peek(1).toLowerCase() === 's') {
728791
this.reader.skip(1)
729792
return SNBT.Short(parseInt(int + '.' + dec))
730793
}
731-
if (this.reader.peek(1) === 'b') {
794+
if (this.reader.peek(1).toLowerCase() === 'b') {
732795
this.reader.skip(1)
733796
return SNBT.Byte(parseInt(int + '.' + dec))
734797
}
735-
if (this.reader.peek(1) === 'i') {
798+
if (this.reader.peek(1).toLowerCase() === 'i') {
736799
this.reader.skip(1)
737-
return SNBT.Int(parseInt(int + '.' + dec))
800+
return SNBT.Int(parseInt(int))
738801
}
739802
if (!dec) {
740803
return SNBT.Int(parseInt(int))
@@ -867,4 +930,3 @@ export const SNBT = {
867930
return workingCopy
868931
},
869932
}
870-
globalThis.SNBT = SNBT

src/util/SNBT2.ts

Lines changed: 0 additions & 133 deletions
This file was deleted.

0 commit comments

Comments
 (0)