diff --git a/renderer/viewer/lib/entities.ts b/renderer/viewer/lib/entities.ts index 21802089..df7ea926 100644 --- a/renderer/viewer/lib/entities.ts +++ b/renderer/viewer/lib/entities.ts @@ -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) { diff --git a/src/index.ts b/src/index.ts index 74bf2f27..941b76c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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 diff --git a/src/react/AppStatusProvider.tsx b/src/react/AppStatusProvider.tsx index 955a2cc5..09fcb40a 100644 --- a/src/react/AppStatusProvider.tsx +++ b/src/react/AppStatusProvider.tsx @@ -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({ diff --git a/src/react/NetworkStatus.module.css b/src/react/NetworkStatus.module.css index 3752379e..372ea79f 100644 --- a/src/react/NetworkStatus.module.css +++ b/src/react/NetworkStatus.module.css @@ -13,6 +13,10 @@ justify-items: center; } +.container.websocket { + grid-template-columns: auto auto auto; +} + .iconRow { display: block; } diff --git a/src/react/NetworkStatus.module.css.d.ts b/src/react/NetworkStatus.module.css.d.ts index 13cb6950..bea85a4c 100644 --- a/src/react/NetworkStatus.module.css.d.ts +++ b/src/react/NetworkStatus.module.css.d.ts @@ -7,6 +7,7 @@ interface CssExports { iconRow: string; ping: string; totalRow: string; + websocket: string; } declare const cssExports: CssExports; export default cssExports; diff --git a/src/react/NetworkStatus.tsx b/src/react/NetworkStatus.tsx index 386e08cf..27d619d7 100644 --- a/src/react/NetworkStatus.tsx +++ b/src/react/NetworkStatus.tsx @@ -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(null) const [serverPing, setServerPing] = useState(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 ( -
+
- - + {!isWebSocket && ( + <> + + + + )} {username} - {proxyPing}ms - {proxyUrl} - {pingTotal ? pingTotal - (proxyPing ?? 0) : '...'}ms + {!isWebSocket && ( + <> + {proxyPing}ms + {proxyUrl} + + )} + {isWebSocket ? (pingTotal || '?') : (pingTotal ? pingTotal - (proxyPing ?? 0) : '...')}ms {serverIp} - Ping: {pingTotal}ms + Ping: {pingTotal || '?'}ms
) }