Fix chat messages (#272)
* added readme pt-pt * added url/querystring deps and fix chat pos/scale url and querystring were missing in node_modules. chat scale option wasn't implemented and chat input was on top instead of bottom. * added bot version text field and guiScale for small screens text field to choose bot version. gui scale changes on small screens (slider takes no effect then). Removed unused images. * Update index.js * fix chat messages and chat on top on mobile * npm fix * fixed mcData var * removed debug stuff and fixed color shadow Co-authored-by: Romain Beaumont <romain.rom1@gmail.com>
This commit is contained in:
parent
8172c478d0
commit
09ba027f9b
1 changed files with 105 additions and 91 deletions
196
lib/chat.js
196
lib/chat.js
|
@ -1,4 +1,5 @@
|
|||
const { LitElement, html, css } = require('lit')
|
||||
const { isMobile } = require('./menus/components/common')
|
||||
|
||||
const styles = {
|
||||
black: 'color:#000000',
|
||||
|
@ -22,17 +23,16 @@ const styles = {
|
|||
underlined: 'text-decoration:underline',
|
||||
italic: 'font-style:italic'
|
||||
}
|
||||
const dictionary = {
|
||||
'chat.stream.emote': '(%s) * %s %s',
|
||||
'chat.stream.text': '(%s) <%s> %s',
|
||||
// 'chat.type.achievement': '%s has just earned the achievement %s', // 1.8? Not tested
|
||||
// 'chat.type.advancement.task': '%s has just earned the advancement %s',
|
||||
// 'chat.type.advancement.goal': '%s has just reached the goal %s',
|
||||
// 'chat.type.advancement.challenge': '%s did a challenge lolol %s',
|
||||
'chat.type.admin': '[%s: %s]',
|
||||
'chat.type.announcement': '[%s] %s',
|
||||
'chat.type.emote': '* %s %s',
|
||||
'chat.type.text': '<%s> %s'
|
||||
|
||||
function colorShadow (hex, dim = 0.25) {
|
||||
const color = parseInt(hex.replace('#', ''), 16)
|
||||
|
||||
const r = (color >> 16 & 0xFF) * dim | 0
|
||||
const g = (color >> 8 & 0xFF) * dim | 0
|
||||
const b = (color & 0xFF) * dim | 0
|
||||
|
||||
const f = (c) => ('00' + c.toString(16)).substr(-2)
|
||||
return `#${f(r)}${f(g)}${f(b)}`
|
||||
}
|
||||
|
||||
class ChatBox extends LitElement {
|
||||
|
@ -63,6 +63,14 @@ class ChatBox extends LitElement {
|
|||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.input-mobile {
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.display-mobile {
|
||||
top: 40px;
|
||||
}
|
||||
|
||||
.chat {
|
||||
overflow: hidden;
|
||||
color: white;
|
||||
|
@ -137,6 +145,9 @@ class ChatBox extends LitElement {
|
|||
const chat = this.shadowRoot.querySelector('#chat')
|
||||
const chatInput = this.shadowRoot.querySelector('#chatinput')
|
||||
|
||||
this.shadowRoot.querySelector('#chat-wrapper2').classList.toggle('input-mobile', isMobile())
|
||||
this.shadowRoot.querySelector('#chat-wrapper').classList.toggle('display-mobile', isMobile())
|
||||
|
||||
// Set inChat value
|
||||
this.inChat = true
|
||||
// Exit the pointer lock
|
||||
|
@ -155,6 +166,10 @@ class ChatBox extends LitElement {
|
|||
document.querySelector('#hud').shadowRoot.querySelector('#chat').shadowRoot.querySelectorAll('.chat-message').forEach(e => e.classList.add('chat-message-chat-opened'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {globalThis.THREE.Renderer} client
|
||||
* @param {import('minecraft-protocol').Client} renderer
|
||||
*/
|
||||
init (client, renderer) {
|
||||
this.inChat = false
|
||||
const chat = this.shadowRoot.querySelector('#chat')
|
||||
|
@ -168,21 +183,21 @@ class ChatBox extends LitElement {
|
|||
// Show chat
|
||||
chat.style.display = 'block'
|
||||
|
||||
const self = this
|
||||
|
||||
// Esc event - Doesnt work with onkeypress?! - keypressed is deprecated uk
|
||||
document.addEventListener('keydown', e => {
|
||||
if (gameMenu.inMenu) return
|
||||
if (!self.inChat) return
|
||||
if (!this.inChat) return
|
||||
e = e || window.event
|
||||
if (e.code === 'Escape') {
|
||||
disableChat()
|
||||
} else if (e.keyCode === 38) {
|
||||
} else if (e.code === 'ArrowUp') {
|
||||
if (this.chatHistoryPos === 0) return
|
||||
chatInput.value = this.chatHistory[--this.chatHistoryPos] !== undefined ? this.chatHistory[this.chatHistoryPos] : ''
|
||||
} else if (e.keyCode === 40) {
|
||||
setTimeout(() => { chatInput.setSelectionRange(-1, -1) }, 0)
|
||||
} else if (e.code === 'ArrowDown') {
|
||||
if (this.chatHistoryPos === this.chatHistory.length) return
|
||||
chatInput.value = this.chatHistory[++this.chatHistoryPos] !== undefined ? this.chatHistory[this.chatHistoryPos] : ''
|
||||
setTimeout(() => { chatInput.setSelectionRange(-1, -1) }, 0)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -192,7 +207,7 @@ class ChatBox extends LitElement {
|
|||
document.addEventListener('keypress', e => {
|
||||
if (gameMenu.inMenu) return
|
||||
e = e || window.event
|
||||
if (self.inChat === false) {
|
||||
if (this.inChat === false) {
|
||||
keyBindScrn.keymaps.forEach(km => {
|
||||
if (e.code === km.key) {
|
||||
switch (km.defaultKey) {
|
||||
|
@ -209,34 +224,24 @@ class ChatBox extends LitElement {
|
|||
return false
|
||||
}
|
||||
|
||||
if (!self.inChat) return
|
||||
if (!this.inChat) return
|
||||
|
||||
e.stopPropagation()
|
||||
|
||||
if (e.code === 'Enter') {
|
||||
this.chatHistory.push(chatInput.value)
|
||||
client.write('chat', { message: chatInput.value })
|
||||
disableChat()
|
||||
}
|
||||
})
|
||||
// Enable inputs back when focused
|
||||
/* document.addEventListener("pointerlockchange", function(event) {
|
||||
const canvas = document.getElementById("noa-canvas");
|
||||
if (
|
||||
document.pointerLockElement === canvas ||
|
||||
document.mozPointerLockElement === canvas
|
||||
) {
|
||||
// Someone focused the game back so we hide chat.
|
||||
chatState.inChat = false;
|
||||
hideChat();
|
||||
}
|
||||
}); */
|
||||
|
||||
function disableChat () {
|
||||
self.inChat = false
|
||||
const disableChat = () => {
|
||||
this.inChat = false
|
||||
hideChat()
|
||||
renderer.domElement.requestPointerLock()
|
||||
}
|
||||
|
||||
function hideChat () {
|
||||
const hideChat = () => {
|
||||
// Clear chat input
|
||||
chatInput.value = ''
|
||||
// Unfocus it
|
||||
|
@ -249,74 +254,83 @@ class ChatBox extends LitElement {
|
|||
document.querySelector('#hud').shadowRoot.querySelector('#chat').shadowRoot.querySelectorAll('.chat-message').forEach(e => e.classList.remove('chat-message-chat-opened'))
|
||||
}
|
||||
|
||||
function readExtra (extra) {
|
||||
const shouldReturn = []
|
||||
for (const i in extra) {
|
||||
if (extra[i].text) {
|
||||
shouldReturn.push({
|
||||
text: extra[i].text,
|
||||
color: extra[i].color,
|
||||
bold: !!extra[i].bold,
|
||||
italic: !!extra[i].italic,
|
||||
underlined: !!extra[i].underlined,
|
||||
strikethrough: !!extra[i].strikethrough,
|
||||
obfuscated: !!extra[i].obfuscated
|
||||
})
|
||||
} else {
|
||||
readExtra(extra).forEach(function (el) {
|
||||
shouldReturn.push(el)
|
||||
})
|
||||
}
|
||||
}
|
||||
return shouldReturn
|
||||
}
|
||||
|
||||
client.on('chat', (packet) => {
|
||||
// Reading of chat message
|
||||
const fullmessage = JSON.parse(packet.message.toString())
|
||||
let msglist = []
|
||||
if (
|
||||
fullmessage.extra &&
|
||||
fullmessage.extra.length > 0 &&
|
||||
!fullmessage.translate
|
||||
) {
|
||||
msglist = readExtra(fullmessage.extra)
|
||||
} else if (fullmessage.text && fullmessage.text.length > 0) {
|
||||
msglist.push({ text: fullmessage.text, color: undefined })
|
||||
} else if (dictionary[fullmessage.translate]) {
|
||||
let msg = dictionary[fullmessage.translate]
|
||||
fullmessage.with.forEach(obj => {
|
||||
if (obj.insertion && obj.text) {
|
||||
msg = msg.replace('%s', obj.text)
|
||||
}
|
||||
if (obj.extra) {
|
||||
if (obj.text && obj.text.length > 0) {
|
||||
msglist.push({ text: obj.text, color: undefined })
|
||||
} else {
|
||||
const text = readExtra(obj.extra)
|
||||
if (text.length > 1) {
|
||||
console.log('Unsupported chat alert :(')
|
||||
}
|
||||
msg = msg.replace('%s', text[0].text)
|
||||
msglist.push({ text: msg, color: undefined })
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// msglist.push({
|
||||
// text:
|
||||
// "Unsupported message (Please report this):\n" +
|
||||
// JSON.stringify(fullmessage),
|
||||
// color: undefined
|
||||
// });
|
||||
const msglist = []
|
||||
|
||||
const colorF = (color) => {
|
||||
return color.trim().startsWith('#') ? `color:${color}` : styles[color] ?? undefined
|
||||
}
|
||||
|
||||
const readMsg = (msglist, msg) => {
|
||||
const styles = {
|
||||
color: msg.color,
|
||||
bold: !!msg.bold,
|
||||
italic: !!msg.italic,
|
||||
underlined: !!msg.underlined,
|
||||
strikethrough: !!msg.strikethrough,
|
||||
obfuscated: !!msg.obfuscated
|
||||
}
|
||||
|
||||
if (msg.text) {
|
||||
msglist.push({
|
||||
text: msg.text,
|
||||
...styles
|
||||
})
|
||||
}
|
||||
|
||||
if (msg.translate) {
|
||||
const tText = window.mcData.language[msg.translate] ?? msg.translate
|
||||
|
||||
if (msg.with) {
|
||||
const splited = tText.split(/%s|%\d+\$s/g)
|
||||
|
||||
let i = 0
|
||||
splited.forEach((spl, j, arr) => {
|
||||
msglist.push({ text: spl, ...styles })
|
||||
|
||||
if (j + 1 < arr.length) {
|
||||
if (msg.with[i]) {
|
||||
if (typeof msg.with[i] === 'string') {
|
||||
readMsg(msglist, {
|
||||
...styles,
|
||||
text: msg.with[i]
|
||||
})
|
||||
} else {
|
||||
readMsg(msglist, {
|
||||
...styles,
|
||||
...msg.with[i]
|
||||
})
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
})
|
||||
} else {
|
||||
msglist.push({
|
||||
text: tText,
|
||||
...styles
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.extra) {
|
||||
msg.extra.forEach(ex => {
|
||||
readMsg(msglist, { ...styles, ...ex })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
readMsg(msglist, fullmessage)
|
||||
|
||||
const li = document.createElement('li')
|
||||
msglist.forEach(msg => {
|
||||
const span = document.createElement('span')
|
||||
span.appendChild(document.createTextNode(msg.text))
|
||||
span.setAttribute(
|
||||
'style',
|
||||
`${msg.color ? styles[msg.color.toLowerCase()] : styles.white}; ${
|
||||
`${msg.color ? colorF(msg.color.toLowerCase()) + `; text-shadow: 1px 1px 0px ${colorShadow(colorF(msg.color.toLowerCase()).replace('color:', ''))}` : styles.white}; ${
|
||||
msg.bold ? styles.bold + ';' : ''
|
||||
}${msg.italic ? styles.italic + ';' : ''}${
|
||||
msg.strikethrough ? styles.strikethrough + ';' : ''
|
||||
|
|
Loading…
Reference in a new issue