152 lines
4.9 KiB
JavaScript
152 lines
4.9 KiB
JavaScript
const nbt = require('prismarine-nbt')
|
|
|
|
module.exports = registry => {
|
|
if (registry.version.type === 'pc') {
|
|
const ChatMessage = require('prismarine-chat')(registry.version.majorVersion)
|
|
|
|
function signValueToJSONArray (text) {
|
|
const texts = []
|
|
if (typeof text === 'string') {
|
|
// Sign line should look like JSON string of `{"text: "actualText"}`. Since we have plaintext, need to add in this JSON wrapper.
|
|
texts.push(...text.split('\n').map((t) => (JSON.stringify({ text: t }))))
|
|
} else if (Array.isArray(text)) {
|
|
for (const t of text) {
|
|
if (t.toJSON) { // prismarine-chat
|
|
texts.push(JSON.stringify(t.toJSON()))
|
|
} else if (typeof t === 'object') { // normal JS object
|
|
texts.push(JSON.stringify(t))
|
|
} else { // plaintext
|
|
texts.push(JSON.stringify({ text: t }))
|
|
}
|
|
}
|
|
}
|
|
return texts
|
|
}
|
|
|
|
function mergeNbt (obj1, obj2) {
|
|
for (const [key, value] of Object.entries(obj2)) {
|
|
if (!(key in obj1)) {
|
|
obj1[key] = value
|
|
continue
|
|
}
|
|
|
|
if (typeof value === 'object' && !Array.isArray(value)) mergeNbt(obj1[key], obj2[key])
|
|
}
|
|
}
|
|
|
|
function setSignTextForMultiSideSign (block, side, text) {
|
|
const texts = signValueToJSONArray(text)
|
|
|
|
if (!block.entity) {
|
|
block.entity = nbt.comp({
|
|
id: nbt.string(registry.version['>=']('1.11') ? 'minecraft:sign' : 'Sign')
|
|
})
|
|
}
|
|
|
|
mergeNbt(block.entity, nbt.comp({
|
|
isWaxed: nbt.byte(0),
|
|
back_text: nbt.comp({
|
|
has_glowing_text: nbt.byte(0),
|
|
color: nbt.string('black'),
|
|
messages: nbt.list(nbt.string(['{"text":""}']))
|
|
}),
|
|
front_text: nbt.comp({
|
|
has_glowing_text: nbt.byte(0),
|
|
color: nbt.string('black'),
|
|
messages: nbt.list(nbt.string(['{"text":""}']))
|
|
})
|
|
}))
|
|
|
|
block.entity.value[side].value.messages.value.value = texts
|
|
}
|
|
|
|
function getSignTextForMultiSideSign (block, side) {
|
|
if (!block.entity) return ''
|
|
return block.entity?.value?.[side]?.value?.messages?.value?.value?.map(text => typeof JSON.parse(text) === 'string' ? JSON.parse(text) : new ChatMessage(JSON.parse(text)).toString()).join('\n') ?? ''
|
|
}
|
|
|
|
function setSignTextForLegacySign (block, text) {
|
|
const texts = signValueToJSONArray(text)
|
|
|
|
if (!block.entity) {
|
|
block.entity = nbt.comp({
|
|
id: nbt.string(registry.version['>=']('1.11') ? 'minecraft:sign' : 'Sign')
|
|
})
|
|
}
|
|
|
|
Object.assign(block.entity.value, {
|
|
Text1: nbt.string(texts[0] || '""'),
|
|
Text2: nbt.string(texts[1] || '""'),
|
|
Text3: nbt.string(texts[2] || '""'),
|
|
Text4: nbt.string(texts[3] || '""')
|
|
})
|
|
}
|
|
|
|
function getSignTextForLegacySign (block) {
|
|
if (!block.entity) return ''
|
|
const texts = [block.entity.value.Text1.value, block.entity.value.Text2.value, block.entity.value.Text3.value, block.entity.value.Text4.value].map(val => val || '"')
|
|
return texts.map(text => typeof JSON.parse(text) === 'string' ? JSON.parse(text) : new ChatMessage(JSON.parse(text)).toString()).join('\n').trimEnd()
|
|
}
|
|
|
|
return {
|
|
sign: {
|
|
setSignText (front, back) {
|
|
if (registry.supportFeature('multiSidedSigns')) {
|
|
if (front !== undefined) setSignTextForMultiSideSign(this, 'front_text', front)
|
|
if (back !== undefined) setSignTextForMultiSideSign(this, 'back_text', back)
|
|
} else {
|
|
if (front !== undefined) setSignTextForLegacySign(this, front)
|
|
if (back !== undefined) throw new Error(`Cannot set the back text of a sign on a version before 1.20 : ${registry.version.minecraftVersion}`)
|
|
}
|
|
},
|
|
|
|
getSignText () {
|
|
if (registry.supportFeature('multiSidedSigns')) {
|
|
return [getSignTextForMultiSideSign(this, 'front_text'), getSignTextForMultiSideSign(this, 'back_text')]
|
|
} else {
|
|
return [getSignTextForLegacySign(this)]
|
|
}
|
|
},
|
|
|
|
// Deprecated APIs kept for backwards compatibility
|
|
get signText () {
|
|
return this.getSignText()[0]
|
|
},
|
|
set signText (text) {
|
|
this.setSignText(text)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (registry.version.type === 'bedrock') {
|
|
return {
|
|
sign: {
|
|
getSignText () {
|
|
if (!this.entity) return ['']
|
|
return [this.entity.Text.value]
|
|
},
|
|
setSignText (text) {
|
|
if (!this.entity) {
|
|
this.entity = nbt.comp({
|
|
id: nbt.string('Sign')
|
|
})
|
|
}
|
|
|
|
Object.assign(this.entity.value, {
|
|
Text: nbt.string(Array.isArray(text) ? text.join('\n') : text)
|
|
})
|
|
},
|
|
|
|
// Deprecated APIs kept for backwards compatibility
|
|
get signText () {
|
|
return this.getSignText()[0]
|
|
},
|
|
set signText (text) {
|
|
this.setSignText(text)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|