diff --git a/esbuild.mjs b/esbuild.mjs index 4d423c87..1e8d6478 100644 --- a/esbuild.mjs +++ b/esbuild.mjs @@ -46,6 +46,9 @@ const buildOptions = { // using \n breaks sourcemaps! js: banner.join(';'), }, + external: [ + 'sharp' + ], alias: { events: 'events', // make explicit buffer: 'buffer', @@ -56,7 +59,8 @@ const buildOptions = { stream: 'stream-browserify', net: 'net-browserify', assert: 'assert', - dns: './src/dns.js' + dns: './src/dns.js', + // todo write advancedAliases plugin }, inject: [ './src/shims.js' diff --git a/experiments/ios-safe-area-bottom-bug.html b/experiments/ios-safe-area-bottom-bug.html new file mode 100644 index 00000000..53d867f5 --- /dev/null +++ b/experiments/ios-safe-area-bottom-bug.html @@ -0,0 +1,15 @@ + +
+ bottom: env(safe-area-inset-bottom) +
diff --git a/package.json b/package.json index 11324549..4bbeaf81 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "lint": "eslint \"{src,cypress}/**/*.{ts,js,jsx,tsx}\"", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build && node scripts/build.js moveStorybookFiles", - "start-experiments": "vite --config experiments/vite.config.ts", + "start-experiments": "vite --config experiments/vite.config.ts --host", "watch-other-workers": "echo NOT IMPLEMENTED", "watch-mesher": "node prismarine-viewer/buildMesherWorker.mjs -w", "run-playground": "run-p watch-mesher watch-other-workers playground-server watch-playground", @@ -72,6 +72,7 @@ "minecraft-assets": "^1.12.2", "minecraft-data": "3.65.0", "minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol", + "mineflayer-item-map-downloader": "github:zardoy/mineflayer-item-map-downloader", "mojangson": "^2.0.4", "net-browserify": "github:zardoy/prismarinejs-net-browserify", "node-gzip": "^1.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bf324472..beb0c0a9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -130,6 +130,9 @@ importers: minecraft-protocol: specifier: github:PrismarineJS/node-minecraft-protocol version: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/ccab9fb39681f3ebe0d264e2a3f833aa3c5a1ac7(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13) + mineflayer-item-map-downloader: + specifier: github:zardoy/mineflayer-item-map-downloader + version: https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7(encoding@0.1.13) mojangson: specifier: ^2.0.4 version: 2.0.4 @@ -6058,9 +6061,17 @@ packages: minecrafthawkeye@1.3.6: resolution: {integrity: sha512-SlRlorxQs6nNzMiiIQ5z47wzbAI27UaCdbRB82CE8jqj4C8m3Gqk5TlgN+PSThxx8EDPXySzd8Vk+/wNigAd5A==} + mineflayer-item-map-downloader@https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7: + resolution: {tarball: https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7} + version: 1.2.0 + mineflayer-pathfinder@2.4.4: resolution: {integrity: sha512-HAXakZrJRb1UC+5dv8EaDrqjW3ZnBnBk3nkb6x/YWyhHCUKn/E7VU0FO+UN9whuqPlkSaVumEdXJdydE6lSYxQ==} + mineflayer@4.20.1: + resolution: {integrity: sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==} + engines: {node: '>=18'} + mineflayer@https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/5a544cf2547a6e0f1f17786962d77a33c661c02f: resolution: {tarball: https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/5a544cf2547a6e0f1f17786962d77a33c661c02f} version: 4.20.1 @@ -15753,6 +15764,14 @@ snapshots: detect-collisions: 7.0.5 vec3: 0.1.8 + mineflayer-item-map-downloader@https://codeload.github.com/zardoy/mineflayer-item-map-downloader/tar.gz/642fd4f7023a98a96da4caf8f993f8e19361a1e7(encoding@0.1.13): + dependencies: + mineflayer: 4.20.1(encoding@0.1.13) + sharp: 0.30.7 + transitivePeerDependencies: + - encoding + - supports-color + mineflayer-pathfinder@2.4.4: dependencies: minecraft-data: 3.65.0 @@ -15763,6 +15782,29 @@ snapshots: prismarine-physics: 1.8.0 vec3: 0.1.8 + mineflayer@4.20.1(encoding@0.1.13): + dependencies: + minecraft-data: 3.65.0 + minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/ccab9fb39681f3ebe0d264e2a3f833aa3c5a1ac7(patch_hash=2uxevyasyasdavsxuehfavgkjq)(encoding@0.1.13) + prismarine-biome: 1.3.0(minecraft-data@3.65.0)(prismarine-registry@1.7.0) + prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/ada4ec3fdfbbc1cc20ab01d0e23f0718a77cc1a0 + prismarine-chat: 1.10.1 + prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/f32234a724a5c2482ffbaf85edc5e91c7ab9b38f(minecraft-data@3.65.0) + prismarine-entity: 2.3.1 + prismarine-item: 1.14.0 + prismarine-nbt: 2.5.0 + prismarine-physics: 1.8.0 + prismarine-recipe: 1.3.1(prismarine-registry@1.7.0) + prismarine-registry: 1.7.0 + prismarine-windows: 2.9.0 + prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/6ae6f009d38460de284f8c226c665f04cbad9465 + protodef: 1.15.0 + typed-emitter: 1.4.0 + vec3: 0.1.8 + transitivePeerDependencies: + - encoding + - supports-color + mineflayer@https://codeload.github.com/PrismarineJS/mineflayer/tar.gz/5a544cf2547a6e0f1f17786962d77a33c661c02f(encoding@0.1.13): dependencies: minecraft-data: 3.65.0 @@ -17408,7 +17450,7 @@ snapshots: detect-libc: 2.0.2 node-addon-api: 5.1.0 prebuild-install: 7.1.1 - semver: 7.5.4 + semver: 7.6.0 simple-get: 4.0.1 tar-fs: 2.1.1 tunnel-agent: 0.6.0 diff --git a/prismarine-viewer/examples/playground.ts b/prismarine-viewer/examples/playground.ts index 295cc47d..223fc6f2 100644 --- a/prismarine-viewer/examples/playground.ts +++ b/prismarine-viewer/examples/playground.ts @@ -138,6 +138,7 @@ async function main () { viewer.entities.onSkinUpdate = () => { viewer.render() } + viewer.world.mesherConfig.enableLighting = false viewer.listen(worldView) // Load chunks diff --git a/prismarine-viewer/viewer/lib/mesher/test/mesherTester.ts b/prismarine-viewer/viewer/lib/mesher/test/mesherTester.ts index a665db6b..6103a3d4 100644 --- a/prismarine-viewer/viewer/lib/mesher/test/mesherTester.ts +++ b/prismarine-viewer/viewer/lib/mesher/test/mesherTester.ts @@ -38,8 +38,22 @@ export const setup = (version, initialBlocks: [number[], string][]) => { } reload() + const getLights = () => { + return Object.fromEntries(getGeometry().faces.map(({ face, light }) => ([face, light * 15 - 2]))) + } + + const setLight = (x: number, y: number, z: number, val = 0) => { + // create columns first + chunk1.setBlockLight(pos.offset(x, y, z), 15) + chunk1.setSkyLight(pos.offset(x, y, z), 15) + chunk1.setBlockLight(pos.offset(x, y, z), val) + chunk1.setSkyLight(pos.offset(x, y, z), 0) + } + return { mesherWorld, + setLight, + getLights, getGeometry, pos, mcData, diff --git a/src/devtools.ts b/src/devtools.ts index 9477d8d9..4dbeb51d 100644 --- a/src/devtools.ts +++ b/src/devtools.ts @@ -23,3 +23,23 @@ Object.defineProperty(window, 'debugSceneChunks', { return (viewer.world as WorldRendererThree).getLoadedChunksRelative?.(bot.entity.position, true) }, }) + +window.len = (obj) => Object.keys(obj).length + +window.inspectPacket = (packetName, full = false) => { + const listener = (...args) => console.log('packet', packetName, full ? args : args[0]) + const attach = () => { + bot?.on(packetName, listener) + } + attach() + customEvents.on('mineflayerBotCreated', attach) + const returnobj = {} + Object.defineProperty(returnobj, 'detach', { + get () { + bot?.removeListener(packetName, listener) + customEvents.removeListener('mineflayerBotCreated', attach) + return true + }, + }) + return returnobj +} diff --git a/src/index.ts b/src/index.ts index f63e45d7..8dbc46cf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -128,6 +128,12 @@ if (isFirefox) { document.body.style.setProperty('--thin-if-firefox', 'thin') } +const isIphone = ua.getDevice().model === 'iPhone' // todo ipad? + +if (isIphone) { + document.documentElement.style.setProperty('--hud-bottom-max', '21px') // env-safe-aria-inset-bottom +} + // Create viewer const viewer: import('prismarine-viewer/viewer/lib/viewer').Viewer = new Viewer(renderer) window.viewer = viewer @@ -438,7 +444,9 @@ async function connect (connectOptions: ConnectOptions) { async versionSelectedHook (client) { await downloadMcData(client.version) setLoadingScreenStatus(initialLoadingText) - } + }, + 'mapDownloader-saveToFile': false, + // "mapDownloader-saveInternal": false, // do not save into memory, todo must be implemeneted as we do really care of ram }) as unknown as typeof __type_bot window.bot = bot earlySoundsMapCheck() @@ -539,6 +547,15 @@ async function connect (connectOptions: ConnectOptions) { window.Vec3 = Vec3 window.pathfinder = pathfinder + // patch mineflayer + // todo move to mineflayer + bot.inventory.on('updateSlot', (index) => { + if ((index as unknown as number) === bot.quickBarSlot + bot.inventory.hotbarStart) { + //@ts-expect-error + bot.emit('heldItemChanged') + } + }) + miscUiState.gameLoaded = true miscUiState.loadedServerIndex = connectOptions.serverIndex ?? '' customEvents.emit('gameLoaded') diff --git a/src/react/HeldMapUi.tsx b/src/react/HeldMapUi.tsx new file mode 100644 index 00000000..9187c98b --- /dev/null +++ b/src/react/HeldMapUi.tsx @@ -0,0 +1,55 @@ +import { useEffect, useState } from 'react' +import { mapDownloader } from 'mineflayer-item-map-downloader/' +import { setImageConverter } from 'mineflayer-item-map-downloader/lib/util' + +export default () => { + const [dataUrl, setDataUrl] = useState(null) // true means loading + + useEffect(() => { + bot.loadPlugin(mapDownloader) + + setImageConverter((buf: Uint8Array) => { + const canvas = document.createElement('canvas') + const ctx = canvas.getContext('2d')! + canvas.width = 128 + canvas.height = 128 + const imageData = ctx.createImageData(canvas.width, canvas.height) + imageData.data.set(buf) + ctx.putImageData(imageData, 0, 0) + // data url + return canvas.toDataURL('image/png') + }) + + // TODO delete maps! + const updateHeldMap = () => { + setDataUrl(null) + if (!bot.heldItem || !['filled_map', 'map'].includes(bot.heldItem.name)) return + // setDataUrl(true) + const mapNumber = (bot.heldItem?.nbt?.value as any)?.map?.value + // if (!mapNumber) return + setDataUrl(bot.mapDownloader.maps?.[mapNumber] as unknown as string) + } + + bot.on('heldItemChanged' as any, () => { + updateHeldMap() + }) + + bot.on('new_map', () => { + // total maps: Object.keys(bot.mapDownloader.maps).length + updateHeldMap() + }) + }, []) + + return dataUrl && dataUrl !== true ?
+ +
: null +} diff --git a/src/react/HotbarRenderApp.tsx b/src/react/HotbarRenderApp.tsx index 5b32e3cc..3b50f49b 100644 --- a/src/react/HotbarRenderApp.tsx +++ b/src/react/HotbarRenderApp.tsx @@ -211,7 +211,7 @@ export default () => { justifyContent: 'center', zIndex: hasModals ? 1 : 8, pointerEvents: 'none', - bottom: 'env(safe-area-inset-bottom)' + bottom: 'var(--hud-bottom-raw)' }} /> diff --git a/src/react/IndicatorEffects.tsx b/src/react/IndicatorEffects.tsx index b767cc23..2aafaa99 100644 --- a/src/react/IndicatorEffects.tsx +++ b/src/react/IndicatorEffects.tsx @@ -7,9 +7,9 @@ import './IndicatorEffects.css' function formatTime (seconds: number): string { if (seconds < 0) return '' const minutes = Math.floor(seconds / 60) - const remainingSeconds = seconds % 60 + const remainingSeconds = Math.floor(seconds % 60) const formattedMinutes = String(minutes).padStart(2, '0') - const formattedSeconds = String(remainingSeconds).padStart(2, '0') + const formattedSeconds = String(remainingSeconds) return `${formattedMinutes}:${formattedSeconds}` } @@ -32,10 +32,10 @@ const EffectBox = ({ image, time, level }: Pick{formattedTime} - ) : null } + ) : null} {level > 0 && level < 256 ? (
{level + 1}
- ) : null } + ) : null} } @@ -56,7 +56,7 @@ const indicatorIcons: Record = { readonlyFiles: 'file-off', } -export default ({ indicators, effects }: {indicators: typeof defaultIndicatorsState, effects: readonly EffectType[]}) => { +export default ({ indicators, effects }: { indicators: typeof defaultIndicatorsState, effects: readonly EffectType[] }) => { const effectsRef = useRef(effects) useEffect(() => { effectsRef.current = effects diff --git a/src/react/ServersList.tsx b/src/react/ServersList.tsx index 2fbbd349..f6b89452 100644 --- a/src/react/ServersList.tsx +++ b/src/react/ServersList.tsx @@ -60,14 +60,22 @@ export default ({ initialProxies, updateProxies: updateProxiesProp, joinServer, return { e.preventDefault() - joinServer(serverIp, { + let ip = serverIp + let version + const parts = ip.split(':') + if (parts.length > 1 && parts.at(-1)!.includes('.')) { + version = parts.at(-1)! + ip = parts.slice(0, -1).join(':') + } + joinServer(ip, { shouldSave: save, + versionOverride: version, }) }} >
{/* todo history */} - setServerIp(value)} /> + setServerIp(value)} />