also lint js, improve style rules
This commit is contained in:
parent
b8c7c2d9e8
commit
fb881e879b
31 changed files with 358 additions and 332 deletions
|
|
@ -1,15 +1,27 @@
|
|||
{
|
||||
"extends": "zardoy",
|
||||
"ignorePatterns": [
|
||||
"!*.js"
|
||||
],
|
||||
"rules": {
|
||||
"object-curly-spacing": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"comma-dangle": [
|
||||
"error",
|
||||
// todo maybe "always-multiline"?
|
||||
"only-multiline"
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
2,
|
||||
{
|
||||
"SwitchCase": 2,
|
||||
"SwitchCase": 1,
|
||||
"ignoredNodes": [
|
||||
"TemplateLiteral"
|
||||
]
|
||||
|
|
@ -65,9 +77,13 @@
|
|||
"@typescript-eslint/no-require-imports": "off",
|
||||
"unicorn/prefer-number-properties": "off",
|
||||
"@typescript-eslint/no-confusing-void-expression": "off",
|
||||
"unicorn/no-empty-file": "off",
|
||||
"unicorn/prefer-event-target": "off",
|
||||
// needs to be fixed actually
|
||||
"@typescript-eslint/no-floating-promises": "warn",
|
||||
"no-async-promise-executor": "off",
|
||||
"no-bitwise": "off"
|
||||
"no-bitwise": "off",
|
||||
"unicorn/filename-case": "off",
|
||||
"max-depth": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const compareRenderedFlatWorld = () => {
|
|||
}
|
||||
|
||||
const testWorldLoad = () => {
|
||||
cy.document().then({ timeout: 20_000, }, doc => {
|
||||
cy.document().then({ timeout: 20_000 }, doc => {
|
||||
return new Cypress.Promise(resolve => {
|
||||
doc.addEventListener('cypress-world-ready', resolve)
|
||||
})
|
||||
|
|
@ -49,7 +49,7 @@ it('Loads & renders singleplayer', () => {
|
|||
},
|
||||
renderDistance: 2
|
||||
})
|
||||
cy.get('#title-screen').find('[data-test-id="singleplayer-button"]', { includeShadowDom: true, }).click()
|
||||
cy.get('#title-screen').find('[data-test-id="singleplayer-button"]', { includeShadowDom: true }).click()
|
||||
testWorldLoad()
|
||||
})
|
||||
|
||||
|
|
@ -58,15 +58,15 @@ it('Joins to server', () => {
|
|||
window.localStorage.version = ''
|
||||
visit()
|
||||
// todo replace with data-test
|
||||
cy.get('#title-screen').find('[data-test-id="connect-screen-button"]', { includeShadowDom: true, }).click()
|
||||
cy.get('input#serverip', { includeShadowDom: true, }).clear().focus().type('localhost')
|
||||
cy.get('[data-test-id="connect-to-server"]', { includeShadowDom: true, }).click()
|
||||
cy.get('#title-screen').find('[data-test-id="connect-screen-button"]', { includeShadowDom: true }).click()
|
||||
cy.get('input#serverip', { includeShadowDom: true }).clear().focus().type('localhost')
|
||||
cy.get('[data-test-id="connect-to-server"]', { includeShadowDom: true }).click()
|
||||
testWorldLoad()
|
||||
})
|
||||
|
||||
it('Loads & renders zip world', () => {
|
||||
cleanVisit()
|
||||
cy.get('#title-screen').find('[data-test-id="select-file-folder"]', { includeShadowDom: true, }).click({ shiftKey: true })
|
||||
cy.get('#title-screen').find('[data-test-id="select-file-folder"]', { includeShadowDom: true }).click({ shiftKey: true })
|
||||
cy.get('input[type="file"]').selectFile('cypress/superflat.zip', { force: true })
|
||||
testWorldLoad()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,23 +4,23 @@ const { initPlugin } = require('cypress-plugin-snapshots/plugin')
|
|||
const polyfill = require('esbuild-plugin-polyfill-node')
|
||||
|
||||
module.exports = (on, config) => {
|
||||
initPlugin(on, config)
|
||||
on('file:preprocessor', cypressEsbuildPreprocessor({
|
||||
esbuildOptions: {
|
||||
plugins: [
|
||||
polyfill.polyfillNode({
|
||||
polyfills: {
|
||||
crypto: true,
|
||||
},
|
||||
})
|
||||
],
|
||||
},
|
||||
}))
|
||||
on('task', {
|
||||
log (message) {
|
||||
console.log(message)
|
||||
return null
|
||||
},
|
||||
})
|
||||
return config
|
||||
initPlugin(on, config)
|
||||
on('file:preprocessor', cypressEsbuildPreprocessor({
|
||||
esbuildOptions: {
|
||||
plugins: [
|
||||
polyfill.polyfillNode({
|
||||
polyfills: {
|
||||
crypto: true,
|
||||
},
|
||||
})
|
||||
],
|
||||
},
|
||||
}))
|
||||
on('task', {
|
||||
log (message) {
|
||||
console.log(message)
|
||||
return null
|
||||
},
|
||||
})
|
||||
return config
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ function getViewDirection (pitch, yaw) {
|
|||
|
||||
class BlockInteraction {
|
||||
static instance = null
|
||||
/** @type {null | {blockPos,mesh}} */
|
||||
interactionLines = null
|
||||
|
||||
init () {
|
||||
bot.on('physicsTick', () => { if (this.lastBlockPlaced < 4) this.lastBlockPlaced++ })
|
||||
|
|
@ -103,8 +105,6 @@ class BlockInteraction {
|
|||
})
|
||||
}
|
||||
|
||||
/** @type {null | {blockPos,mesh}} */
|
||||
interactionLines = null
|
||||
updateBlockInteractionLines (/** @type {Vec3 | null} */blockPos, /** @type {{position, width, height, depth}[]} */shapePositions = undefined) {
|
||||
if (this.interactionLines !== null) {
|
||||
viewer.scene.remove(this.interactionLines.mesh)
|
||||
|
|
@ -127,6 +127,7 @@ class BlockInteraction {
|
|||
}
|
||||
|
||||
// todo this shouldnt be done in the render loop, migrate the code to dom events to avoid delays on lags
|
||||
// eslint-disable-next-line complexity
|
||||
update () {
|
||||
const cursorBlock = bot.blockAtCursor(5)
|
||||
let cursorBlockDiggable = cursorBlock
|
||||
|
|
@ -137,13 +138,13 @@ class BlockInteraction {
|
|||
cursorChanged = !cursorBlock.position.equals(this.cursorBlock.position)
|
||||
}
|
||||
|
||||
// Place
|
||||
if (cursorBlock && this.buttons[2] && (!this.lastButtons[2] || cursorChanged) && this.lastBlockPlaced >= 4) {
|
||||
// Place / interact
|
||||
if (this.buttons[2] && (!this.lastButtons[2] || cursorChanged) && this.lastBlockPlaced >= 4) {
|
||||
const vecArray = [new Vec3(0, -1, 0), new Vec3(0, 1, 0), new Vec3(0, 0, -1), new Vec3(0, 0, 1), new Vec3(-1, 0, 0), new Vec3(1, 0, 0)]
|
||||
//@ts-ignore
|
||||
//@ts-expect-error
|
||||
const delta = cursorBlock.intersect.minus(cursorBlock.position)
|
||||
// check instead?
|
||||
//@ts-ignore
|
||||
|
||||
//@ts-expect-error
|
||||
bot._placeBlockWithOptions(cursorBlock, vecArray[cursorBlock.face], { delta, forceLook: 'ignore' }).catch(console.warn)
|
||||
this.lastBlockPlaced = 0
|
||||
}
|
||||
|
|
@ -167,9 +168,7 @@ class BlockInteraction {
|
|||
}
|
||||
|
||||
// Show cursor
|
||||
if (!cursorBlock) {
|
||||
this.updateBlockInteractionLines(null)
|
||||
} else {
|
||||
if (cursorBlock) {
|
||||
const allShapes = [...cursorBlock.shapes, ...cursorBlock['interactionShapes'] ?? []]
|
||||
this.updateBlockInteractionLines(cursorBlock.position, allShapes.map(shape => {
|
||||
return getDataFromShape(shape)
|
||||
|
|
@ -191,6 +190,8 @@ class BlockInteraction {
|
|||
position.add(cursorBlock.position)
|
||||
this.blockBreakMesh.position.set(position.x, position.y, position.z)
|
||||
}
|
||||
} else {
|
||||
this.updateBlockInteractionLines(null)
|
||||
}
|
||||
|
||||
// Show break animation
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ async function addFolderToZip(folderPath, zip, relativePath) {
|
|||
const exportWorld = async () => {
|
||||
// todo issue into chat warning if fs is writable!
|
||||
const zip = new JSZip()
|
||||
let {worldFolder} = localServer.options
|
||||
let { worldFolder } = localServer.options
|
||||
if (!worldFolder.startsWith('/')) worldFolder = `/${worldFolder}`
|
||||
await addFolderToZip(worldFolder, zip, '')
|
||||
|
||||
|
|
|
|||
88
src/chat.js
88
src/chat.js
|
|
@ -1,13 +1,12 @@
|
|||
//@ts-check
|
||||
const { LitElement, html, css } = require('lit')
|
||||
const { isMobile } = require('./menus/components/common')
|
||||
const { activeModalStack, hideCurrentModal, showModal, miscUiState } = require('./globalState')
|
||||
import { repeat } from 'lit/directives/repeat.js'
|
||||
import { classMap } from 'lit/directives/class-map.js'
|
||||
import { LitElement, html, css } from 'lit'
|
||||
import { isCypress } from './utils'
|
||||
import { getBuiltinCommandsList, tryHandleBuiltinCommand } from './builtinCommands'
|
||||
import { notification } from './menus/notification'
|
||||
import { options } from './optionsStorage'
|
||||
import { activeModalStack, hideCurrentModal, showModal, miscUiState } from './globalState'
|
||||
|
||||
const styles = {
|
||||
black: 'color:#000000',
|
||||
|
|
@ -35,11 +34,11 @@ const styles = {
|
|||
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 r = Math.trunc((color >> 16 & 0xFF) * dim)
|
||||
const g = Math.trunc((color >> 8 & 0xFF) * dim)
|
||||
const b = Math.trunc((color & 0xFF) * dim)
|
||||
|
||||
const f = (c) => ('00' + c.toString(16)).substr(-2)
|
||||
const f = (c) => ('00' + c.toString(16)).slice(-2)
|
||||
return `#${f(r)}${f(g)}${f(b)}`
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +258,7 @@ class ChatBox extends LitElement {
|
|||
notification.show = false
|
||||
const chat = this.shadowRoot.getElementById('chat-messages')
|
||||
/** @type {HTMLInputElement} */
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
const chatInput = this.shadowRoot.getElementById('chatinput')
|
||||
|
||||
showModal(this)
|
||||
|
|
@ -281,7 +280,7 @@ class ChatBox extends LitElement {
|
|||
}
|
||||
|
||||
get inChat () {
|
||||
return activeModalStack.find(m => m.elem === this) !== undefined
|
||||
return activeModalStack.some(m => m.elem === this)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -290,7 +289,7 @@ class ChatBox extends LitElement {
|
|||
init (client) {
|
||||
const chat = this.shadowRoot.getElementById('chat-messages')
|
||||
/** @type {HTMLInputElement} */
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
const chatInput = this.shadowRoot.getElementById('chatinput')
|
||||
this.chatInput = chatInput
|
||||
|
||||
|
|
@ -300,7 +299,7 @@ class ChatBox extends LitElement {
|
|||
let savedCurrentValue
|
||||
// Chat events
|
||||
document.addEventListener('keydown', e => {
|
||||
if (activeModalStack.slice(-1)[0]?.elem !== this) return
|
||||
if (activeModalStack.at(-1)?.elem !== this) return
|
||||
if (e.code === 'ArrowUp') {
|
||||
if (this.chatHistoryPos === 0) return
|
||||
if (this.chatHistoryPos === this.chatHistory.length) {
|
||||
|
|
@ -379,7 +378,7 @@ class ChatBox extends LitElement {
|
|||
const splitted = tText.split(/%s|%\d+\$s/g)
|
||||
|
||||
let i = 0
|
||||
splitted.forEach((part, j) => {
|
||||
for (const [j, part] of splitted.entries()) {
|
||||
msglist.push({ text: part, ...styles })
|
||||
|
||||
if (j + 1 < splitted.length) {
|
||||
|
|
@ -398,7 +397,7 @@ class ChatBox extends LitElement {
|
|||
}
|
||||
i++
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
msglist.push({
|
||||
...msg,
|
||||
|
|
@ -409,9 +408,9 @@ class ChatBox extends LitElement {
|
|||
}
|
||||
|
||||
if (msg.extra) {
|
||||
msg.extra.forEach(ex => {
|
||||
for (const ex of msg.extra) {
|
||||
readMsg({ ...styles, ...ex })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -441,9 +440,9 @@ class ChatBox extends LitElement {
|
|||
// todo remove
|
||||
window.dummyMessage = () => {
|
||||
client.emit('chat', {
|
||||
message: "{\"color\":\"yellow\",\"translate\":\"multiplayer.player.joined\",\"with\":[{\"insertion\":\"pviewer672\",\"clickEvent\":{\"action\":\"suggest_command\",\"value\":\"/tell pviewer672 \"},\"hoverEvent\":{\"action\":\"show_entity\",\"contents\":{\"type\":\"minecraft:player\",\"id\":\"ecd0eeb1-625e-3fea-b16e-cb449dcfa434\",\"name\":{\"text\":\"pviewer672\"}}},\"text\":\"pviewer672\"}]}",
|
||||
message: '{"color":"yellow","translate":"multiplayer.player.joined","with":[{"insertion":"pviewer672","clickEvent":{"action":"suggest_command","value":"/tell pviewer672 "},"hoverEvent":{"action":"show_entity","contents":{"type":"minecraft:player","id":"ecd0eeb1-625e-3fea-b16e-cb449dcfa434","name":{"text":"pviewer672"}}},"text":"pviewer672"}]}',
|
||||
position: 1,
|
||||
sender: "00000000-0000-0000-0000-000000000000",
|
||||
sender: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
}
|
||||
// window.dummyMessage()
|
||||
|
|
@ -493,7 +492,7 @@ class ChatBox extends LitElement {
|
|||
this.completeRequestValue = value
|
||||
let items = await bot.tabComplete(value, true, true)
|
||||
if (typeof items[0] === 'object') {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
if (items[0].match) items = items.map(i => i.match)
|
||||
}
|
||||
if (value !== this.completeRequestValue) return
|
||||
|
|
@ -518,10 +517,11 @@ class ChatBox extends LitElement {
|
|||
].filter(Boolean)
|
||||
|
||||
return html`
|
||||
<span
|
||||
class="chat-message-part"
|
||||
style="${applyStyles.join(';')}"
|
||||
>${text}</span>`
|
||||
<span
|
||||
class="chat-message-part"
|
||||
style="${applyStyles.join(';')}"
|
||||
>${text}</span>
|
||||
`
|
||||
}
|
||||
|
||||
renderMessage (/** @type {Message} */message) {
|
||||
|
|
@ -565,29 +565,31 @@ class ChatBox extends LitElement {
|
|||
render () {
|
||||
|
||||
return html`
|
||||
<div class="chat-wrapper chat-messages-wrapper ${miscUiState.currentTouch ? 'display-mobile' : ''}">
|
||||
<div class="chat ${this.inChat ? 'opened' : ''}" id="chat-messages">
|
||||
<!-- its to hide player joined at random timings, todo add chat tests as well -->
|
||||
${repeat(isCypress() ? [] : this.messages, (m) => m.id, (m) => this.renderMessage(m))}
|
||||
<div class="chat-wrapper chat-messages-wrapper ${miscUiState.currentTouch ? 'display-mobile' : ''}">
|
||||
<div class="chat ${this.inChat ? 'opened' : ''}" id="chat-messages">
|
||||
<!-- its to hide player joined at random timings, todo add chat tests as well -->
|
||||
${repeat(isCypress() ? [] : this.messages, (m) => m.id, (m) => this.renderMessage(m))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-wrapper chat-input-wrapper ${miscUiState.currentTouch ? 'input-mobile' : ''}" style="display: ${this.inChat ? 'block' : 'none'}">
|
||||
<div class="chat-input">
|
||||
${this.completionItems.length ? html`<div class="chat-completions">
|
||||
<div class="chat-completions-pad-text">${this.completePadText}</div>
|
||||
<div class="chat-completions-items">
|
||||
${repeat(this.completionItems, (i) => i, (i) => html`<div @click=${() => this.acceptComplete(i)}>${i}</div>`)}
|
||||
</div>
|
||||
</div>` : ''}
|
||||
<input type="text" class="chat-mobile-hidden" id="chatinput-next-command" spellcheck="false" autocomplete="off" @focus=${() => {
|
||||
this.auxInputFocus('ArrowUp')
|
||||
}}></input>
|
||||
<input type="text" class="chat-input" id="chatinput" spellcheck="false" autocomplete="off" aria-autocomplete="both"></input>
|
||||
<input type="text" class="chat-mobile-hidden" id="chatinput-prev-command" spellcheck="false" autocomplete="off" @focus=${() => {
|
||||
this.auxInputFocus('ArrowDown')
|
||||
}}></input>
|
||||
<div class="chat-wrapper chat-input-wrapper ${miscUiState.currentTouch ? 'input-mobile' : ''}" style="display: ${this.inChat ? 'block' : 'none'}">
|
||||
<div class="chat-input">
|
||||
${this.completionItems.length ? html`
|
||||
<div class="chat-completions">
|
||||
<div class="chat-completions-pad-text">${this.completePadText}</div>
|
||||
<div class="chat-completions-items">
|
||||
${repeat(this.completionItems, (i) => i, (i) => html`<div @click=${() => this.acceptComplete(i)}>${i}</div>`)}
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
<input type="text" class="chat-mobile-hidden" id="chatinput-next-command" spellcheck="false" autocomplete="off" @focus=${() => {
|
||||
this.auxInputFocus('ArrowUp')
|
||||
}}></input>
|
||||
<input type="text" class="chat-input" id="chatinput" spellcheck="false" autocomplete="off" aria-autocomplete="both"></input>
|
||||
<input type="text" class="chat-mobile-hidden" id="chatinput-prev-command" spellcheck="false" autocomplete="off" @focus=${() => {
|
||||
this.auxInputFocus('ArrowDown')
|
||||
}}></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,22 +139,22 @@ const onTriggerOrReleased = (command: Command, pressed: boolean) => {
|
|||
// handle general commands
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (command) {
|
||||
case 'general.jump':
|
||||
bot.setControlState('jump', pressed)
|
||||
break
|
||||
case 'general.sneak':
|
||||
gameAdditionalState.isSneaking = pressed
|
||||
bot.setControlState('sneak', pressed)
|
||||
break
|
||||
case 'general.sprint':
|
||||
case 'general.jump':
|
||||
bot.setControlState('jump', pressed)
|
||||
break
|
||||
case 'general.sneak':
|
||||
gameAdditionalState.isSneaking = pressed
|
||||
bot.setControlState('sneak', pressed)
|
||||
break
|
||||
case 'general.sprint':
|
||||
// todo add setting to change behavior
|
||||
if (pressed) {
|
||||
setSprinting(pressed)
|
||||
}
|
||||
break
|
||||
case 'general.attackDestroy':
|
||||
document.dispatchEvent(new MouseEvent(pressed ? 'mousedown' : 'mouseup', { button: 0 }))
|
||||
break
|
||||
if (pressed) {
|
||||
setSprinting(pressed)
|
||||
}
|
||||
break
|
||||
case 'general.attackDestroy':
|
||||
document.dispatchEvent(new MouseEvent(pressed ? 'mousedown' : 'mouseup', { button: 0 }))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,26 +192,26 @@ contro.on('trigger', ({ command }) => {
|
|||
if (stringStartsWith(command, 'general')) {
|
||||
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
||||
switch (command) {
|
||||
case 'general.inventory':
|
||||
document.exitPointerLock?.()
|
||||
showModal({ reactType: 'inventory' })
|
||||
break
|
||||
case 'general.drop':
|
||||
if (bot.heldItem) bot.tossStack(bot.heldItem)
|
||||
break
|
||||
case 'general.chat':
|
||||
document.getElementById('hud').shadowRoot.getElementById('chat').enableChat()
|
||||
break
|
||||
case 'general.command':
|
||||
document.getElementById('hud').shadowRoot.getElementById('chat').enableChat('/')
|
||||
break
|
||||
case 'general.interactPlace':
|
||||
document.dispatchEvent(new MouseEvent('mousedown', { button: 2 }))
|
||||
setTimeout(() => {
|
||||
case 'general.inventory':
|
||||
document.exitPointerLock?.()
|
||||
showModal({ reactType: 'inventory' })
|
||||
break
|
||||
case 'general.drop':
|
||||
if (bot.heldItem) bot.tossStack(bot.heldItem)
|
||||
break
|
||||
case 'general.chat':
|
||||
document.getElementById('hud').shadowRoot.getElementById('chat').enableChat()
|
||||
break
|
||||
case 'general.command':
|
||||
document.getElementById('hud').shadowRoot.getElementById('chat').enableChat('/')
|
||||
break
|
||||
case 'general.interactPlace':
|
||||
document.dispatchEvent(new MouseEvent('mousedown', { button: 2 }))
|
||||
setTimeout(() => {
|
||||
// todo cleanup
|
||||
document.dispatchEvent(new MouseEvent('mouseup', { button: 2 }))
|
||||
})
|
||||
break
|
||||
document.dispatchEvent(new MouseEvent('mouseup', { button: 2 }))
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -319,16 +319,16 @@ const toggleFly = () => {
|
|||
gameAdditionalState.isFlying = isFlying()
|
||||
}
|
||||
// #endregion
|
||||
addEventListener('mousedown', (e) => {
|
||||
addEventListener('mousedown', async (e) => {
|
||||
if (!bot) return
|
||||
// wheel click
|
||||
// todo support ctrl+wheel (+nbt)
|
||||
if (e.button === 1) {
|
||||
const block = bot.blockAtCursor(/* 6 */5)
|
||||
const block = bot.blockAtCursor(5)
|
||||
if (!block) return
|
||||
const Item = require('prismarine-item')(bot.version)
|
||||
const item = new Item(block.type, 1, 0)
|
||||
bot.creative.setInventorySlot(bot.inventory.hotbarStart + bot.quickBarSlot, item)
|
||||
await bot.creative.setInventorySlot(bot.inventory.hotbarStart + bot.quickBarSlot, item)
|
||||
bot.updateHeldItem()
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
//@ts-check
|
||||
const EventEmitter = require('events').EventEmitter
|
||||
const { EventEmitter } = require('events')
|
||||
const debug = require('debug')('minecraft-protocol')
|
||||
const states = require('minecraft-protocol/src/states')
|
||||
|
||||
window.serverDataChannel ??= {}
|
||||
export const customCommunication = {
|
||||
sendData (data) {
|
||||
//@ts-ignore
|
||||
setTimeout(() => {
|
||||
window.serverDataChannel[this.isServer ? 'emitClient' : 'emitServer'](data)
|
||||
})
|
||||
},
|
||||
receiverSetup (processData) {
|
||||
//@ts-ignore
|
||||
window.serverDataChannel[this.isServer ? 'emitServer' : 'emitClient'] = (data) => {
|
||||
processData(data)
|
||||
}
|
||||
|
|
@ -39,6 +37,7 @@ class CustomChannelClient extends EventEmitter {
|
|||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/adjacent-overload-signatures, grouped-accessor-pairs
|
||||
set state (newProperty) {
|
||||
const oldProperty = this.protocolState
|
||||
this.protocolState = newProperty
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
module.exports = {
|
||||
'motd': 'A Minecraft Server \nRunning flying-squid',
|
||||
// host: '',
|
||||
// eslint-disable-next-line unicorn/numeric-separators-style
|
||||
'port': 25565,
|
||||
'max-players': 10,
|
||||
'online-mode': false,
|
||||
|
|
@ -21,7 +22,7 @@ module.exports = {
|
|||
// 'worldHeight': 80
|
||||
// }
|
||||
},
|
||||
'kickTimeout': 10000,
|
||||
'kickTimeout': 10_000,
|
||||
'plugins': {},
|
||||
'modpe': false,
|
||||
'view-distance': 2,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module.exports.resolveSrv = function (hostname, callback) {
|
|||
Http.send()
|
||||
|
||||
Http.onload = function () {
|
||||
const response = Http.response
|
||||
const { response } = Http
|
||||
if (response.Status === 3) {
|
||||
const err = new Error('querySrv ENOTFOUND')
|
||||
err.code = 'ENOTFOUND'
|
||||
|
|
@ -24,7 +24,7 @@ module.exports.resolveSrv = function (hostname, callback) {
|
|||
return
|
||||
}
|
||||
const willreturn = []
|
||||
response.Answer.forEach(function (object) {
|
||||
for (const object of response.Answer) {
|
||||
const data = object.data.split(' ')
|
||||
willreturn.push({
|
||||
priority: data[0],
|
||||
|
|
@ -32,7 +32,7 @@ module.exports.resolveSrv = function (hostname, callback) {
|
|||
port: data[2],
|
||||
name: data[3]
|
||||
})
|
||||
})
|
||||
}
|
||||
console.log(willreturn)
|
||||
callback(null, willreturn)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ type ContextMenuItem = { callback; label }
|
|||
export const activeModalStack: Modal[] = proxy([])
|
||||
|
||||
export const replaceActiveModalStack = (name: string, newModalStack = activeModalStacks[name]) => {
|
||||
hideModal(undefined, undefined, { restorePrevious: false, force: true, })
|
||||
hideModal(undefined, undefined, { restorePrevious: false, force: true })
|
||||
activeModalStack.splice(0, activeModalStack.length, ...newModalStack)
|
||||
// todo restore previous
|
||||
}
|
||||
|
|
@ -90,7 +90,7 @@ export const hideCurrentModal = (_data = undefined, restoredActions = undefined)
|
|||
|
||||
// ---
|
||||
|
||||
export const currentContextMenu = proxy({ items: [] as ContextMenuItem[] | null, x: 0, y: 0, })
|
||||
export const currentContextMenu = proxy({ items: [] as ContextMenuItem[] | null, x: 0, y: 0 })
|
||||
|
||||
export const showContextmenu = (items: ContextMenuItem[], { clientX, clientY }) => {
|
||||
Object.assign(currentContextMenu, {
|
||||
|
|
|
|||
|
|
@ -632,7 +632,7 @@ async function connect(connectOptions: {
|
|||
}
|
||||
screenTouches++
|
||||
if (screenTouches === 3) {
|
||||
window.dispatchEvent(new MouseEvent('mousedown', { button: 1, }))
|
||||
window.dispatchEvent(new MouseEvent('mousedown', { button: 1 }))
|
||||
}
|
||||
if (capturedPointer) {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ subscribeKey(miscUiState, 'gameLoaded', async () => {
|
|||
// on game load
|
||||
version = getVersion(bot.version)
|
||||
blockStates = await fetch(`blocksStates/${version}.json`).then(async res => res.json())
|
||||
getImage({ path: 'blocks', } as any)
|
||||
getImage({ path: 'invsprite', } as any)
|
||||
getImage({ path: 'blocks' } as any)
|
||||
getImage({ path: 'invsprite' } as any)
|
||||
mcData = MinecraftData(version)
|
||||
})
|
||||
|
||||
|
|
@ -88,9 +88,9 @@ const getItemSlice = (name) => {
|
|||
|
||||
const getImageSrc = (path) => {
|
||||
switch (path) {
|
||||
case 'gui/container/inventory': return InventoryGui
|
||||
case 'blocks': return globalThis.texturePackDataUrl || `textures/${version}.png`
|
||||
case 'invsprite': return `invsprite.png`
|
||||
case 'gui/container/inventory': return InventoryGui
|
||||
case 'blocks': return globalThis.texturePackDataUrl || `textures/${version}.png`
|
||||
case 'invsprite': return `invsprite.png`
|
||||
}
|
||||
return Dirt
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
//@ts-check
|
||||
const { html, css, LitElement } = require('lit')
|
||||
const { commonCss, openURL } = require('./components/common')
|
||||
const { subscribe } = require('valtio')
|
||||
const { hideCurrentModal } = require('../globalState')
|
||||
const { getScreenRefreshRate } = require('../utils')
|
||||
const { subscribe } = require('valtio')
|
||||
const { options } = require('../optionsStorage')
|
||||
const { commonCss, openURL } = require('./components/common')
|
||||
|
||||
class AdvancedOptionsScreen extends LitElement {
|
||||
/** @type {null | number} */
|
||||
|
|
@ -55,8 +55,8 @@ class AdvancedOptionsScreen extends LitElement {
|
|||
<main>
|
||||
<div class="wrapper">
|
||||
<pmui-button pmui-width="150px" pmui-label=${`Always Show Mobile Controls: ${options.alwaysShowMobileControls ? 'ON' : 'OFF'}`} @pmui-click=${() => {
|
||||
options.alwaysShowMobileControls = !options.alwaysShowMobileControls
|
||||
}
|
||||
options.alwaysShowMobileControls = !options.alwaysShowMobileControls
|
||||
}
|
||||
}></pmui-button>
|
||||
<!-- todo rename button, also might be unstable -->
|
||||
<pmui-button pmui-width="150px" pmui-label="Guide: Disable VSync" @click=${() => openURL('https://gist.github.com/zardoy/6e5ce377d2b4c1e322e660973da069cd')}></pmui-button>
|
||||
|
|
|
|||
|
|
@ -57,14 +57,15 @@ class BossBar extends LitElement {
|
|||
this.updateBar(this.bar)
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
<div class="title">${this.title}</div>
|
||||
<div class="bossbar" style=${styleMap(this.bossBarStyles)}>
|
||||
<div class="fill" style=${styleMap(this.fillStyles)}></div>
|
||||
<div class="fill" style=${styleMap(this.div1Styles)}></div>
|
||||
<div class="fill" style=${styleMap(this.div2Styles)}></div>
|
||||
</div>
|
||||
</div>`
|
||||
<div class="container">
|
||||
<div class="title">${this.title}</div>
|
||||
<div class="bossbar" style=${styleMap(this.bossBarStyles)}>
|
||||
<div class="fill" style=${styleMap(this.fillStyles)}></div>
|
||||
<div class="fill" style=${styleMap(this.div1Styles)}></div>
|
||||
<div class="fill" style=${styleMap(this.div2Styles)}></div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
setTitle (bar) {
|
||||
|
|
@ -121,9 +122,11 @@ class BossBars extends LitElement {
|
|||
}
|
||||
|
||||
render () {
|
||||
return html`<div class="bossBars" id="bossBars">
|
||||
return html`
|
||||
<div class="bossBars" id="bossBars">
|
||||
${[...this.bossBars.values()]}
|
||||
</div>`
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
init () {
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ class BreathBar extends LitElement {
|
|||
|
||||
const breaths = breathbar.children
|
||||
|
||||
for (let i = 0; i < breaths.length; i++) {
|
||||
breaths[i].classList.remove('full')
|
||||
breaths[i].classList.remove('half')
|
||||
for (const breath of breaths) {
|
||||
breath.classList.remove('full')
|
||||
breath.classList.remove('half')
|
||||
}
|
||||
|
||||
for (let i = 0; i < Math.ceil(hValue / 2); i++) {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ let audioContext
|
|||
const sounds = {}
|
||||
|
||||
// load as many resources on page load as possible instead on demand as user can disable internet connection after he thinks the page is loaded
|
||||
let loadingSounds = []
|
||||
const loadingSounds = []
|
||||
async function loadSound (path) {
|
||||
loadingSounds.push(path)
|
||||
const res = await window.fetch(path)
|
||||
|
|
@ -151,22 +151,23 @@ class Button extends LitElement {
|
|||
|
||||
render () {
|
||||
return html`
|
||||
<button
|
||||
class="button"
|
||||
?disabled=${this.disabled}
|
||||
@click=${this.onBtnClick}
|
||||
style="width: ${this.width};"
|
||||
data-test-id=${this.testId}
|
||||
>
|
||||
<!-- todo self host icons -->
|
||||
${this.icon ? html`<iconify-icon class="icon" icon="${this.icon}"></iconify-icon>` : ''}
|
||||
${this.label}
|
||||
</button>`
|
||||
<button
|
||||
class="button"
|
||||
?disabled=${this.disabled}
|
||||
@click=${this.onBtnClick}
|
||||
style="width: ${this.width};"
|
||||
data-test-id=${this.testId}
|
||||
>
|
||||
<!-- todo self host icons -->
|
||||
${this.icon ? html`<iconify-icon class="icon" icon="${this.icon}"></iconify-icon>` : ''}
|
||||
${this.label}
|
||||
</button>
|
||||
`
|
||||
}
|
||||
|
||||
onBtnClick (e) {
|
||||
playSound('button_click.mp3')
|
||||
this.dispatchEvent(new window.CustomEvent('pmui-click', { detail: e, }))
|
||||
this.dispatchEvent(new window.CustomEvent('pmui-click', { detail: e }))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,9 +83,9 @@ class FoodBar extends LitElement {
|
|||
|
||||
const foods = foodbar.children
|
||||
|
||||
for (let i = 0; i < foods.length; i++) {
|
||||
foods[i].classList.remove('full')
|
||||
foods[i].classList.remove('half')
|
||||
for (const food of foods) {
|
||||
food.classList.remove('full')
|
||||
food.classList.remove('half')
|
||||
}
|
||||
|
||||
// if (d) this.onHungerUpdate()
|
||||
|
|
|
|||
|
|
@ -120,9 +120,9 @@ class HealthBar extends LitElement {
|
|||
|
||||
const hearts = health.children
|
||||
|
||||
for (let i = 0; i < hearts.length; i++) {
|
||||
hearts[i].classList.remove('full')
|
||||
hearts[i].classList.remove('half')
|
||||
for (const heart of hearts) {
|
||||
heart.classList.remove('full')
|
||||
heart.classList.remove('half')
|
||||
}
|
||||
|
||||
if (d) this.onDamage()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
const { LitElement, html, css, unsafeCSS } = require('lit')
|
||||
const widgetsTexture = require('minecraft-assets/minecraft-assets/data/1.16.4/gui/widgets.png')
|
||||
const { subscribeKey } = require('valtio/utils')
|
||||
const invsprite = require('../../invsprite.json')
|
||||
const { isGameActive, miscUiState, showModal } = require('../../globalState')
|
||||
|
||||
const widgetsTexture = require('minecraft-assets/minecraft-assets/data/1.16.4/gui/widgets.png')
|
||||
const { subscribeKey } = require('valtio/utils')
|
||||
const { isProbablyIphone } = require('./common')
|
||||
|
||||
class Hotbar extends LitElement {
|
||||
|
|
@ -139,7 +139,7 @@ class Hotbar extends LitElement {
|
|||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (!isGameActive(true)) return
|
||||
const numPressed = +(e.code.match(/Digit(\d)/)?.[1] ?? -1)
|
||||
const numPressed = +((/Digit(\d)/.exec(e.code))?.[1] ?? -1)
|
||||
if (numPressed < 1 || numPressed > 9) return
|
||||
this.reloadHotbarSelected(numPressed - 1)
|
||||
})
|
||||
|
|
@ -188,21 +188,21 @@ class Hotbar extends LitElement {
|
|||
<p id="hotbar-item-name">${this.activeItemName}</p>
|
||||
<div id="hotbar-selected"></div>
|
||||
<div id="hotbar-items-wrapper" @pointerdown=${(e) => {
|
||||
if (!e.target.id.startsWith('hotbar')) return
|
||||
const slot = +e.target.id.split('-')[1]
|
||||
this.reloadHotbarSelected(slot)
|
||||
}}>
|
||||
${Array.from({ length: 9 }).map((_, i) => html`
|
||||
<div class="hotbar-item" id="${`hotbar-${i}`}" @pointerdown=${(e) => {
|
||||
this.reloadHotbarSelected(i)
|
||||
}}>
|
||||
<div class="item-icon"></div>
|
||||
<span class="item-stack"></span>
|
||||
</div>
|
||||
`)}
|
||||
${miscUiState.currentTouch ? html`<div class="hotbar-item hotbar-more" @pointerdown=${() => {
|
||||
showModal({ reactType: 'inventory', })
|
||||
}}>` : undefined}
|
||||
if (!e.target.id.startsWith('hotbar')) return
|
||||
const slot = +e.target.id.split('-')[1]
|
||||
this.reloadHotbarSelected(slot)
|
||||
}}>
|
||||
${Array.from({ length: 9 }).map((_, i) => html`
|
||||
<div class="hotbar-item" id="${`hotbar-${i}`}" @pointerdown=${(e) => {
|
||||
this.reloadHotbarSelected(i)
|
||||
}}>
|
||||
<div class="item-icon"></div>
|
||||
<span class="item-stack"></span>
|
||||
</div>
|
||||
`)}
|
||||
${miscUiState.currentTouch ? html`<div class="hotbar-item hotbar-more" @pointerdown=${() => {
|
||||
showModal({ reactType: 'inventory' })
|
||||
}}>` : undefined}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -187,20 +187,20 @@ class Slider extends LitElement {
|
|||
value="${this.value}"
|
||||
?disabled=${!!this.disabled}
|
||||
@input=${(e) => {
|
||||
const range = e.target
|
||||
this.ratio = (range.value - range.min) / (range.max - range.min)
|
||||
this.value = range.value
|
||||
}}
|
||||
const range = e.target
|
||||
this.ratio = (range.value - range.min) / (range.max - range.min)
|
||||
this.value = range.value
|
||||
}}
|
||||
@pointerdown=${() => {
|
||||
window.addEventListener('pointerup', (e) => {
|
||||
this.dispatchEvent(new InputEvent('change'))
|
||||
}, {
|
||||
once: true,
|
||||
})
|
||||
}}
|
||||
@keyup=${() => {
|
||||
window.addEventListener('pointerup', (e) => {
|
||||
this.dispatchEvent(new InputEvent('change'))
|
||||
}}>
|
||||
}, {
|
||||
once: true,
|
||||
})
|
||||
}}
|
||||
@keyup=${() => {
|
||||
this.dispatchEvent(new InputEvent('change'))
|
||||
}}>
|
||||
<div class="disabled" title="${this.disabled}"></div>
|
||||
<div
|
||||
class="slider-thumb"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
//@ts-check
|
||||
const { LitElement, html, css, unsafeCSS } = require('lit')
|
||||
const { isMobile } = require('./components/common')
|
||||
const { showModal, miscUiState } = require('../globalState')
|
||||
const { options, watchValue } = require('../optionsStorage')
|
||||
const { getGamemodeNumber } = require('../utils')
|
||||
const { isMobile } = require('./components/common')
|
||||
|
||||
export const guiIcons1_17_1 = require('minecraft-assets/minecraft-assets/data/1.17.1/gui/icons.png')
|
||||
export const guiIcons1_16_4 = require('minecraft-assets/minecraft-assets/data/1.16.4/gui/icons.png')
|
||||
|
|
@ -277,7 +277,7 @@ class Hud extends LitElement {
|
|||
onHealthUpdate()
|
||||
|
||||
const onXpUpdate = () => {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
this.shadowRoot.querySelector('#xp-bar-bg').firstElementChild.style.width = `${182 * bot.experience.progress}px`
|
||||
xpLabel.innerHTML = String(bot.experience.level)
|
||||
xpLabel.style.display = bot.experience.level > 0 ? 'block' : 'none'
|
||||
|
|
@ -307,19 +307,19 @@ class Hud extends LitElement {
|
|||
return html`
|
||||
<div class="mobile-top-btns" id="mobile-top">
|
||||
<button class="debug-btn" @pointerdown=${(e) => {
|
||||
window.dispatchEvent(new MouseEvent('mousedown', { button: 1, }))
|
||||
}}>Select</button>
|
||||
window.dispatchEvent(new MouseEvent('mousedown', { button: 1 }))
|
||||
}}>Select</button>
|
||||
<button class="debug-btn" @pointerdown=${(e) => {
|
||||
this.shadowRoot.getElementById('debug-overlay').showOverlay = !this.shadowRoot.getElementById('debug-overlay').showOverlay
|
||||
}}>F3</button>
|
||||
this.shadowRoot.getElementById('debug-overlay').showOverlay = !this.shadowRoot.getElementById('debug-overlay').showOverlay
|
||||
}}>F3</button>
|
||||
<button class="chat-btn" @pointerdown=${(e) => {
|
||||
e.stopPropagation()
|
||||
this.shadowRoot.querySelector('#chat').enableChat()
|
||||
}}></button>
|
||||
e.stopPropagation()
|
||||
this.shadowRoot.querySelector('#chat').enableChat()
|
||||
}}></button>
|
||||
<button class="pause-btn" @pointerdown=${(e) => {
|
||||
e.stopPropagation()
|
||||
showModal(document.getElementById('pause-screen'))
|
||||
}}></button>
|
||||
e.stopPropagation()
|
||||
showModal(document.getElementById('pause-screen'))
|
||||
}}></button>
|
||||
</div>
|
||||
|
||||
<pmui-debug-overlay id="debug-overlay"></pmui-debug-overlay>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const { LitElement, html, css } = require('lit')
|
||||
const { commonCss } = require('./components/common')
|
||||
const { hideCurrentModal } = require('../globalState')
|
||||
const { commonCss } = require('./components/common')
|
||||
|
||||
class KeyBindsScreen extends LitElement {
|
||||
static get styles () {
|
||||
|
|
@ -135,23 +135,23 @@ class KeyBindsScreen extends LitElement {
|
|||
<main>
|
||||
<div class="keymap-list">
|
||||
${this.keymaps.map((m, i) => html`
|
||||
<div class="keymap-entry">
|
||||
<span>${m.name}</span>
|
||||
<div class="keymap-entry">
|
||||
<span>${m.name}</span>
|
||||
|
||||
<div class="keymap-entry-btns">
|
||||
<pmui-button pmui-width="72px" pmui-label="${this.selected === i ? `> ${m.key} <` : m.key}" @pmui-click=${e => {
|
||||
e.target.setAttribute('pmui-label', `> ${m.key} <`)
|
||||
this.selected = i
|
||||
this.requestUpdate()
|
||||
}}></pmui-button>
|
||||
<pmui-button pmui-width="50px" ?pmui-disabled=${m.key === m.defaultKey} pmui-label="Reset" @pmui-click=${() => {
|
||||
this.keymaps[i].key = this.keymaps[i].defaultKey
|
||||
this.requestUpdate()
|
||||
this.selected = -1
|
||||
}}></pmui-button>
|
||||
<div class="keymap-entry-btns">
|
||||
<pmui-button pmui-width="72px" pmui-label="${this.selected === i ? `> ${m.key} <` : m.key}" @pmui-click=${e => {
|
||||
e.target.setAttribute('pmui-label', `> ${m.key} <`)
|
||||
this.selected = i
|
||||
this.requestUpdate()
|
||||
}}></pmui-button>
|
||||
<pmui-button pmui-width="50px" ?pmui-disabled=${m.key === m.defaultKey} pmui-label="Reset" @pmui-click=${() => {
|
||||
this.keymaps[i].key = this.keymaps[i].defaultKey
|
||||
this.requestUpdate()
|
||||
this.selected = -1
|
||||
}}></pmui-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`)}
|
||||
`)}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
//@ts-check
|
||||
const { LitElement, html, css } = require('lit')
|
||||
const { commonCss } = require('./components/common')
|
||||
const { addPanoramaCubeMap } = require('../panorama')
|
||||
const { hideModal, activeModalStacks, activeModalStack, replaceActiveModalStack, miscUiState } = require('../globalState')
|
||||
const { guessProblem } = require('../guessProblem')
|
||||
const { fsState } = require('../loadSave')
|
||||
const { commonCss } = require('./components/common')
|
||||
|
||||
class LoadingErrorScreen extends LitElement {
|
||||
static get styles () {
|
||||
|
|
@ -58,9 +58,10 @@ class LoadingErrorScreen extends LitElement {
|
|||
|
||||
async statusRunner () {
|
||||
const array = ['.', '..', '...', '']
|
||||
const timer = ms => new Promise((resolve) => setTimeout(resolve, ms))
|
||||
const timer = async ms => new Promise((resolve) => {setTimeout(resolve, ms)})
|
||||
|
||||
const load = async () => {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
for (let i = 0; true; i = ((i + 1) % array.length)) {
|
||||
this._loadingDots = array[i]
|
||||
await timer(500)
|
||||
|
|
@ -84,27 +85,27 @@ class LoadingErrorScreen extends LitElement {
|
|||
<p class="last-status">${this.lastStatus ? `Last status: ${this.lastStatus}` : this.lastStatus}</p></div>
|
||||
|
||||
${this.hasError
|
||||
? html`<div class="error-buttons"><pmui-button .hidden=${!this.maybeRecoverable} pmui-width="200px" pmui-label="Back" @pmui-click=${() => {
|
||||
this.hasError = false
|
||||
this.lastStatus = ''
|
||||
miscUiState.gameLoaded = false
|
||||
if (activeModalStacks['main-menu']) {
|
||||
replaceActiveModalStack('main-menu')
|
||||
} else {
|
||||
hideModal(undefined, undefined, { force: true })
|
||||
? html`<div class="error-buttons"><pmui-button .hidden=${!this.maybeRecoverable} pmui-width="200px" pmui-label="Back" @pmui-click=${() => {
|
||||
this.hasError = false
|
||||
this.lastStatus = ''
|
||||
miscUiState.gameLoaded = false
|
||||
if (activeModalStacks['main-menu']) {
|
||||
replaceActiveModalStack('main-menu')
|
||||
} else {
|
||||
hideModal(undefined, undefined, { force: true })
|
||||
}
|
||||
document.getElementById('play-screen').style.display = 'block'
|
||||
addPanoramaCubeMap()
|
||||
}}></pmui-button><pmui-button .hidden=${!(miscUiState.singleplayer && fsState.inMemorySave)} pmui-width="200px" pmui-label="Reset world" @pmui-click=${() => {
|
||||
if (!confirm('Are you sure you want to delete all local world content?')) return
|
||||
for (const key of Object.keys(localStorage)) {
|
||||
if (/^[\da-fA-F]{8}(?:\b-[\da-fA-F]{4}){3}\b-[\da-fA-F]{12}$/g.test(key) || key === '/') {
|
||||
localStorage.removeItem(key)
|
||||
}
|
||||
document.getElementById('play-screen').style.display = 'block'
|
||||
addPanoramaCubeMap()
|
||||
}}></pmui-button><pmui-button .hidden=${!(miscUiState.singleplayer && fsState.inMemorySave)} pmui-width="200px" pmui-label="Reset world" @pmui-click=${() => {
|
||||
if (!confirm('Are you sure you want to delete all local world content?')) return
|
||||
for (const key of Object.keys(localStorage)) {
|
||||
if (/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/g.test(key) || key === '/') {
|
||||
localStorage.removeItem(key)
|
||||
}
|
||||
}
|
||||
window.location.reload()
|
||||
}}></pmui-button><pmui-button @pmui-click=${() => window.location.reload()} pmui-label="Full Reload" pmui-width="200px"></pmui-button></div>`
|
||||
: ''
|
||||
}
|
||||
window.location.reload()
|
||||
}}></pmui-button><pmui-button @pmui-click=${() => window.location.reload()} pmui-label="Full Reload" pmui-width="200px"></pmui-button></div>`
|
||||
: ''
|
||||
}
|
||||
`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
const { LitElement, html, css } = require('lit')
|
||||
const { commonCss, isMobile } = require('./components/common')
|
||||
const { subscribe } = require('valtio')
|
||||
const { subscribeKey } = require('valtio/utils')
|
||||
const { showModal, hideCurrentModal, isGameActive, miscUiState } = require('../globalState')
|
||||
const { toNumber, openFilePicker, setLoadingScreenStatus } = require('../utils')
|
||||
const { options, watchValue } = require('../optionsStorage')
|
||||
const { subscribe } = require('valtio')
|
||||
const { subscribeKey } = require('valtio/utils')
|
||||
const { getResourcePackName, uninstallTexturePack, resourcePackState } = require('../texturePack')
|
||||
const { fsState } = require('../loadSave')
|
||||
const { commonCss, isMobile } = require('./components/common')
|
||||
|
||||
class OptionsScreen extends LitElement {
|
||||
static get styles () {
|
||||
|
|
@ -69,47 +69,47 @@ class OptionsScreen extends LitElement {
|
|||
<main>
|
||||
<div class="wrapper">
|
||||
<pmui-slider pmui-label="Mouse Sensitivity X" pmui-value="${options.mouseSensX}" pmui-min="1" pmui-max="100" @input=${(e) => {
|
||||
options.mouseSensX = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.mouseSensX = +e.target.value
|
||||
}}></pmui-slider>
|
||||
<pmui-slider pmui-label="Mouse Sensitivity Y" pmui-value="${options.mouseSensY}" pmui-min="1" pmui-max="100" @input=${(e) => {
|
||||
options.mouseSensY = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.mouseSensY = +e.target.value
|
||||
}}></pmui-slider>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<pmui-slider pmui-label="Chat Width" pmui-value="${options.chatWidth}" pmui-min="0" pmui-max="320" pmui-type="px" @input=${(e) => {
|
||||
options.chatWidth = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.chatWidth = +e.target.value
|
||||
}}></pmui-slider>
|
||||
<pmui-slider pmui-label="Chat Height" pmui-value="${options.chatHeight}" pmui-min="0" pmui-max="180" pmui-type="px" @input=${(e) => {
|
||||
options.chatHeight = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.chatHeight = +e.target.value
|
||||
}}></pmui-slider>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<pmui-slider pmui-label="Chat Scale" pmui-value="${options.chatScale}" pmui-min="0" pmui-max="100" @input=${(e) => {
|
||||
options.chatScale = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.chatScale = +e.target.value
|
||||
}}></pmui-slider>
|
||||
<pmui-slider pmui-label="Sound Volume" pmui-value="${options.volume}" pmui-min="0" pmui-max="100" @input=${(e) => {
|
||||
options.volume = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.volume = +e.target.value
|
||||
}}></pmui-slider>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<pmui-button .disabled=${true} pmui-width="150px" pmui-label="Key Binds" @pmui-click=${() => showModal(document.getElementById('keybinds-screen'))}></pmui-button>
|
||||
<pmui-slider pmui-label="Gui Scale" pmui-value="${options.guiScale}" pmui-min="1" pmui-max="4" pmui-type="" @change=${(e) => {
|
||||
options.guiScale = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.guiScale = +e.target.value
|
||||
}}></pmui-slider>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<pmui-slider pmui-label="Render Distance" pmui-value="${options.renderDistance}" .disabled="${isGameActive(false) && !miscUiState.singleplayer ? 'Can be changed only from main menu for now' : undefined}" pmui-min="2" pmui-max="${miscUiState.singleplayer ? 16 : 6}" pmui-type=" chunks" @change=${(e) => {
|
||||
options.renderDistance = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.renderDistance = +e.target.value
|
||||
}}></pmui-slider>
|
||||
<pmui-slider pmui-label="Field of View" pmui-value="${options.fov}" pmui-min="30" pmui-max="110" pmui-type="" @input=${(e) => {
|
||||
options.fov = +e.target.value
|
||||
}}></pmui-slider>
|
||||
options.fov = +e.target.value
|
||||
}}></pmui-slider>
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<pmui-button pmui-width="150px" pmui-label=${'Advanced'} @pmui-click=${() => {
|
||||
showModal(document.querySelector('pmui-advanced-optionsscreen'))
|
||||
}
|
||||
showModal(document.querySelector('pmui-advanced-optionsscreen'))
|
||||
}
|
||||
}></pmui-button>
|
||||
<pmui-button pmui-width="150px" pmui-label=${'Mouse Raw Input: ' + (options.mouseRawInput ? 'ON' : 'OFF')} title="Wether to disable any mouse acceleration (MC does it by default)" @pmui-click=${() => {
|
||||
options.mouseRawInput = !options.mouseRawInput
|
||||
|
|
@ -117,7 +117,7 @@ class OptionsScreen extends LitElement {
|
|||
}></pmui-button>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<pmui-button title="Auto Fullscreen allows you to use Ctrl+W and Escape without delays" .disabled="${!navigator['keyboard'] ? "Your browser doesn't support keyboard lock API" : undefined}" pmui-width="150px" pmui-label=${'Auto Fullscreen: ' + (options.autoFullScreen ? 'ON' : 'OFF')} title="Wether to disable any mouse acceleration (MC does it by default)" @pmui-click=${() => {
|
||||
<pmui-button title="Auto Fullscreen allows you to use Ctrl+W and Escape without delays" .disabled="${navigator['keyboard'] ? undefined : 'Your browser doesn\'t support keyboard lock API'}" pmui-width="150px" pmui-label=${'Auto Fullscreen: ' + (options.autoFullScreen ? 'ON' : 'OFF')} @pmui-click=${() => {
|
||||
options.autoFullScreen = !options.autoFullScreen
|
||||
}
|
||||
}></pmui-button>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
//@ts-check
|
||||
const { LitElement, html, css } = require('lit')
|
||||
const { openURL } = require('./components/common')
|
||||
const { subscribe } = require('valtio')
|
||||
const { subscribeKey } = require('valtio/utils')
|
||||
const { hideCurrentModal, showModal, miscUiState } = require('../globalState')
|
||||
const { fsState } = require('../loadSave')
|
||||
const { subscribe } = require('valtio')
|
||||
const { saveWorld } = require('../builtinCommands')
|
||||
const { notification } = require('./notification')
|
||||
const { disconnect } = require('../utils')
|
||||
const { subscribeKey } = require('valtio/utils')
|
||||
const { closeWan, openToWanAndCopyJoinLink, getJoinLink } = require('../localServerMultiplayer')
|
||||
const { notification } = require('./notification')
|
||||
const { openURL } = require('./components/common')
|
||||
|
||||
class PauseScreen extends LitElement {
|
||||
static get styles () {
|
||||
|
|
@ -80,13 +80,15 @@ class PauseScreen extends LitElement {
|
|||
<pmui-button pmui-width="204px" pmui-label="Options" @pmui-click=${() => showModal(document.getElementById('options-screen'))}></pmui-button>
|
||||
<!-- todo use qr icon (full pixelarticons package) -->
|
||||
<!-- todo also display copy link button when opened -->
|
||||
${joinButton ? html`<div class="row">
|
||||
<pmui-button pmui-width="170px" pmui-label="${miscUiState.wanOpened ? "Close Wan" : "Copy Join Link"}" @pmui-click=${() => this.clickJoinLinkButton()}></pmui-button>
|
||||
<pmui-button style="height: 0;" pmui-icon="pixelarticons:dice" pmui-width="20px" pmui-label="" @pmui-click=${() => this.clickJoinLinkButton(true)}></pmui-button>
|
||||
</div>` : ''}
|
||||
${joinButton ? html`
|
||||
<div class="row">
|
||||
<pmui-button pmui-width="170px" pmui-label="${miscUiState.wanOpened ? 'Close Wan' : 'Copy Join Link'}" @pmui-click=${async () => this.clickJoinLinkButton()}></pmui-button>
|
||||
<pmui-button style="height: 0;" pmui-icon="pixelarticons:dice" pmui-width="20px" pmui-label="" @pmui-click=${async () => this.clickJoinLinkButton(true)}></pmui-button>
|
||||
</div>
|
||||
` : ''}
|
||||
<pmui-button pmui-width="204px" pmui-label="${localServer && !fsState.syncFs && !fsState.isReadonly ? 'Save & Quit' : 'Disconnect'}" @pmui-click=${async () => {
|
||||
disconnect()
|
||||
}}></pmui-button>
|
||||
disconnect()
|
||||
}}></pmui-button>
|
||||
</main>
|
||||
`
|
||||
}
|
||||
|
|
@ -102,7 +104,7 @@ class PauseScreen extends LitElement {
|
|||
if (qr) {
|
||||
const joinLink = getJoinLink()
|
||||
miscUiState.currentDisplayQr = joinLink
|
||||
return
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
//@ts-check
|
||||
const { LitElement, html, css } = require('lit')
|
||||
const { commonCss } = require('./components/common')
|
||||
const { hideCurrentModal } = require('../globalState')
|
||||
const mineflayer = require('mineflayer')
|
||||
const viewerSupportedVersions = require('prismarine-viewer/viewer/supportedVersions.json')
|
||||
const { hideCurrentModal } = require('../globalState')
|
||||
const { commonCss } = require('./components/common')
|
||||
|
||||
const fullySupporedVersions = viewerSupportedVersions
|
||||
const partiallySupportVersions = mineflayer.supportedVersions
|
||||
|
|
@ -84,7 +84,7 @@ class PlayScreen extends LitElement {
|
|||
super()
|
||||
this.version = ''
|
||||
// todo set them sooner add indicator
|
||||
window.fetch('config.json').then(res => res.json()).then(c => c, (error) => {
|
||||
window.fetch('config.json').then(async res => res.json()).then(c => c, (error) => {
|
||||
console.error('Failed to load config.json', error)
|
||||
return {}
|
||||
}).then(config => {
|
||||
|
|
@ -100,7 +100,7 @@ class PlayScreen extends LitElement {
|
|||
}
|
||||
|
||||
this.server = getParam('server', 'ip') ?? config.defaultHost
|
||||
this.serverport = getParam('serverport', false) ?? config.defaultHostPort ?? 25565
|
||||
this.serverport = getParam('serverport', false) ?? config.defaultHostPort ?? 25_565
|
||||
this.proxy = getParam('proxy') ?? config.defaultProxy
|
||||
this.proxyport = getParam('proxyport', false) ?? (!config.defaultProxy && !config.defaultProxyPort ? '' : config.defaultProxyPort ?? 443)
|
||||
this.version = getParam('version') || (window.localStorage.getItem('version') ?? config.defaultVersion)
|
||||
|
|
@ -203,7 +203,7 @@ class PlayScreen extends LitElement {
|
|||
this.dispatchEvent(new window.CustomEvent('connect', {
|
||||
detail: {
|
||||
server: `${this.server}:${this.serverport}`,
|
||||
proxy: `${this.proxy}${this.proxy !== '' ? `:${this.proxyport}` : ''}`,
|
||||
proxy: `${this.proxy}${this.proxy === '' ? '' : `:${this.proxyport}`}`,
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
botVersion: this.version
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
const { openWorldDirectory, openWorldZip } = require('../browserfs')
|
||||
const { showModal } = require('../globalState')
|
||||
const { fsState } = require('../loadSave')
|
||||
const { openURL } = require('./components/common')
|
||||
const { LitElement, html, css, unsafeCSS } = require('lit')
|
||||
const fs = require('fs')
|
||||
const { LitElement, html, css, unsafeCSS } = require('lit')
|
||||
|
||||
const mcImage = require('minecraft-assets/minecraft-assets/data/1.17.1/gui/title/minecraft.png')
|
||||
const { fsState } = require('../loadSave')
|
||||
const { showModal } = require('../globalState')
|
||||
const { openWorldDirectory, openWorldZip } = require('../browserfs')
|
||||
const { options } = require('../optionsStorage')
|
||||
const defaultLocalServerOptions = require('../defaultLocalServerOptions')
|
||||
const { openFilePicker } = require('../utils')
|
||||
const { openURL } = require('./components/common')
|
||||
|
||||
// const SUPPORT_WORLD_LOADING = !!window.showDirectoryPicker
|
||||
const SUPPORT_WORLD_LOADING = true
|
||||
|
|
@ -121,14 +121,6 @@ class TitleScreen extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
reload () {
|
||||
navigator.serviceWorker.getRegistration().then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
constructor () {
|
||||
super()
|
||||
this.versionStatus = ''
|
||||
|
|
@ -147,6 +139,14 @@ class TitleScreen extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
reload () {
|
||||
navigator.serviceWorker.getRegistration().then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
return html`
|
||||
<div class="game-title">
|
||||
|
|
@ -160,25 +160,25 @@ class TitleScreen extends LitElement {
|
|||
<pmui-button pmui-width="200px" pmui-label="Connect to server" pmui-test-id="connect-screen-button" @pmui-click=${() => showModal(document.getElementById('play-screen'))}></pmui-button>
|
||||
<div style="display:flex;justify-content: space-between;">
|
||||
<pmui-button pmui-width="${SUPPORT_WORLD_LOADING ? '170px' : '200px'}" pmui-test-id="singleplayer-button" pmui-label="Singleplayer" @pmui-click=${() => {
|
||||
this.style.display = 'none'
|
||||
fsState.isReadonly = false
|
||||
fsState.syncFs = true
|
||||
fsState.inMemorySave = true
|
||||
const notFirstTime = fs.existsSync('./world/level.dat')
|
||||
if (notFirstTime && !options.localServerOptions.version) {
|
||||
options.localServerOptions.version = '1.16.1' // legacy version
|
||||
} else {
|
||||
options.localServerOptions.version ??= defaultLocalServerOptions.version
|
||||
}
|
||||
this.dispatchEvent(new window.CustomEvent('singleplayer', {}))
|
||||
}}></pmui-button>
|
||||
this.style.display = 'none'
|
||||
fsState.isReadonly = false
|
||||
fsState.syncFs = true
|
||||
fsState.inMemorySave = true
|
||||
const notFirstTime = fs.existsSync('./world/level.dat')
|
||||
if (notFirstTime && !options.localServerOptions.version) {
|
||||
options.localServerOptions.version = '1.16.1' // legacy version
|
||||
} else {
|
||||
options.localServerOptions.version ??= defaultLocalServerOptions.version
|
||||
}
|
||||
this.dispatchEvent(new window.CustomEvent('singleplayer', {}))
|
||||
}}></pmui-button>
|
||||
${SUPPORT_WORLD_LOADING ? html`<pmui-button pmui-test-id="select-file-folder" pmui-icon="pixelarticons:folder" pmui-width="20px" pmui-label="" @pmui-click=${({ detail: e }) => {
|
||||
if (!!window.showDirectoryPicker && !e.shiftKey) {
|
||||
openWorldDirectory()
|
||||
} else {
|
||||
openFilePicker()
|
||||
}
|
||||
}}></pmui-button>` : ''}
|
||||
if (!!window.showDirectoryPicker && !e.shiftKey) {
|
||||
openWorldDirectory()
|
||||
} else {
|
||||
openFilePicker()
|
||||
}
|
||||
}}></pmui-button>` : ''}
|
||||
</div>
|
||||
<pmui-button pmui-width="200px" pmui-label="Options" @pmui-click=${() => showModal(document.getElementById('options-screen'))}></pmui-button>
|
||||
<div class="menu-row">
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
//@ts-check
|
||||
|
||||
import { join } from 'path'
|
||||
import { fromTexturePackPath, resourcePackState } from './texturePack'
|
||||
import fs from 'fs'
|
||||
import { subscribeKey } from 'valtio/utils'
|
||||
import { fromTexturePackPath, resourcePackState } from './texturePack'
|
||||
import { options } from './optionsStorage'
|
||||
|
||||
let panoramaCubeMap
|
||||
|
|
@ -68,7 +68,7 @@ export async function addPanoramaCubeMap () {
|
|||
const panorGeo = new THREE.BoxGeometry(1000, 1000, 1000)
|
||||
|
||||
const loader = new THREE.TextureLoader()
|
||||
let panorMaterials = []
|
||||
const panorMaterials = []
|
||||
await updateResourcePackSupportPanorama()
|
||||
for (const file of panoramaFiles) {
|
||||
panorMaterials.push(new THREE.MeshBasicMaterial({
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ useInterfaceState.setState({
|
|||
if (!bot) return
|
||||
if (state === 0) {
|
||||
for (const action of actionAndState) {
|
||||
contro.pressedKeyOrButtonChanged({code: action[2],}, false)
|
||||
contro.pressedKeyOrButtonChanged({ code: action[2] }, false)
|
||||
}
|
||||
} else {
|
||||
//@ts-expect-error
|
||||
contro.pressedKeyOrButtonChanged({code: actionAndState[2],}, true)
|
||||
contro.pressedKeyOrButtonChanged({ code: actionAndState[2] }, true)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -104,7 +104,7 @@ const DisplayQr = () => {
|
|||
miscUiState.currentDisplayQr = null
|
||||
}}
|
||||
>
|
||||
<QRCodeSVG size={384} value={currentDisplayQr} style={{display: 'block', border: '2px solid black',}} />
|
||||
<QRCodeSVG size={384} value={currentDisplayQr} style={{ display: 'block', border: '2px solid black' }} />
|
||||
</div>, document.body)
|
||||
|
||||
}
|
||||
|
|
|
|||
12
src/utils.ts
12
src/utils.ts
|
|
@ -106,11 +106,11 @@ export async function getScreenRefreshRate(): Promise<number> {
|
|||
|
||||
export const getGamemodeNumber = (bot) => {
|
||||
switch (bot.game.gameMode) {
|
||||
case 'survival': return 0
|
||||
case 'creative': return 1
|
||||
case 'adventure': return 2
|
||||
case 'spectator': return 3
|
||||
default: return -1
|
||||
case 'survival': return 0
|
||||
case 'creative': return 1
|
||||
case 'adventure': return 2
|
||||
case 'spectator': return 3
|
||||
default: return -1
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ export const setLoadingScreenStatus = function (status: string | undefined, isEr
|
|||
|
||||
if (status === undefined) {
|
||||
loadingScreen.status = ''
|
||||
hideModal({ elem: loadingScreen, }, null, { force: true })
|
||||
hideModal({ elem: loadingScreen }, null, { force: true })
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue