fix entities apply skin crash

fix websocket ping display for ws
This commit is contained in:
Vitaly Turovsky 2025-02-18 21:25:18 +03:00
commit 44d630b1b3
6 changed files with 48 additions and 21 deletions

View file

@ -383,19 +383,26 @@ export class Entities extends EventEmitter {
if (!playerObject) return
let skinTexture: THREE.Texture
let skinCanvas: HTMLCanvasElement
if (skinUrl === stevePngUrl) {
skinTexture = await steveTexture
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (!ctx) throw new Error('Failed to get context')
ctx.drawImage(skinTexture.image, 0, 0)
skinCanvas = canvas
} else {
const { canvas: skinCanvas, image } = await loadSkinImage(skinUrl)
const { canvas, image } = await loadSkinImage(skinUrl)
playerCustomSkinImage = image
skinTexture = new THREE.CanvasTexture(skinCanvas)
skinTexture = new THREE.CanvasTexture(canvas)
skinCanvas = canvas
}
skinTexture.magFilter = THREE.NearestFilter
skinTexture.minFilter = THREE.NearestFilter
skinTexture.needsUpdate = true
playerObject.skin.map = skinTexture as any
playerObject.skin.modelType = inferModelType(skinTexture.image)
playerObject.skin.modelType = inferModelType(skinCanvas)
let earsCanvas
if (renderEars && playerCustomSkinImage) {

View file

@ -644,7 +644,6 @@ export async function connect (connectOptions: ConnectOptions) {
})
})
})
bot.loadPlugin(ping)
}
// socket setup actually can be delayed because of dns lookup
if (bot._client.socket) {
@ -662,6 +661,10 @@ export async function connect (connectOptions: ConnectOptions) {
} catch (err) {
handleError(err)
}
if (connectOptions.server) {
bot.loadPlugin(ping)
}
if (!bot) return
const p2pConnectTimeout = p2pMultiplayer ? setTimeout(() => { throw new UserError('Spawn timeout. There might be error on the other side, check console.') }, 20_000) : undefined

View file

@ -36,6 +36,7 @@ export const resetAppStatusState = () => {
export const lastConnectOptions = {
value: null as ConnectOptions | null
}
globalThis.lastConnectOptions = lastConnectOptions
const saveReconnectOptions = (options: ConnectOptions) => {
sessionStorage.setItem('reconnectOptions', JSON.stringify({

View file

@ -13,6 +13,10 @@
justify-items: center;
}
.container.websocket {
grid-template-columns: auto auto auto;
}
.iconRow {
display: block;
}

View file

@ -7,6 +7,7 @@ interface CssExports {
iconRow: string;
ping: string;
totalRow: string;
websocket: string;
}
declare const cssExports: CssExports;
export default cssExports;

View file

@ -1,4 +1,5 @@
import { useEffect, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { parseServerAddress } from '../parseServerAddress'
import { lastConnectOptions } from './AppStatusProvider'
import PixelartIcon, { pixelartIcons } from './PixelartIcon'
import styles from './NetworkStatus.module.css'
@ -7,22 +8,23 @@ export default () => {
const [proxyPing, setProxyPing] = useState<number | null>(null)
const [serverPing, setServerPing] = useState<number | null>(null)
useEffect(() => {
if (!lastConnectOptions.value?.proxy) return
const isWebSocket = useMemo(() => parseServerAddress(lastConnectOptions.value?.server).isWebSocket, [lastConnectOptions.value?.server])
const serverIp = useMemo(() => lastConnectOptions.value?.server, [])
let update = 0
useEffect(() => {
if (!serverIp) return
const updatePing = async () => {
const currentUpdate = ++update
const updateServerPing = async () => {
const ping = await bot.pingServer()
if (ping) setServerPing(ping)
}
const updateProxyPing = async () => {
const ping = await bot.pingProxy()
setProxyPing(ping)
if (!isWebSocket) {
const ping = await bot.pingProxy()
setProxyPing(ping)
}
}
try {
@ -37,28 +39,37 @@ export default () => {
return () => clearInterval(interval)
}, [])
if (!lastConnectOptions.value?.proxy) return null
if (!serverIp) return null
const { username } = bot.player
const { proxy: proxyUrl, server: serverIp } = lastConnectOptions.value
const { proxy: proxyUrl } = lastConnectOptions.value!
const pingTotal = serverPing
const ICON_SIZE = 18
return (
<div className={styles.container}>
<div className={`${styles.container} ${isWebSocket ? styles.websocket : ''}`}>
<PixelartIcon className={styles.iconRow} iconName={pixelartIcons.user} width={ICON_SIZE} />
<PixelartIcon className={`${styles.iconRow} ${styles.arrowRow}`} iconName={pixelartIcons['arrow-right']} width={16} />
<PixelartIcon className={styles.iconRow} iconName={pixelartIcons.server} width={ICON_SIZE} />
{!isWebSocket && (
<>
<PixelartIcon className={`${styles.iconRow} ${styles.arrowRow}`} iconName={pixelartIcons['arrow-right']} width={16} />
<PixelartIcon className={styles.iconRow} iconName={pixelartIcons.server} width={ICON_SIZE} />
</>
)}
<PixelartIcon className={`${styles.iconRow} ${styles.arrowRow}`} iconName={pixelartIcons['arrow-right']} width={16} />
<PixelartIcon className={styles.iconRow} iconName={pixelartIcons['list-box']} width={ICON_SIZE} />
<span className={styles.dataRow}>{username}</span>
<span className={`${styles.dataRow} ${styles.ping}`}>{proxyPing}ms</span>
<span className={styles.dataRow}>{proxyUrl}</span>
<span className={`${styles.dataRow} ${styles.ping}`}>{pingTotal ? pingTotal - (proxyPing ?? 0) : '...'}ms</span>
{!isWebSocket && (
<>
<span className={`${styles.dataRow} ${styles.ping}`}>{proxyPing}ms</span>
<span className={styles.dataRow}>{proxyUrl}</span>
</>
)}
<span className={`${styles.dataRow} ${styles.ping}`}>{isWebSocket ? (pingTotal || '?') : (pingTotal ? pingTotal - (proxyPing ?? 0) : '...')}ms</span>
<span className={styles.dataRow}>{serverIp}</span>
<span className={styles.totalRow}>Ping: {pingTotal}ms</span>
<span className={styles.totalRow}>Ping: {pingTotal || '?'}ms</span>
</div>
)
}