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)} />