From e84dc5924eb60279918875f202694825818d793c Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 13 Jun 2024 21:29:02 +0400 Subject: [PATCH 001/955] minimap storybook --- src/react/Minimap.stories.tsx | 17 +++++++++++++ src/react/Minimap.tsx | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/react/Minimap.stories.tsx create mode 100644 src/react/Minimap.tsx diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx new file mode 100644 index 00000000..854b27fb --- /dev/null +++ b/src/react/Minimap.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import Minimap from './Minimap' + +const meta: Meta = { + component: Minimap, + args: { + }, +} + +export default meta +type Story = StoryObj; + +export const Primary: Story = { + args: { + }, +} diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx new file mode 100644 index 00000000..9f333779 --- /dev/null +++ b/src/react/Minimap.tsx @@ -0,0 +1,47 @@ +import { useRef, useEffect } from 'react' + +export default () => { + const canvasRef = useRef(null) + + const drawMap = () => { + const canvas = canvasRef.current! + const ctx = canvas.getContext('2d')! + ctx.clearRect(0, 0, canvas.width, canvas.height) + + const centerX = canvas.width / 2 + const centerY = canvas.height / 2 + const radius = 25 + + ctx.beginPath() + + ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false) + + ctx.fillStyle = 'white' + ctx.fill() + + ctx.strokeStyle = '#000000' + ctx.lineWidth = 1 + ctx.stroke() + } + + useEffect(() => { + if (canvasRef.current) { + drawMap() + } + }, [canvasRef.current]) + + + return
+ + +
+} From d8aabaf99d8680688fb65c2ecd01cb27bb64f02f Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 13 Jun 2024 22:10:06 +0400 Subject: [PATCH 002/955] simple class for map drawing --- src/react/Minimap.tsx | 20 +++--------------- src/react/MinimapDrawer.ts | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 src/react/MinimapDrawer.ts diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9f333779..3ee177b6 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,27 +1,13 @@ import { useRef, useEffect } from 'react' +import { MinimapDrawer } from './MinimapDrawer' export default () => { const canvasRef = useRef(null) const drawMap = () => { const canvas = canvasRef.current! - const ctx = canvas.getContext('2d')! - ctx.clearRect(0, 0, canvas.width, canvas.height) - - const centerX = canvas.width / 2 - const centerY = canvas.height / 2 - const radius = 25 - - ctx.beginPath() - - ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false) - - ctx.fillStyle = 'white' - ctx.fill() - - ctx.strokeStyle = '#000000' - ctx.lineWidth = 1 - ctx.stroke() + const minimapDrawer = new MinimapDrawer(canvas) + minimapDrawer.draw() } useEffect(() => { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts new file mode 100644 index 00000000..8bb29f97 --- /dev/null +++ b/src/react/MinimapDrawer.ts @@ -0,0 +1,43 @@ + +export class MinimapDrawer { + centerX: number + centerY: number + radius: number + canvas: HTMLCanvasElement + ctx: CanvasRenderingContext2D + + constructor ( + canvas: HTMLCanvasElement, + centerX?: number, + centerY?: number, + radius?: number, + ) { + this.canvas = canvas + this.ctx = this.canvas.getContext('2d')! + this.centerX = centerX ?? this.canvas.width / 2 + this.centerY = centerY ?? this.canvas.height / 2 + this.radius = radius ?? 25 + } + + draw() { + this.ctx.clearRect( + this.centerX - this.radius, + this.centerY - this.radius, + this.canvas.width, + this.canvas.height + ) + this.ctx.strokeStyle = 'black' + + this.ctx.beginPath() + + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) + + this.ctx.fillStyle = 'white' + this.ctx.fill() + + this.ctx.strokeStyle = '#000000' + this.ctx.lineWidth = 1 + this.ctx.stroke() + + } +} From 2696a1e345d6355dae137f6de3b6a420c59e1148 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 13 Jun 2024 23:13:26 +0400 Subject: [PATCH 003/955] drawing map by pixel ex --- src/react/Minimap.stories.tsx | 14 ++++++++++-- src/react/Minimap.tsx | 4 ++-- src/react/MinimapDrawer.ts | 43 +++++++++++++++++++++++++++-------- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 854b27fb..5df1b26a 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -4,14 +4,24 @@ import Minimap from './Minimap' const meta: Meta = { component: Minimap, - args: { - }, } export default meta type Story = StoryObj; +let worldColors: string[][] = [] + +const mapSize = 50 +for (let i=0; i { +export default ({ worldColors }: { worldColors: string[][] }) => { const canvasRef = useRef(null) const drawMap = () => { const canvas = canvasRef.current! const minimapDrawer = new MinimapDrawer(canvas) - minimapDrawer.draw() + minimapDrawer.draw(worldColors) } useEffect(() => { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 8bb29f97..71f24a18 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,10 +1,10 @@ - export class MinimapDrawer { centerX: number centerY: number radius: number canvas: HTMLCanvasElement ctx: CanvasRenderingContext2D + worldColors: string[] constructor ( canvas: HTMLCanvasElement, @@ -19,25 +19,48 @@ export class MinimapDrawer { this.radius = radius ?? 25 } - draw() { + draw(worldColors?: string[][]) { this.ctx.clearRect( this.centerX - this.radius, this.centerY - this.radius, this.canvas.width, this.canvas.height ) - this.ctx.strokeStyle = 'black' - this.ctx.beginPath() + if (worldColors) { + this.updateWorldColors(worldColors) + } else { + this.ctx.strokeStyle = 'black' + this.ctx.beginPath() - this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) - this.ctx.fillStyle = 'white' - this.ctx.fill() + this.ctx.fillStyle = 'white' + this.ctx.fill() - this.ctx.strokeStyle = '#000000' - this.ctx.lineWidth = 1 - this.ctx.stroke() + this.ctx.strokeStyle = '#000000' + this.ctx.lineWidth = 1 + this.ctx.stroke() + } } + + updateWorldColors(worldColors: string[][]) { + const left = this.centerX - this.radius + const top = this.centerY - this.radius + + this.ctx.save() + + this.ctx.beginPath() + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI*2, true) + this.ctx.clip() + + for (let row=0; row Date: Thu, 13 Jun 2024 23:21:41 +0400 Subject: [PATCH 004/955] better scaling --- src/react/Minimap.stories.tsx | 2 +- src/react/MinimapDrawer.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 5df1b26a..8b63d391 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -11,7 +11,7 @@ type Story = StoryObj; let worldColors: string[][] = [] -const mapSize = 50 +const mapSize = 10 for (let i=0; i Date: Fri, 14 Jun 2024 12:45:37 +0400 Subject: [PATCH 005/955] fixed eslint in MinimapDrawer --- src/react/Minimap.stories.tsx | 6 +++--- src/react/MinimapDrawer.ts | 20 ++++++++------------ src/react/MinimapProvider.tsx | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 src/react/MinimapProvider.tsx diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 8b63d391..25ea6507 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -9,12 +9,12 @@ const meta: Meta = { export default meta type Story = StoryObj; -let worldColors: string[][] = [] +const worldColors: string[][] = [] const mapSize = 10 -for (let i=0; i { + const [worldColors, setWorldColors] = useState([]) + + useEffect(() => { + const newColors = [] as string[][] + + + }, []) + + return
+ +
+} From 0f78c74146b4e11da99037350068b731fcc44974 Mon Sep 17 00:00:00 2001 From: gguio Date: Sat, 15 Jun 2024 13:37:35 +0400 Subject: [PATCH 006/955] map draws and updates. Not optimized --- src/react/Minimap.tsx | 2 +- src/react/MinimapProvider.tsx | 35 ++++++++++++++++++++++++++++++++++- src/reactUi.tsx | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 0e6aee42..7590862a 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -14,7 +14,7 @@ export default ({ worldColors }: { worldColors: string[][] }) => { if (canvasRef.current) { drawMap() } - }, [canvasRef.current]) + }, [canvasRef.current, worldColors]) return
{ const [worldColors, setWorldColors] = useState([]) - useEffect(() => { + const getHighestBlock = (x: number, z: number) => { + let block = null as import('prismarine-block').Block | null + let height = (bot.game as any).height + const airBlocks = ['air', 'cave_air', 'void_air'] + do { + block = bot.world.getBlock(new Vec3(x, height, z)) + height -= 1 + } while (airBlocks.includes(block?.name ?? '')) + return height + } + + const drawMap = () => { + const { colors } = BlockData const newColors = [] as string[][] + const mapSize = 24 + for (let i = 0; i < mapSize; i += 1) { + newColors[i] = [] as string[] + for (let j = 0; j < mapSize; j += 1) { + const x = bot.entity.position.x - mapSize / 2 + i + const z = bot.entity.position.z - mapSize / 2 + j + const y = getHighestBlock(x, z) + const blockName = bot.world.getBlock(new Vec3(x, y, z))?.name + newColors[i][j] = blockName ? colors[blockName] ?? 'white' : 'white' + } + } + setWorldColors([...newColors]) + } + useEffect(() => { + bot.on('move', drawMap) + + return () => { + bot.off('move', drawMap) + } }, []) return
diff --git a/src/reactUi.tsx b/src/reactUi.tsx index 8a9cc32c..7a80d55e 100644 --- a/src/reactUi.tsx +++ b/src/reactUi.tsx @@ -19,6 +19,7 @@ import ScoreboardProvider from './react/ScoreboardProvider' import SignEditorProvider from './react/SignEditorProvider' import IndicatorEffectsProvider from './react/IndicatorEffectsProvider' import PlayerListOverlayProvider from './react/PlayerListOverlayProvider' +import MinimapProvider from './react/MinimapProvider' import HudBarsProvider from './react/HudBarsProvider' import XPBarProvider from './react/XPBarProvider' import DebugOverlay from './react/DebugOverlay' @@ -114,6 +115,7 @@ const InGameUi = () => { +
From 362d87c320293807d95a596f61f7e0c5d1a9a0a0 Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 17 Jun 2024 12:20:43 +0400 Subject: [PATCH 007/955] stable --- src/react/MinimapProvider.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index c0193e21..237122dd 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -15,25 +15,24 @@ export default () => { block = bot.world.getBlock(new Vec3(x, height, z)) height -= 1 } while (airBlocks.includes(block?.name ?? '')) - return height + return block.name } const drawMap = () => { const { colors } = BlockData const newColors = [] as string[][] - const mapSize = 24 + const mapSize = 50 for (let i = 0; i < mapSize; i += 1) { newColors[i] = [] as string[] for (let j = 0; j < mapSize; j += 1) { const x = bot.entity.position.x - mapSize / 2 + i const z = bot.entity.position.z - mapSize / 2 + j - const y = getHighestBlock(x, z) - const blockName = bot.world.getBlock(new Vec3(x, y, z))?.name + const blockName = getHighestBlock(x, z) newColors[i][j] = blockName ? colors[blockName] ?? 'white' : 'white' } } - setWorldColors([...newColors]) + setWorldColors(newColors) } useEffect(() => { From 73cf00b1b4c399999cc7fe720d2064b75f4152dd Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 17 Jun 2024 13:37:27 +0400 Subject: [PATCH 008/955] a little faster drawing. Still lags --- src/react/Minimap.tsx | 25 ++++++++++----- src/react/MinimapDrawer.ts | 57 +++++++++++++++++++++++++++-------- src/react/MinimapProvider.tsx | 39 +----------------------- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 7590862a..1ddcef0e 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,20 +1,31 @@ import { useRef, useEffect } from 'react' import { MinimapDrawer } from './MinimapDrawer' -export default ({ worldColors }: { worldColors: string[][] }) => { +export default () => { + const canvasTick = useRef(0) const canvasRef = useRef(null) + const drawerRef = useRef(null) - const drawMap = () => { - const canvas = canvasRef.current! - const minimapDrawer = new MinimapDrawer(canvas) - minimapDrawer.draw(worldColors) + function updateMap () { + if (drawerRef.current && canvasTick.current % 10 === 0) { + drawerRef.current.draw(bot) + } + canvasTick.current += 1 } useEffect(() => { if (canvasRef.current) { - drawMap() + drawerRef.current = new MinimapDrawer(canvasRef.current) } - }, [canvasRef.current, worldColors]) + }, [canvasRef.current]) + + useEffect(() => { + bot.on('move', updateMap) + + return () => { + bot.off('move', updateMap) + } + }, []) return
& { + world: Omit & { + getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null + } + _client: Omit & { + write: typeof import('../generatedClientPackets').clientWrite + on: typeof import('../generatedServerPackets').clientOn + } +} + export class MinimapDrawer { centerX: number centerY: number + mapSize: number radius: number ctx: CanvasRenderingContext2D @@ -9,15 +24,17 @@ export class MinimapDrawer { centerX?: number, centerY?: number, radius?: number, + mapSize?: number ) { this.canvas = canvas this.ctx = this.canvas.getContext('2d')! this.centerX = centerX ?? this.canvas.width / 2 this.centerY = centerY ?? this.canvas.height / 2 this.radius = radius ?? 25 + this.mapSize = mapSize ?? this.radius * 2 } - draw (worldColors?: string[][]) { + draw (bot: BotType | undefined) { this.ctx.clearRect( this.centerX - this.radius, this.centerY - this.radius, @@ -25,8 +42,8 @@ export class MinimapDrawer { this.radius * 2 ) - if (worldColors) { - this.updateWorldColors(worldColors) + if (bot) { + this.updateWorldColors(bot) } else { this.ctx.strokeStyle = 'black' this.ctx.beginPath() @@ -42,9 +59,10 @@ export class MinimapDrawer { } } - updateWorldColors (worldColors: string[][]) { + updateWorldColors (bot: BotType) { const left = this.centerX - this.radius const top = this.centerY - this.radius + const mapPixel = Math.floor(this.radius * 2 / this.mapSize) this.ctx.save() @@ -52,18 +70,31 @@ export class MinimapDrawer { this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) this.ctx.clip() - for (let row = 0; row < worldColors.length; row += 1) { - for (let col = 0; col < worldColors[row].length; col += 1) { - this.ctx.fillStyle = worldColors[row][col] - const rectWidth = Math.floor(this.radius * 2 / worldColors[row].length) - const rectHeight = Math.floor(this.radius * 2 / worldColors.length) + for (let row = 0; row < this.mapSize; row += 1) { + for (let col = 0; col < this.mapSize; col += 1) { + this.ctx.fillStyle = this.getHighestBlockColor( + bot, + bot.entity.position.x - this.mapSize / 2 + row, + bot.entity.position.z - this.mapSize / 2 + col + ) this.ctx.fillRect( - left + rectWidth * col, - top + rectHeight * row, - rectWidth, - rectHeight + left + mapPixel * col, + top + mapPixel * row, + mapPixel, + mapPixel ) } } } + + getHighestBlockColor (bot: BotType, x: number, z: number) { + let block = null as import('prismarine-block').Block | null + let { height } = (bot.game as any) + const airBlocks = new Set(['air', 'cave_air', 'void_air']) + do { + block = bot.world.getBlock(new Vec3(x, height, z)) + height -= 1 + } while (airBlocks.has(block?.name ?? '')) + return BlockData.colors[block?.name ?? ''] ?? 'white' + } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 237122dd..d189337a 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -5,45 +5,8 @@ import Minimap from './Minimap' export default () => { - const [worldColors, setWorldColors] = useState([]) - - const getHighestBlock = (x: number, z: number) => { - let block = null as import('prismarine-block').Block | null - let height = (bot.game as any).height - const airBlocks = ['air', 'cave_air', 'void_air'] - do { - block = bot.world.getBlock(new Vec3(x, height, z)) - height -= 1 - } while (airBlocks.includes(block?.name ?? '')) - return block.name - } - - const drawMap = () => { - const { colors } = BlockData - const newColors = [] as string[][] - - const mapSize = 50 - for (let i = 0; i < mapSize; i += 1) { - newColors[i] = [] as string[] - for (let j = 0; j < mapSize; j += 1) { - const x = bot.entity.position.x - mapSize / 2 + i - const z = bot.entity.position.z - mapSize / 2 + j - const blockName = getHighestBlock(x, z) - newColors[i][j] = blockName ? colors[blockName] ?? 'white' : 'white' - } - } - setWorldColors(newColors) - } - - useEffect(() => { - bot.on('move', drawMap) - - return () => { - bot.off('move', drawMap) - } - }, []) return
- +
} From 55ce44585f6f65af1eb4d4938dff925dd6f6026b Mon Sep 17 00:00:00 2001 From: gguio Date: Mon, 17 Jun 2024 19:59:40 +0400 Subject: [PATCH 009/955] cacha added. Didnt change anything, refactoring required --- src/react/Minimap.tsx | 3 ++ src/react/MinimapDrawer.ts | 63 ++++++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 1ddcef0e..7f46c349 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -9,6 +9,9 @@ export default () => { function updateMap () { if (drawerRef.current && canvasTick.current % 10 === 0) { drawerRef.current.draw(bot) + if (canvasTick.current % 300 === 0) { + drawerRef.current.clearCache(bot.entity.position.x, bot.entity.position.z) + } } canvasTick.current += 1 } diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 013421c6..a5f12a60 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,15 +1,17 @@ import { Vec3 } from 'vec3' +import { Position } from 'source-map-js' +import { underive } from 'valtio/utils' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' type BotType = Omit & { - world: Omit & { - getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null - } - _client: Omit & { - write: typeof import('../generatedClientPackets').clientWrite - on: typeof import('../generatedServerPackets').clientOn - } + world: Omit & { + getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null + } + _client: Omit & { + write: typeof import('../generatedClientPackets').clientWrite + on: typeof import('../generatedServerPackets').clientOn + } } export class MinimapDrawer { @@ -17,7 +19,8 @@ export class MinimapDrawer { centerY: number mapSize: number radius: number - ctx: CanvasRenderingContext2D + ctx: CanvasRenderingContext2D + worldColors: { [key: string]: string } constructor ( private readonly canvas: HTMLCanvasElement, @@ -28,6 +31,7 @@ export class MinimapDrawer { ) { this.canvas = canvas this.ctx = this.canvas.getContext('2d')! + this.ctx.imageSmoothingEnabled = false this.centerX = centerX ?? this.canvas.width / 2 this.centerY = centerY ?? this.canvas.height / 2 this.radius = radius ?? 25 @@ -36,9 +40,9 @@ export class MinimapDrawer { draw (bot: BotType | undefined) { this.ctx.clearRect( - this.centerX - this.radius, - this.centerY - this.radius, - this.radius * 2, + this.centerX - this.radius, + this.centerY - this.radius, + this.radius * 2, this.radius * 2 ) @@ -67,20 +71,20 @@ export class MinimapDrawer { this.ctx.save() this.ctx.beginPath() - this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) + this.ctx.arc(this.centerX, this.centerY, this.radius, 0, Math.PI * 2, true) this.ctx.clip() for (let row = 0; row < this.mapSize; row += 1) { for (let col = 0; col < this.mapSize; col += 1) { this.ctx.fillStyle = this.getHighestBlockColor( - bot, - bot.entity.position.x - this.mapSize / 2 + row, + bot, + bot.entity.position.x - this.mapSize / 2 + row, bot.entity.position.z - this.mapSize / 2 + col ) this.ctx.fillRect( - left + mapPixel * col, - top + mapPixel * row, - mapPixel, + left + mapPixel * col, + top + mapPixel * row, + mapPixel, mapPixel ) } @@ -88,13 +92,32 @@ export class MinimapDrawer { } getHighestBlockColor (bot: BotType, x: number, z: number) { - let block = null as import('prismarine-block').Block | null + const key = `${x},${z}` + if (Object.keys(this.worldColors).includes(key)) { + return this.worldColors[key] + } + let block = null as import('prismarine-block').Block | null let { height } = (bot.game as any) const airBlocks = new Set(['air', 'cave_air', 'void_air']) do { block = bot.world.getBlock(new Vec3(x, height, z)) height -= 1 } while (airBlocks.has(block?.name ?? '')) - return BlockData.colors[block?.name ?? ''] ?? 'white' - } + const color = BlockData.colors[block?.name ?? ''] ?? 'white' + this.worldColors[key] = color + return color + } + + getDistance (x1: number, z1: number, x2: number, z2: number): number { + return Math.hypot((x2 - x1), (z2 - z1)) + } + + clearCache (currX: number, currZ: number) { + for (const key of Object.keys(this.worldColors)) { + const [x, z] = key.split(',').map(Number) + if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { + delete this.worldColors[`${x},${z}`] + } + } + } } From dfd1cb00283bc0028cb458be80f2dffbd5f6db97 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 18 Jun 2024 13:33:23 +0400 Subject: [PATCH 010/955] build doesnt work right --- src/react/Minimap.tsx | 4 ++++ src/react/MinimapDrawer.ts | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 7f46c349..291fdc4a 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -7,7 +7,9 @@ export default () => { const drawerRef = useRef(null) function updateMap () { + console.log('test') if (drawerRef.current && canvasTick.current % 10 === 0) { + console.log(drawerRef.current.worldColors) drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { drawerRef.current.clearCache(bot.entity.position.x, bot.entity.position.z) @@ -23,9 +25,11 @@ export default () => { }, [canvasRef.current]) useEffect(() => { + console.log('set update') bot.on('move', updateMap) return () => { + console.log('delete update') bot.off('move', updateMap) } }, []) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index a5f12a60..e96d177d 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -48,6 +48,7 @@ export class MinimapDrawer { if (bot) { this.updateWorldColors(bot) + console.log(this.worldColors) } else { this.ctx.strokeStyle = 'black' this.ctx.beginPath() @@ -93,7 +94,8 @@ export class MinimapDrawer { getHighestBlockColor (bot: BotType, x: number, z: number) { const key = `${x},${z}` - if (Object.keys(this.worldColors).includes(key)) { + if (this.worldColors[key]) { + console.log('using cashed value') return this.worldColors[key] } let block = null as import('prismarine-block').Block | null @@ -113,7 +115,7 @@ export class MinimapDrawer { } clearCache (currX: number, currZ: number) { - for (const key of Object.keys(this.worldColors)) { + for (const key in this.worldColors) { const [x, z] = key.split(',').map(Number) if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { delete this.worldColors[`${x},${z}`] From f6194e462826348893cc282c79b6336f022bf322 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Tue, 18 Jun 2024 15:22:00 +0300 Subject: [PATCH 011/955] fix and cleanup code --- src/react/MinimapDrawer.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index e96d177d..32c231df 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,9 +1,9 @@ import { Vec3 } from 'vec3' import { Position } from 'source-map-js' -import { underive } from 'valtio/utils' +import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' - type BotType = Omit & { world: Omit & { getBlock: (pos: import('vec3').Vec3) => import('prismarine-block').Block | null @@ -14,15 +14,26 @@ type BotType = Omit & { } } +interface DrawerAdapter extends TypedEventEmitter<{ + updateBlockColor: (pos: Position) => void + updatePlayerPosition: () => void + updateWarps: () => void +}> { + getHighestBlockColor: (x: number, z: number) => string + playerPosition: Position + warps: WorldWarp + setWarp: (name: string, pos: Position, rotation: Position, color: string, disabled: boolean) => void +} + export class MinimapDrawer { centerX: number centerY: number mapSize: number radius: number ctx: CanvasRenderingContext2D - worldColors: { [key: string]: string } + worldColors: { [key: string]: string } = {} - constructor ( + constructor( private readonly canvas: HTMLCanvasElement, centerX?: number, centerY?: number, @@ -48,7 +59,6 @@ export class MinimapDrawer { if (bot) { this.updateWorldColors(bot) - console.log(this.worldColors) } else { this.ctx.strokeStyle = 'black' this.ctx.beginPath() @@ -95,7 +105,6 @@ export class MinimapDrawer { getHighestBlockColor (bot: BotType, x: number, z: number) { const key = `${x},${z}` if (this.worldColors[key]) { - console.log('using cashed value') return this.worldColors[key] } let block = null as import('prismarine-block').Block | null From ce951fe6ddcb2d1dd273af96c4a44e411da671d0 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Tue, 18 Jun 2024 19:55:58 +0300 Subject: [PATCH 012/955] update squid, fix lint --- package.json | 2 +- pnpm-lock.yaml | 11 ++++++----- src/react/Minimap.tsx | 6 +++--- src/react/MinimapDrawer.ts | 9 +++++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 56e3cfdd..3369e91c 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "esbuild-plugin-polyfill-node": "^0.3.0", "express": "^4.18.2", "filesize": "^10.0.12", - "flying-squid": "npm:@zardoy/flying-squid@^0.0.29", + "flying-squid": "npm:@zardoy/flying-squid@^0.0.30", "fs-extra": "^11.1.1", "google-drive-browserfs": "github:zardoy/browserfs#google-drive", "iconify-icon": "^1.0.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e1ab099..fa8ba5e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -104,8 +104,8 @@ importers: specifier: ^10.0.12 version: 10.0.12 flying-squid: - specifier: npm:@zardoy/flying-squid@^0.0.29 - version: '@zardoy/flying-squid@0.0.29(encoding@0.1.13)' + specifier: npm:@zardoy/flying-squid@^0.0.30 + version: '@zardoy/flying-squid@0.0.30(encoding@0.1.13)' fs-extra: specifier: ^11.1.1 version: 11.1.1 @@ -3075,8 +3075,8 @@ packages: resolution: {integrity: sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==} engines: {node: '>=12 <14 || 14.2 - 14.9 || >14.10.0'} - '@zardoy/flying-squid@0.0.29': - resolution: {integrity: sha512-E5Nk1gMeH+fAHM5aJY8kIxjBS/zuPtPD6QPeZg+laPV5H58Jx3Et17clF1zC9MT2wyFQ5wi5uTnfdGBTpSEqHw==} + '@zardoy/flying-squid@0.0.30': + resolution: {integrity: sha512-jQ9GQUKR0nRmUxERLB1sOIkQRc1PdSxqHVPe+BB80ELx2P7R1sVcG8sGMQ2BBdH2vRYBg+HD3r1vKudqYSd1Ww==} engines: {node: '>=8'} hasBin: true @@ -11971,7 +11971,7 @@ snapshots: '@types/emscripten': 1.39.8 tslib: 1.14.1 - '@zardoy/flying-squid@0.0.29(encoding@0.1.13)': + '@zardoy/flying-squid@0.0.30(encoding@0.1.13)': dependencies: '@tootallnate/once': 2.0.0 change-case: 4.1.2 @@ -11997,6 +11997,7 @@ snapshots: random-seed: 0.3.0 range: 0.0.3 readline: 1.3.0 + sanitize-filename: 1.6.3 typed-emitter: 1.4.0 uuid-1345: 1.0.2 vec3: 0.1.8 diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 291fdc4a..a017936c 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -3,7 +3,7 @@ import { MinimapDrawer } from './MinimapDrawer' export default () => { const canvasTick = useRef(0) - const canvasRef = useRef(null) + const canvasRef = useRef(null) const drawerRef = useRef(null) function updateMap () { @@ -12,7 +12,7 @@ export default () => { console.log(drawerRef.current.worldColors) drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { - drawerRef.current.clearCache(bot.entity.position.x, bot.entity.position.z) + drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) } } canvasTick.current += 1 @@ -35,7 +35,7 @@ export default () => { }, []) - return
string playerPosition: Position warps: WorldWarp - setWarp: (name: string, pos: Position, rotation: Position, color: string, disabled: boolean) => void + setWarp: (name: string, pos: Position, rotation: Position, dimension: string, color: string, disabled: boolean) => void } export class MinimapDrawer { @@ -33,7 +33,7 @@ export class MinimapDrawer { ctx: CanvasRenderingContext2D worldColors: { [key: string]: string } = {} - constructor( + constructor ( private readonly canvas: HTMLCanvasElement, centerX?: number, centerY?: number, @@ -123,10 +123,11 @@ export class MinimapDrawer { return Math.hypot((x2 - x1), (z2 - z1)) } - clearCache (currX: number, currZ: number) { - for (const key in this.worldColors) { + deleteOldWorldColors (currX: number, currZ: number) { + for (const key of Object.keys(this.worldColors)) { const [x, z] = key.split(',').map(Number) if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete this.worldColors[`${x},${z}`] } } From 326ef49c7e791b3f531d8c622f9428bd68a1ce2e Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 20 Jun 2024 17:48:36 +0400 Subject: [PATCH 013/955] fix cache --- src/react/Minimap.tsx | 2 +- src/react/MinimapDrawer.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index a017936c..610befa9 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -7,12 +7,12 @@ export default () => { const drawerRef = useRef(null) function updateMap () { - console.log('test') if (drawerRef.current && canvasTick.current % 10 === 0) { console.log(drawerRef.current.worldColors) drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) + console.log(drawerRef.current.worldColors) } } canvasTick.current += 1 diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 49f0241a..bba5e107 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -103,7 +103,9 @@ export class MinimapDrawer { } getHighestBlockColor (bot: BotType, x: number, z: number) { - const key = `${x},${z}` + const roundX = Math.floor(x) + const roundZ = Math.floor(z) + const key = `${roundX},${roundZ}` if (this.worldColors[key]) { return this.worldColors[key] } From 6ebe049ad1d85183a64aa69f42b199a69f11eff7 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 20 Jun 2024 18:24:12 +0400 Subject: [PATCH 014/955] full map container --- src/react/Minimap.tsx | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 610befa9..67d13303 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,41 +1,52 @@ -import { useRef, useEffect } from 'react' +import { useRef, useEffect, useState } from 'react' import { MinimapDrawer } from './MinimapDrawer' export default () => { + const [fullMapOpened, setFullMapOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) function updateMap () { - if (drawerRef.current && canvasTick.current % 10 === 0) { - console.log(drawerRef.current.worldColors) + if (drawerRef.current && canvasTick.current % 2 === 0) { drawerRef.current.draw(bot) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) - console.log(drawerRef.current.worldColors) } } canvasTick.current += 1 } + const openFullMap = () => { + setFullMapOpened(true) + } + useEffect(() => { - if (canvasRef.current) { + if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current) } }, [canvasRef.current]) useEffect(() => { - console.log('set update') bot.on('move', updateMap) return () => { - console.log('delete update') bot.off('move', updateMap) } }, []) + return fullMapOpened ?
+ - return
:
Date: Thu, 20 Jun 2024 19:16:56 +0400 Subject: [PATCH 015/955] fix for weired bug with undo button in Keybindings screen --- src/react/KeybindingsScreen.module.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/react/KeybindingsScreen.module.css b/src/react/KeybindingsScreen.module.css index e8a9f69b..102974ce 100644 --- a/src/react/KeybindingsScreen.module.css +++ b/src/react/KeybindingsScreen.module.css @@ -49,6 +49,7 @@ .undo-keyboard, .undo-gamepad { aspect-ratio: 1; + min-width: 20px; } .button { From 3b91a17f90c87926c231d609148e8909704ac58e Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 12:09:52 +0400 Subject: [PATCH 016/955] toggle command --- src/controls.ts | 17 +++++++++-------- src/react/Minimap.tsx | 10 ++++++++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/controls.ts b/src/controls.ts index a3a22029..0469a0b0 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -51,6 +51,7 @@ export const contro = new ControMax({ }, ui: { back: [null/* 'Escape' */, 'B'], + toggleMap: ['KeyM'], leftClick: [null, 'A'], rightClick: [null, 'Y'], speedupCursor: [null, 'Left Stick'], @@ -75,12 +76,12 @@ export const contro = new ControMax({ }, { defaultControlOptions: controlOptions, target: document, - captureEvents () { + captureEvents() { return true }, storeProvider: { load: () => customKeymaps, - save () { }, + save() { }, }, gamepadPollingInterval: 10 }) @@ -153,10 +154,10 @@ let lastCommandTrigger = null as { command: string, time: number } | null const secondActionActivationTimeout = 300 const secondActionCommands = { - 'general.jump' () { + 'general.jump'() { toggleFly() }, - 'general.forward' () { + 'general.forward'() { setSprinting(true) } } @@ -292,7 +293,7 @@ const alwaysPressedHandledCommand = (command: Command) => { } } -function cycleHotbarSlot (dir: 1 | -1) { +function cycleHotbarSlot(dir: 1 | -1) { const newHotbarSlot = (bot.quickBarSlot + dir + 9) % 9 bot.setQuickBarSlot(newHotbarSlot) } @@ -418,7 +419,7 @@ contro.on('release', ({ command }) => { export const f3Keybinds = [ { key: 'KeyA', - action () { + action() { //@ts-expect-error const loadedChunks = Object.entries(worldView.loadedChunks).filter(([, v]) => v).map(([key]) => key.split(',').map(Number)) for (const [x, z] of loadedChunks) { @@ -440,7 +441,7 @@ export const f3Keybinds = [ }, { key: 'KeyG', - action () { + action() { options.showChunkBorders = !options.showChunkBorders viewer.world.updateShowChunksBorder(options.showChunkBorders) }, @@ -448,7 +449,7 @@ export const f3Keybinds = [ }, { key: 'KeyT', - async action () { + async action() { // waypoints const widgetNames = widgets.map(widget => widget.name) const widget = await showOptionsModal('Open Widget', widgetNames) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 67d13303..c1740a60 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,5 +1,6 @@ import { useRef, useEffect, useState } from 'react' import { MinimapDrawer } from './MinimapDrawer' +import { contro } from '../controls' export default () => { const [fullMapOpened, setFullMapOpened] = useState(false) @@ -17,10 +18,11 @@ export default () => { canvasTick.current += 1 } - const openFullMap = () => { - setFullMapOpened(true) + const toggleFullMap = ({ command }) => { + if (command === 'ui.toggleMap') setFullMapOpened(prev => !prev) } + useEffect(() => { if (canvasRef.current && !drawerRef.current) { drawerRef.current = new MinimapDrawer(canvasRef.current) @@ -30,8 +32,11 @@ export default () => { useEffect(() => { bot.on('move', updateMap) + contro.on('trigger', toggleFullMap) + return () => { bot.off('move', updateMap) + contro.off('', toggleFullMap) } }, []) @@ -41,6 +46,7 @@ export default () => { inset: '0px', display: 'flex', justifyContent: 'center', + alignItems: 'center', border: '2px solid red' }} > From 33302c06aa9a8a1ec11c254435f6c3ccca457f42 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 13:48:27 +0400 Subject: [PATCH 017/955] toggle full map --- src/controls.ts | 16 ++++++++-------- src/react/Minimap.tsx | 22 +++++++++++++++++----- src/react/MinimapDrawer.ts | 22 +++++++++++++++------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/controls.ts b/src/controls.ts index 0469a0b0..8df3f209 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -76,12 +76,12 @@ export const contro = new ControMax({ }, { defaultControlOptions: controlOptions, target: document, - captureEvents() { + captureEvents () { return true }, storeProvider: { load: () => customKeymaps, - save() { }, + save () { }, }, gamepadPollingInterval: 10 }) @@ -154,10 +154,10 @@ let lastCommandTrigger = null as { command: string, time: number } | null const secondActionActivationTimeout = 300 const secondActionCommands = { - 'general.jump'() { + 'general.jump' () { toggleFly() }, - 'general.forward'() { + 'general.forward' () { setSprinting(true) } } @@ -293,7 +293,7 @@ const alwaysPressedHandledCommand = (command: Command) => { } } -function cycleHotbarSlot(dir: 1 | -1) { +function cycleHotbarSlot (dir: 1 | -1) { const newHotbarSlot = (bot.quickBarSlot + dir + 9) % 9 bot.setQuickBarSlot(newHotbarSlot) } @@ -419,7 +419,7 @@ contro.on('release', ({ command }) => { export const f3Keybinds = [ { key: 'KeyA', - action() { + action () { //@ts-expect-error const loadedChunks = Object.entries(worldView.loadedChunks).filter(([, v]) => v).map(([key]) => key.split(',').map(Number)) for (const [x, z] of loadedChunks) { @@ -441,7 +441,7 @@ export const f3Keybinds = [ }, { key: 'KeyG', - action() { + action () { options.showChunkBorders = !options.showChunkBorders viewer.world.updateShowChunksBorder(options.showChunkBorders) }, @@ -449,7 +449,7 @@ export const f3Keybinds = [ }, { key: 'KeyT', - async action() { + async action () { // waypoints const widgetNames = widgets.map(widget => widget.name) const widget = await showOptionsModal('Open Widget', widgetNames) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index c1740a60..39577ffc 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,6 +1,6 @@ import { useRef, useEffect, useState } from 'react' -import { MinimapDrawer } from './MinimapDrawer' import { contro } from '../controls' +import { MinimapDrawer } from './MinimapDrawer' export default () => { const [fullMapOpened, setFullMapOpened] = useState(false) @@ -25,9 +25,13 @@ export default () => { useEffect(() => { if (canvasRef.current && !drawerRef.current) { + console.log('creating canvas') drawerRef.current = new MinimapDrawer(canvasRef.current) + } else if (canvasRef.current && drawerRef.current) { + console.log('updating canvas') + drawerRef.current.canvas = canvasRef.current } - }, [canvasRef.current]) + }, [canvasRef.current, fullMapOpened]) useEffect(() => { bot.on('move', updateMap) @@ -36,7 +40,7 @@ export default () => { return () => { bot.off('move', updateMap) - contro.off('', toggleFullMap) + contro.off('trigger', toggleFullMap) } }, []) @@ -47,10 +51,18 @@ export default () => { display: 'flex', justifyContent: 'center', alignItems: 'center', - border: '2px solid red' + border: '2px solid red', + backgroundColor: 'rgba(0, 0, 0, 0.4)' }} > - +
:
Date: Fri, 21 Jun 2024 13:49:41 +0400 Subject: [PATCH 018/955] small clean up --- src/react/Minimap.tsx | 2 -- src/react/MinimapDrawer.ts | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 39577ffc..9a22d3ef 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -25,10 +25,8 @@ export default () => { useEffect(() => { if (canvasRef.current && !drawerRef.current) { - console.log('creating canvas') drawerRef.current = new MinimapDrawer(canvasRef.current) } else if (canvasRef.current && drawerRef.current) { - console.log('updating canvas') drawerRef.current.canvas = canvasRef.current } }, [canvasRef.current, fullMapOpened]) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 924a3810..7b2ba296 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -36,9 +36,6 @@ export class MinimapDrawer { constructor ( canvas: HTMLCanvasElement, - centerX?: number, - centerY?: number, - mapSize?: number ) { this.canvas = canvas } From 7901a3a041cb7499ae0a047ccb8e0eb72f957707 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 15:10:36 +0400 Subject: [PATCH 019/955] adapter implementation --- src/react/Minimap.stories.tsx | 34 ++++++++-------- src/react/Minimap.tsx | 27 +++++++----- src/react/MinimapDrawer.ts | 77 +++++++++++++++++++---------------- src/react/MinimapProvider.tsx | 72 +++++++++++++++++++++++++++++++- 4 files changed, 144 insertions(+), 66 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 25ea6507..8fd94c1c 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -7,21 +7,21 @@ const meta: Meta = { } export default meta -type Story = StoryObj; +// type Story = StoryObj; -const worldColors: string[][] = [] - -const mapSize = 10 -for (let i = 0; i < mapSize; i += 1) { - worldColors[i] = [] as string[] - for (let j = 0; j < mapSize; j += 1) { - const randColor = Math.floor(Math.random() * 255) - worldColors[i][j] = `rgb(${randColor}, ${randColor}, ${randColor})` - } -} - -export const Primary: Story = { - args: { - worldColors - }, -} +// const worldColors: string[][] = [] +// +// const mapSize = 10 +// for (let i = 0; i < mapSize; i += 1) { +// worldColors[i] = [] as string[] +// for (let j = 0; j < mapSize; j += 1) { +// const randColor = Math.floor(Math.random() * 255) +// worldColors[i][j] = `rgb(${randColor}, ${randColor}, ${randColor})` +// } +// } +// +// export const Primary: Story = { +// args: { +// worldColors +// }, +// } diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9a22d3ef..361b6569 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,25 +1,27 @@ import { useRef, useEffect, useState } from 'react' import { contro } from '../controls' import { MinimapDrawer } from './MinimapDrawer' +import { DrawerAdapter } from './MinimapDrawer' -export default () => { +export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const [fullMapOpened, setFullMapOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) function updateMap () { + if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { - drawerRef.current.draw(bot) + drawerRef.current.draw(adapter.getHighestBlockColor, adapter.playerPosition.x, adapter.playerPosition.z) if (canvasTick.current % 300 === 0) { - drawerRef.current.deleteOldWorldColors(bot.entity.position.x, bot.entity.position.z) + drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } } canvasTick.current += 1 } - const toggleFullMap = ({ command }) => { - if (command === 'ui.toggleMap') setFullMapOpened(prev => !prev) + const toggleFullMap = () => { + setFullMapOpened(prev => !prev) } @@ -32,15 +34,18 @@ export default () => { }, [canvasRef.current, fullMapOpened]) useEffect(() => { - bot.on('move', updateMap) - - contro.on('trigger', toggleFullMap) + if (adapter) { + adapter.on('updateMap', updateMap) + adapter.on('toggleFullMap', toggleFullMap) + } return () => { - bot.off('move', updateMap) - contro.off('trigger', toggleFullMap) + if (adapter) { + adapter.off('updateMap', updateMap) + adapter.off('toggleFullMap', toggleFullMap) + } } - }, []) + }, [adapter]) return fullMapOpened ?
& { } } -interface DrawerAdapter extends TypedEventEmitter<{ - updateBlockColor: (pos: Position) => void +export interface DrawerAdapter extends TypedEventEmitter<{ + updateBlockColor: (pos: Vec3) => void updatePlayerPosition: () => void updateWarps: () => void }> { getHighestBlockColor: (x: number, z: number) => string - playerPosition: Position - warps: WorldWarp - setWarp: (name: string, pos: Position, rotation: Position, dimension: string, color: string, disabled: boolean) => void + playerPosition: Vec3 + warps: WorldWarp[] + setWarp: (name: string, pos: Vec3, dimension: string, color: string, disabled: boolean) => void } export class MinimapDrawer { @@ -54,7 +54,11 @@ export class MinimapDrawer { this._canvas = canvas } - draw (bot: BotType | undefined) { + draw ( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, + z: number + ) { this.ctx.clearRect( this.centerX - this.radius, this.centerY - this.radius, @@ -62,24 +66,28 @@ export class MinimapDrawer { this.radius * 2 ) - if (bot) { - this.updateWorldColors(bot) - } else { - this.ctx.strokeStyle = 'black' - this.ctx.beginPath() - - this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) - - this.ctx.fillStyle = 'white' - this.ctx.fill() - - this.ctx.strokeStyle = '#000000' - this.ctx.lineWidth = 1 - this.ctx.stroke() - } + // if (bot) { + this.updateWorldColors(getHighestBlockColor, x, z) + // } else { + // this.ctx.strokeStyle = 'black' + // this.ctx.beginPath() + // + // this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) + // + // this.ctx.fillStyle = 'white' + // this.ctx.fill() + // + // this.ctx.strokeStyle = '#000000' + // this.ctx.lineWidth = 1 + // this.ctx.stroke() + // } } - updateWorldColors (bot: BotType) { + updateWorldColors ( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, + z: number + ) { const left = this.centerX - this.radius const top = this.centerY - this.radius const mapPixel = Math.floor(this.radius * 2 / this.mapSize) @@ -92,10 +100,10 @@ export class MinimapDrawer { for (let row = 0; row < this.mapSize; row += 1) { for (let col = 0; col < this.mapSize; col += 1) { - this.ctx.fillStyle = this.getHighestBlockColor( - bot, - bot.entity.position.x - this.mapSize / 2 + row, - bot.entity.position.z - this.mapSize / 2 + col + this.ctx.fillStyle = this.getHighestBlockColorCached( + getHighestBlockColor, + x - this.mapSize / 2 + row, + z - this.mapSize / 2 + col ) this.ctx.fillRect( left + mapPixel * col, @@ -107,22 +115,19 @@ export class MinimapDrawer { } } - getHighestBlockColor (bot: BotType, x: number, z: number) { + getHighestBlockColorCached ( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, + z: number + ) { const roundX = Math.floor(x) const roundZ = Math.floor(z) const key = `${roundX},${roundZ}` if (this.worldColors[key]) { return this.worldColors[key] } - let block = null as import('prismarine-block').Block | null - let { height } = (bot.game as any) - const airBlocks = new Set(['air', 'cave_air', 'void_air']) - do { - block = bot.world.getBlock(new Vec3(x, height, z)) - height -= 1 - } while (airBlocks.has(block?.name ?? '')) - const color = BlockData.colors[block?.name ?? ''] ?? 'white' - this.worldColors[key] = color + const color = getHighestBlockColor(x, z) + if (color !== 'white') this.worldColors[key] = color return color } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index d189337a..1a306070 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,12 +1,80 @@ -import { useEffect, useState } from 'react' +import { useEffect, useRef } from 'react' import { Vec3 } from 'vec3' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import Minimap from './Minimap' +import { DrawerAdapter } from './MinimapDrawer' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' +import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import { contro } from '../controls' +class DrawerAdapterImpl extends TypedEventEmitter<{ + updateBlockColor: (pos: Vec3) => void + updatePlayerPosition: () => void + updateWarps: () => void +}> implements DrawerAdapter { + playerPosition: Vec3 + warps: WorldWarp[] + + constructor(pos?: Vec3, warps?: WorldWarp[]) { + super() + this.playerPosition = pos ?? new Vec3(0, 0, 0) + this.warps = warps ?? [] as WorldWarp[] + } + + getHighestBlockColor (x: number, z:number) { + let block = null as import('prismarine-block').Block | null + let { height } = (bot.game as any) + const airBlocks = new Set(['air', 'cave_air', 'void_air']) + do { + block = bot.world.getBlock(new Vec3(x, height, z)) + height -= 1 + } while (airBlocks.has(block?.name ?? '')) + const color = BlockData.colors[block?.name ?? ''] ?? 'white' + return color + } + + setWarp(name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } + const index = this.warps.findIndex(w => w.name === name) + if (index !== -1) { + this.warps[index] = warp + } else { + this.warps.push(warp) + } + this.emit('updateWarps') + } +} export default () => { + const adapter = useRef(null) + + const updateMap = () => { + if (!adapter.current) return + adapter.current.playerPosition = bot.entity.position + adapter.current.emit('updateMap') + } + + const toggleFullMap = ({ command }) => { + if (!adapter.current) return + if (command === 'ui.toggleMap') adapter.current.emit('toggleFullMap') + } + + useEffect(() => { + adapter.current = new DrawerAdapterImpl(bot.entity.position) + }, []) + + useEffect(() => { + bot.on('move', updateMap) + + contro.on('trigger', toggleFullMap) + + return () => { + bot.off('move', updateMap) + contro.off('trigger', toggleFullMap) + } + }, []) return
- +
} From fb84af6105ffdb9c809eb7f7649aa2f3acc5cc9c Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 21 Jun 2024 15:17:54 +0400 Subject: [PATCH 020/955] clean up --- src/react/Minimap.tsx | 4 ++-- src/react/MinimapDrawer.ts | 16 +--------------- src/react/MinimapProvider.tsx | 16 ++++++++-------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 361b6569..29b29d9c 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect, useState } from 'react' import { contro } from '../controls' -import { MinimapDrawer } from './MinimapDrawer' -import { DrawerAdapter } from './MinimapDrawer' +import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' + export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const [fullMapOpened, setFullMapOpened] = useState(false) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 68149a41..f2088fc7 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -66,21 +66,7 @@ export class MinimapDrawer { this.radius * 2 ) - // if (bot) { - this.updateWorldColors(getHighestBlockColor, x, z) - // } else { - // this.ctx.strokeStyle = 'black' - // this.ctx.beginPath() - // - // this.ctx.arc(this.centerX, this.centerY, this.radius, 0, 2 * Math.PI, false) - // - // this.ctx.fillStyle = 'white' - // this.ctx.fill() - // - // this.ctx.strokeStyle = '#000000' - // this.ctx.lineWidth = 1 - // this.ctx.stroke() - // } + this.updateWorldColors(getHighestBlockColor, x, z) } updateWorldColors ( diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 1a306070..4656c0f6 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,11 +1,11 @@ import { useEffect, useRef } from 'react' import { Vec3 } from 'vec3' -import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' -import Minimap from './Minimap' -import { DrawerAdapter } from './MinimapDrawer' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import { contro } from '../controls' +import Minimap from './Minimap' +import { DrawerAdapter } from './MinimapDrawer' class DrawerAdapterImpl extends TypedEventEmitter<{ updateBlockColor: (pos: Vec3) => void @@ -15,7 +15,7 @@ class DrawerAdapterImpl extends TypedEventEmitter<{ playerPosition: Vec3 warps: WorldWarp[] - constructor(pos?: Vec3, warps?: WorldWarp[]) { + constructor (pos?: Vec3, warps?: WorldWarp[]) { super() this.playerPosition = pos ?? new Vec3(0, 0, 0) this.warps = warps ?? [] as WorldWarp[] @@ -33,13 +33,13 @@ class DrawerAdapterImpl extends TypedEventEmitter<{ return color } - setWarp(name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + setWarp (name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } const index = this.warps.findIndex(w => w.name === name) - if (index !== -1) { - this.warps[index] = warp - } else { + if (index === -1) { this.warps.push(warp) + } else { + this.warps[index] = warp } this.emit('updateWarps') } From 0dfff262f477623b6fc091d23d4dda2e57fb6d4c Mon Sep 17 00:00:00 2001 From: gguio Date: Sat, 22 Jun 2024 17:00:55 +0400 Subject: [PATCH 021/955] useState used for adapter --- src/react/MinimapDrawer.ts | 8 ++++---- src/react/MinimapProvider.tsx | 28 ++++++++++------------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index f2088fc7..d9094ae7 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -1,8 +1,6 @@ import { Vec3 } from 'vec3' -import { Position } from 'source-map-js' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' -import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' type BotType = Omit & { world: Omit & { @@ -14,11 +12,13 @@ type BotType = Omit & { } } -export interface DrawerAdapter extends TypedEventEmitter<{ +export type MapUpdates = { updateBlockColor: (pos: Vec3) => void updatePlayerPosition: () => void updateWarps: () => void -}> { +} + +export interface DrawerAdapter extends TypedEventEmitter { getHighestBlockColor: (x: number, z: number) => string playerPosition: Vec3 warps: WorldWarp[] diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 4656c0f6..7eab51eb 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,17 +1,13 @@ -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' import { Vec3 } from 'vec3' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json' import { contro } from '../controls' import Minimap from './Minimap' -import { DrawerAdapter } from './MinimapDrawer' +import { DrawerAdapter, MapUpdates } from './MinimapDrawer' -class DrawerAdapterImpl extends TypedEventEmitter<{ - updateBlockColor: (pos: Vec3) => void - updatePlayerPosition: () => void - updateWarps: () => void -}> implements DrawerAdapter { +class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 warps: WorldWarp[] @@ -46,23 +42,19 @@ class DrawerAdapterImpl extends TypedEventEmitter<{ } export default () => { - const adapter = useRef(null) + const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) const updateMap = () => { - if (!adapter.current) return - adapter.current.playerPosition = bot.entity.position - adapter.current.emit('updateMap') + if (!adapter) return + adapter.playerPosition = bot.entity.position + adapter.emit('updateMap') } const toggleFullMap = ({ command }) => { - if (!adapter.current) return - if (command === 'ui.toggleMap') adapter.current.emit('toggleFullMap') + if (!adapter) return + if (command === 'ui.toggleMap') adapter.emit('toggleFullMap') } - useEffect(() => { - adapter.current = new DrawerAdapterImpl(bot.entity.position) - }, []) - useEffect(() => { bot.on('move', updateMap) @@ -75,6 +67,6 @@ export default () => { }, []) return
- +
} From 03d8e3100fe9501f2bde4fad2fadc2edbb9f0e95 Mon Sep 17 00:00:00 2001 From: gguio Date: Sat, 22 Jun 2024 17:46:39 +0400 Subject: [PATCH 022/955] pointer lock --- src/react/Minimap.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 29b29d9c..35380708 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,10 +1,11 @@ -import { useRef, useEffect, useState } from 'react' -import { contro } from '../controls' +import { useRef, useEffect } from 'react' +import { showModal, hideModal } from '../globalState' +import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' export default ({ adapter }: { adapter: DrawerAdapter | null }) => { - const [fullMapOpened, setFullMapOpened] = useState(false) + const fullMapOpened = useIsModalActive('full-map') const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) @@ -21,7 +22,11 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { } const toggleFullMap = () => { - setFullMapOpened(prev => !prev) + if (fullMapOpened) { + hideModal({ reactType: 'full-map' }) + } else { + showModal({ reactType: 'full-map' }) + } } From 4ef31616c2ab458d309e98b9cab1e832b5ccd748 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 25 Jun 2024 15:52:30 +0400 Subject: [PATCH 023/955] mouse click in world coords doesnt count correctly --- src/react/Minimap.tsx | 21 +++++++++++++++++++++ src/react/MinimapDrawer.ts | 7 +++++++ src/react/MinimapProvider.tsx | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 35380708..9a60364e 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -29,6 +29,14 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { } } + const setWarp = (e: MouseEvent) => { + if (!e.target) return + const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() + const x = e.pageX - rect.left + const y = e.pageY - rect.top + const coords = drawerRef.current?.mouseToWorldPos(x, y, bot.entity.position) + console.log('coords:', x, y, '| In game coords:', coords) + } useEffect(() => { if (canvasRef.current && !drawerRef.current) { @@ -38,6 +46,19 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { } }, [canvasRef.current, fullMapOpened]) + useEffect(() => { + console.log('full map toggled') + if (fullMapOpened && canvasRef.current) { + console.log('in if') + canvasRef.current.addEventListener('click', setWarp) + } + + return () => { + console.log('memory clear') + canvasRef.current?.removeEventListener('click', setWarp) + } + }, [fullMapOpened]) + useEffect(() => { if (adapter) { adapter.on('updateMap', updateMap) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index d9094ae7..bc9a79a7 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -130,4 +130,11 @@ export class MinimapDrawer { } } } + + mouseToWorldPos(x: number, z: number, botPos: Vec3) { + const worldX = x - this.radius + const worldZ = z - this.radius + + return [botPos.x - worldX, botPos.z - worldZ] + } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 7eab51eb..14afc657 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { useEffect, useState } from 'react' import { Vec3 } from 'vec3' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' From e8864447d239d9c1cbbfe76975d8cc37d5d49ed5 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 12:46:17 +0400 Subject: [PATCH 024/955] click to map pos fix --- src/react/Minimap.tsx | 4 ++-- src/react/MinimapDrawer.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9a60364e..4c11aa27 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -32,8 +32,8 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const setWarp = (e: MouseEvent) => { if (!e.target) return const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const x = e.pageX - rect.left - const y = e.pageY - rect.top + const x = (e.pageX - rect.left) * canvasRef.current!.width / rect.width + const y = (e.pageY - rect.top) * canvasRef.current!.height / rect.height const coords = drawerRef.current?.mouseToWorldPos(x, y, bot.entity.position) console.log('coords:', x, y, '| In game coords:', coords) } diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index bc9a79a7..5d583a6f 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -131,10 +131,10 @@ export class MinimapDrawer { } } - mouseToWorldPos(x: number, z: number, botPos: Vec3) { - const worldX = x - this.radius - const worldZ = z - this.radius + mouseToWorldPos (x: number, z: number, botPos: Vec3) { + const worldX = x - this.mapSize / 2 + const worldZ = z - this.mapSize / 2 - return [botPos.x - worldX, botPos.z - worldZ] + return [(botPos.x + worldX).toFixed(1), (botPos.z + worldZ).toFixed(1)] } } From a6880be14cc58480633c3da78ece72b50b23750d Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 13:18:14 +0400 Subject: [PATCH 025/955] x and y should be otherwise --- src/react/Minimap.tsx | 11 ++++------- src/react/MinimapDrawer.ts | 27 ++++++++++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 4c11aa27..df1831e4 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -4,7 +4,7 @@ import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' -export default ({ adapter }: { adapter: DrawerAdapter | null }) => { +export default ({ adapter }: { adapter: DrawerAdapter }) => { const fullMapOpened = useIsModalActive('full-map') const canvasTick = useRef(0) const canvasRef = useRef(null) @@ -13,7 +13,7 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { function updateMap () { if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { - drawerRef.current.draw(adapter.getHighestBlockColor, adapter.playerPosition.x, adapter.playerPosition.z) + drawerRef.current.draw(bot.entity.position) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } @@ -34,27 +34,24 @@ export default ({ adapter }: { adapter: DrawerAdapter | null }) => { const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() const x = (e.pageX - rect.left) * canvasRef.current!.width / rect.width const y = (e.pageY - rect.top) * canvasRef.current!.height / rect.height - const coords = drawerRef.current?.mouseToWorldPos(x, y, bot.entity.position) + const coords = drawerRef.current?.mouseToWorldPos(y, x, bot.entity.position) console.log('coords:', x, y, '| In game coords:', coords) } useEffect(() => { if (canvasRef.current && !drawerRef.current) { - drawerRef.current = new MinimapDrawer(canvasRef.current) + drawerRef.current = new MinimapDrawer(canvasRef.current, adapter.getHighestBlockColor) } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } }, [canvasRef.current, fullMapOpened]) useEffect(() => { - console.log('full map toggled') if (fullMapOpened && canvasRef.current) { - console.log('in if') canvasRef.current.addEventListener('click', setWarp) } return () => { - console.log('memory clear') canvasRef.current?.removeEventListener('click', setWarp) } }, [fullMapOpened]) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 5d583a6f..87e56962 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -28,16 +28,20 @@ export interface DrawerAdapter extends TypedEventEmitter { export class MinimapDrawer { centerX: number centerY: number - mapSize: number + _mapSize: number radius: number ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] + lastBotPos: Vec3 constructor ( canvas: HTMLCanvasElement, + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] ) { this.canvas = canvas + this.getHighestBlockColor = getHighestBlockColor } get canvas () { @@ -48,16 +52,24 @@ export class MinimapDrawer { this.ctx = canvas.getContext('2d')! this.ctx.imageSmoothingEnabled = false this.radius = Math.min(canvas.width, canvas.height) / 2 - this.mapSize = this.radius * 2 + this._mapSize = this.radius * 2 this.centerX = canvas.width / 2 this.centerY = canvas.height / 2 this._canvas = canvas } + get mapSize() { + return this._mapSize + } + + set mapSize(mapSize: number) { + this._mapSize = mapSize + this.draw(this.lastBotPos) + } + draw ( - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], - x: number, - z: number + botPos: Vec3, + getHighestBlockColor?: DrawerAdapter['getHighestBlockColor'], ) { this.ctx.clearRect( this.centerX - this.radius, @@ -66,7 +78,8 @@ export class MinimapDrawer { this.radius * 2 ) - this.updateWorldColors(getHighestBlockColor, x, z) + this.lastBotPos = botPos + this.updateWorldColors(getHighestBlockColor ?? this.getHighestBlockColor, botPos.x, botPos.z) } updateWorldColors ( @@ -135,6 +148,6 @@ export class MinimapDrawer { const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 - return [(botPos.x + worldX).toFixed(1), (botPos.z + worldZ).toFixed(1)] + return [(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)] } } From 3c63c0b24006bc40a86e64efffe5e88d52d626c6 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 13:39:54 +0400 Subject: [PATCH 026/955] add new warp logic in MinimapDrawer --- src/react/Minimap.tsx | 27 +++++++++------------------ src/react/MinimapDrawer.ts | 19 +++++++++++-------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index df1831e4..9e0c8c27 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -29,18 +29,13 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { } } - const setWarp = (e: MouseEvent) => { - if (!e.target) return - const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const x = (e.pageX - rect.left) * canvasRef.current!.width / rect.width - const y = (e.pageY - rect.top) * canvasRef.current!.height / rect.height - const coords = drawerRef.current?.mouseToWorldPos(y, x, bot.entity.position) - console.log('coords:', x, y, '| In game coords:', coords) + const handleClickOnMap = (e: MouseEvent) => { + drawerRef.current?.addWarpOnClick(e, bot.entity.position) } useEffect(() => { if (canvasRef.current && !drawerRef.current) { - drawerRef.current = new MinimapDrawer(canvasRef.current, adapter.getHighestBlockColor) + drawerRef.current = new MinimapDrawer(canvasRef.current, adapter) } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } @@ -48,25 +43,21 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { useEffect(() => { if (fullMapOpened && canvasRef.current) { - canvasRef.current.addEventListener('click', setWarp) + canvasRef.current.addEventListener('click', handleClickOnMap) } return () => { - canvasRef.current?.removeEventListener('click', setWarp) + canvasRef.current?.removeEventListener('click', handleClickOnMap) } }, [fullMapOpened]) useEffect(() => { - if (adapter) { - adapter.on('updateMap', updateMap) - adapter.on('toggleFullMap', toggleFullMap) - } + adapter.on('updateMap', updateMap) + adapter.on('toggleFullMap', toggleFullMap) return () => { - if (adapter) { - adapter.off('updateMap', updateMap) - adapter.off('toggleFullMap', toggleFullMap) - } + adapter.off('updateMap', updateMap) + adapter.off('toggleFullMap', toggleFullMap) } }, [adapter]) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 87e56962..a24c2174 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -33,15 +33,14 @@ export class MinimapDrawer { ctx: CanvasRenderingContext2D _canvas: HTMLCanvasElement worldColors: { [key: string]: string } = {} - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] lastBotPos: Vec3 constructor ( canvas: HTMLCanvasElement, - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'] + public adapter: DrawerAdapter ) { this.canvas = canvas - this.getHighestBlockColor = getHighestBlockColor + this.adapter = adapter } get canvas () { @@ -58,11 +57,11 @@ export class MinimapDrawer { this._canvas = canvas } - get mapSize() { + get mapSize () { return this._mapSize } - set mapSize(mapSize: number) { + set mapSize (mapSize: number) { this._mapSize = mapSize this.draw(this.lastBotPos) } @@ -79,7 +78,7 @@ export class MinimapDrawer { ) this.lastBotPos = botPos - this.updateWorldColors(getHighestBlockColor ?? this.getHighestBlockColor, botPos.x, botPos.z) + this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) } updateWorldColors ( @@ -144,10 +143,14 @@ export class MinimapDrawer { } } - mouseToWorldPos (x: number, z: number, botPos: Vec3) { + addWarpOnClick (e: MouseEvent, botPos: Vec3) { + if (!e.target) return + const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() + const z = (e.pageX - rect.left) * this.canvas.width / rect.width + const x = (e.pageY - rect.top) * this.canvas.height / rect.height const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 - return [(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)] + console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) } } From d61adb0a5a2a1288b2df034368bf21d346236251 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 14:35:32 +0400 Subject: [PATCH 027/955] screen to set up warp --- src/react/Minimap.tsx | 44 ++++++++++++++++++++++++++++++++++++-- src/react/MinimapDrawer.ts | 2 +- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 9e0c8c27..b17770f8 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,11 +1,13 @@ -import { useRef, useEffect } from 'react' +import { useRef, useEffect, useState } from 'react' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' +import Input from './Input' export default ({ adapter }: { adapter: DrawerAdapter }) => { const fullMapOpened = useIsModalActive('full-map') + const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const canvasTick = useRef(0) const canvasRef = useRef(null) const drawerRef = useRef(null) @@ -13,7 +15,7 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { function updateMap () { if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { - drawerRef.current.draw(bot.entity.position) + drawerRef.current.draw(adapter.playerPosition) if (canvasTick.current % 300 === 0) { drawerRef.current.deleteOldWorldColors(adapter.playerPosition.x, adapter.playerPosition.z) } @@ -31,6 +33,11 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { const handleClickOnMap = (e: MouseEvent) => { drawerRef.current?.addWarpOnClick(e, bot.entity.position) + setIsWarpInfoOpened(true) + } + + const updateWarps = () => { + } useEffect(() => { @@ -44,6 +51,8 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { useEffect(() => { if (fullMapOpened && canvasRef.current) { canvasRef.current.addEventListener('click', handleClickOnMap) + } else if (!fullMapOpened) { + setIsWarpInfoOpened(false) } return () => { @@ -54,10 +63,12 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { useEffect(() => { adapter.on('updateMap', updateMap) adapter.on('toggleFullMap', toggleFullMap) + adapter.on('updateWaprs', updateWarps) return () => { adapter.off('updateMap', updateMap) adapter.off('toggleFullMap', toggleFullMap) + adapter.off('updateWaprs', updateWarps) } }, [adapter]) @@ -80,6 +91,7 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { height={150} ref={canvasRef} > + {isWarpInfoOpened && }
:
{
} + +const WarpInfo = ({ adapter }: { adapter: DrawerAdapter }) => { + + return
+
+ Name: +
+
+
X:
+
Y:
+
Z:
+
+ +
+} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index a24c2174..ff6457dc 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -22,7 +22,7 @@ export interface DrawerAdapter extends TypedEventEmitter { getHighestBlockColor: (x: number, z: number) => string playerPosition: Vec3 warps: WorldWarp[] - setWarp: (name: string, pos: Vec3, dimension: string, color: string, disabled: boolean) => void + setWarp: (name: string, pos: Vec3, world: string, color: string, disabled: boolean) => void } export class MinimapDrawer { From 9e7299c2b0021b1f97afc929d8cd0ecda67c679a Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 14:45:51 +0400 Subject: [PATCH 028/955] storybook doesnt worl --- src/react/Minimap.stories.tsx | 20 ++++++++++++++------ src/react/Minimap.tsx | 2 +- src/react/MinimapProvider.tsx | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 8fd94c1c..458139e3 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -1,4 +1,6 @@ +import { Vec3 } from 'vec3' import type { Meta, StoryObj } from '@storybook/react' +import { DrawerAdapterImpl } from './MinimapProvider' import Minimap from './Minimap' @@ -7,7 +9,13 @@ const meta: Meta = { } export default meta -// type Story = StoryObj; +type Story = StoryObj; + +const adapter = new DrawerAdapterImpl(new Vec3(0, 0, 0)) + +adapter.getHighestBlockColor = (x: number, z: number) => { + return 'green' +} // const worldColors: string[][] = [] // @@ -20,8 +28,8 @@ export default meta // } // } // -// export const Primary: Story = { -// args: { -// worldColors -// }, -// } +export const Primary: Story = { + args: { + adapter + }, +} diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index b17770f8..f2d8d1e2 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -32,7 +32,7 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { } const handleClickOnMap = (e: MouseEvent) => { - drawerRef.current?.addWarpOnClick(e, bot.entity.position) + drawerRef.current?.addWarpOnClick(e, adapter.playerPosition) setIsWarpInfoOpened(true) } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 14afc657..27520c49 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -7,7 +7,7 @@ import { contro } from '../controls' import Minimap from './Minimap' import { DrawerAdapter, MapUpdates } from './MinimapDrawer' -class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { +export class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 warps: WorldWarp[] From d960d9a55af3b326d8c7299a555df9c9756034c3 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 16:16:46 +0400 Subject: [PATCH 029/955] storybook for minimap. Toggle full map doesnt work yet --- src/react/Minimap.stories.tsx | 65 ++++++++++++++++++++++++++--------- src/react/Minimap.tsx | 10 +++++- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 458139e3..1c73ff22 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -1,35 +1,68 @@ import { Vec3 } from 'vec3' import type { Meta, StoryObj } from '@storybook/react' -import { DrawerAdapterImpl } from './MinimapProvider' +import { DrawerAdapter, MapUpdates } from './MinimapDrawer' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' +import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' +import { useEffect } from 'react' import Minimap from './Minimap' const meta: Meta = { component: Minimap, + decorators: [ + (Story, context) => { + + useEffect(() => { + adapter.emit('toggleFullMap') + setTimeout(updateMap, 2000) + }, [context.args['fullMap']]) + + return
+ } + ] } export default meta type Story = StoryObj; -const adapter = new DrawerAdapterImpl(new Vec3(0, 0, 0)) -adapter.getHighestBlockColor = (x: number, z: number) => { - return 'green' +class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { + playerPosition: Vec3 + warps: WorldWarp[] + + constructor (pos?: Vec3, warps?: WorldWarp[]) { + super() + this.playerPosition = pos ?? new Vec3(0, 0, 0) + this.warps = warps ?? [] as WorldWarp[] + } + + getHighestBlockColor (x: number, z:number) { + console.log('got color') + return 'green' + } + + setWarp (name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } + const index = this.warps.findIndex(w => w.name === name) + if (index === -1) { + this.warps.push(warp) + } else { + this.warps[index] = warp + } + this.emit('updateWarps') + } } -// const worldColors: string[][] = [] -// -// const mapSize = 10 -// for (let i = 0; i < mapSize; i += 1) { -// worldColors[i] = [] as string[] -// for (let j = 0; j < mapSize; j += 1) { -// const randColor = Math.floor(Math.random() * 255) -// worldColors[i][j] = `rgb(${randColor}, ${randColor}, ${randColor})` -// } -// } -// +const adapter = new DrawerAdapterImpl() +const updateMap = () => { + console.log('map updated') + adapter.emit('updateMap') +} +setTimeout(updateMap, 2000) + export const Primary: Story = { args: { - adapter + adapter, + fullMap: false }, } diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index f2d8d1e2..ebf8a6bc 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -5,7 +5,7 @@ import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' -export default ({ adapter }: { adapter: DrawerAdapter }) => { +export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { const fullMapOpened = useIsModalActive('full-map') const [isWarpInfoOpened, setIsWarpInfoOpened] = useState(false) const canvasTick = useRef(0) @@ -48,6 +48,14 @@ export default ({ adapter }: { adapter: DrawerAdapter }) => { } }, [canvasRef.current, fullMapOpened]) + // useEffect(() => { + // if (fullMap) { + // showModal({ reactType: 'full-map' }) + // } else { + // hideModal({ reactType: 'full-map' }) + // } + // }, [fullMap]) + useEffect(() => { if (fullMapOpened && canvasRef.current) { canvasRef.current.addEventListener('click', handleClickOnMap) From c4282c9ab7659dc6a4ceb4167cb2578ae9255281 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 26 Jun 2024 20:36:35 +0400 Subject: [PATCH 030/955] storybook for map + fields to set warp. Styles are not done --- src/react/Minimap.stories.tsx | 13 +++---- src/react/Minimap.tsx | 67 +++++++++++++++++++++++------------ src/react/MinimapDrawer.ts | 1 + 3 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 1c73ff22..75c0b45d 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -1,11 +1,12 @@ import { Vec3 } from 'vec3' import type { Meta, StoryObj } from '@storybook/react' -import { DrawerAdapter, MapUpdates } from './MinimapDrawer' import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { TypedEventEmitter } from 'contro-max/build/typedEventEmitter' import { useEffect } from 'react' +import { cleanData } from 'cypress/types/jquery' import Minimap from './Minimap' +import { DrawerAdapter, MapUpdates } from './MinimapDrawer' const meta: Meta = { component: Minimap, @@ -13,8 +14,9 @@ const meta: Meta = { (Story, context) => { useEffect(() => { - adapter.emit('toggleFullMap') - setTimeout(updateMap, 2000) + console.log('map updated') + adapter.emit('updateMap') + }, [context.args['fullMap']]) return
@@ -54,11 +56,6 @@ class DrawerAdapterImpl extends TypedEventEmitter implements DrawerA } const adapter = new DrawerAdapterImpl() -const updateMap = () => { - console.log('map updated') - adapter.emit('updateMap') -} -setTimeout(updateMap, 2000) export const Primary: Story = { args: { diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index ebf8a6bc..4f445813 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,4 +1,4 @@ -import { useRef, useEffect, useState } from 'react' +import { useRef, useEffect, useState, CSSProperties } from 'react' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' @@ -13,7 +13,6 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea const drawerRef = useRef(null) function updateMap () { - if (!adapter) return if (drawerRef.current && canvasTick.current % 2 === 0) { drawerRef.current.draw(adapter.playerPosition) if (canvasTick.current % 300 === 0) { @@ -46,27 +45,19 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } else if (canvasRef.current && drawerRef.current) { drawerRef.current.canvas = canvasRef.current } - }, [canvasRef.current, fullMapOpened]) - - // useEffect(() => { - // if (fullMap) { - // showModal({ reactType: 'full-map' }) - // } else { - // hideModal({ reactType: 'full-map' }) - // } - // }, [fullMap]) + }, [canvasRef.current, fullMapOpened, fullMap]) useEffect(() => { - if (fullMapOpened && canvasRef.current) { + if ((fullMapOpened || fullMap) && canvasRef.current) { canvasRef.current.addEventListener('click', handleClickOnMap) - } else if (!fullMapOpened) { + } else if (!fullMapOpened || !fullMap) { setIsWarpInfoOpened(false) } return () => { canvasRef.current?.removeEventListener('click', handleClickOnMap) } - }, [fullMapOpened]) + }, [fullMapOpened, fullMap]) useEffect(() => { adapter.on('updateMap', updateMap) @@ -80,7 +71,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } }, [adapter]) - return fullMapOpened ?
- {isWarpInfoOpened && } + {isWarpInfoOpened && }
:
} -const WarpInfo = ({ adapter }: { adapter: DrawerAdapter }) => { +const WarpInfo = ({ adapter, drawer }: { adapter: DrawerAdapter, drawer: MinimapDrawer | null }) => { + const posInputStyle: CSSProperties = { + width: '100%', + } + const posInputContStyle: CSSProperties = { + flexGrow: '1', + display: 'flex', + } return
{ display: 'flex', justifyContent: 'center', alignItems: 'center', + gap: '10px', flexDirection: 'column', backgroundColor: 'rgba(0, 0, 0, 0.5)', - maxWidth: '70%' }} >
Name:
-
X:
-
Y:
-
Z:
+
X: +
+
+ Y: +
+
+ Z: +
+
+
+ Color: +
+
+ Disabled:
diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index ff6457dc..3f0e03e3 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -152,5 +152,6 @@ export class MinimapDrawer { const worldZ = z - this.mapSize / 2 console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) + this.lastBotPos = new Vec3(Math.floor(botPos.x + worldX), botPos.y, Math.floor(botPos.z + worldZ)) } } From f49c5294423225fd641975d278598c180b10e78d Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 27 Jun 2024 13:04:31 +0400 Subject: [PATCH 031/955] ui for set warp --- src/react/Minimap.tsx | 100 +++++++++++++++++++++------------- src/react/MinimapProvider.tsx | 1 + 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 4f445813..617dcbd5 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,8 +1,9 @@ -import { useRef, useEffect, useState, CSSProperties } from 'react' +import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' +import Button from './Button' export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { @@ -90,8 +91,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea height={150} ref={canvasRef} > - {isWarpInfoOpened && } - + {isWarpInfoOpened && }
:
-
} -const WarpInfo = ({ adapter, drawer }: { adapter: DrawerAdapter, drawer: MinimapDrawer | null }) => { +const WarpInfo = ( + { adapter, drawer, setIsWarpInfoOpened } + : + { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } +) => { const posInputStyle: CSSProperties = { - width: '100%', - } - const posInputContStyle: CSSProperties = { flexGrow: '1', + } + const fieldCont: CSSProperties = { display: 'flex', + alignItems: 'center', + gap: '5px' } return
-
- Name: -
-
-
X: +
+
+ Name: +
+ +
+
+
+ X: +
+ -
-
- Y: + Y: +
+ -
-
- Z: + Z: +
+ -
+
+
+
Color:
+ +
+
+
Disabled:
+ +
+
+ + +
-
- Color: -
-
- Disabled: -
-
} diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 27520c49..b40ddefa 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -37,6 +37,7 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } else { this.warps[index] = warp } + if (localServer) void localServer.setWarp(warp) this.emit('updateWarps') } } From 58cb23d2d83d8c60f999da5a74dbd74a6039b5af Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 27 Jun 2024 14:41:07 +0400 Subject: [PATCH 032/955] saving warps in local server --- src/react/Minimap.stories.tsx | 2 +- src/react/Minimap.tsx | 98 +++++++++++++++++++++++++++-------- src/react/MinimapDrawer.ts | 10 ++-- src/react/MinimapProvider.tsx | 8 ++- 4 files changed, 90 insertions(+), 28 deletions(-) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index 75c0b45d..d55f809a 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -43,7 +43,7 @@ class DrawerAdapterImpl extends TypedEventEmitter implements DrawerA return 'green' } - setWarp (name: string, pos: Vec3, world: string, color: string, disabled: boolean): void { + setWarp (name: string, pos: Vec3, color: string, disabled: boolean, world?: string): void { const warp: WorldWarp = { name, x: pos.x, y: pos.y, z: pos.z, world, color, disabled } const index = this.warps.findIndex(w => w.name === name) if (index === -1) { diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index 617dcbd5..9c37cd36 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -1,10 +1,12 @@ import { useRef, useEffect, useState, CSSProperties, Dispatch, SetStateAction } from 'react' +import { Vec3 } from 'vec3' +import { WorldWarp } from 'flying-squid/dist/lib/modules/warps' import { showModal, hideModal } from '../globalState' import { useIsModalActive } from './utilsApp' import { MinimapDrawer, DrawerAdapter } from './MinimapDrawer' import Input from './Input' import Button from './Button' - + export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolean }) => { const fullMapOpened = useIsModalActive('full-map') @@ -32,7 +34,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } const handleClickOnMap = (e: MouseEvent) => { - drawerRef.current?.addWarpOnClick(e, adapter.playerPosition) + drawerRef.current?.setWarpPosOnClick(e, adapter.playerPosition) setIsWarpInfoOpened(true) } @@ -72,7 +74,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea } }, [adapter]) - return fullMapOpened || fullMap ?
- {isWarpInfoOpened && } @@ -108,9 +110,19 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea const WarpInfo = ( { adapter, drawer, setIsWarpInfoOpened } - : - { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } + : + { adapter: DrawerAdapter, drawer: MinimapDrawer | null, setIsWarpInfoOpened: Dispatch> } ) => { + const [warp, setWarp] = useState({ + name: '', + x: drawer?.lastWarpPos.x ?? 100, + y: drawer?.lastWarpPos.y ?? 100, + z: drawer?.lastWarpPos.z ?? 100, + color: '#d3d3d3', + disabled: false, + world: adapter.world + }) + const posInputStyle: CSSProperties = { flexGrow: '1', } @@ -149,38 +161,82 @@ const WarpInfo = (
Name:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, name: e.target.value } }) + }} + />
X:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, x: Number(e.target.value) } }) + }} + />
Y:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, y: Number(e.target.value) } }) + }} + />
Z:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, z: Number(e.target.value) } }) + }} + />
Color:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, color: e.target.value } }) + }} + />
Disabled:
- + { + if (!e.target) return + setWarp(prev => { return { ...prev, disabled: e.target.checked } }) + }} + />
- + diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 1be02898..d097c302 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -37,7 +37,7 @@ export class MinimapDrawer { lastBotPos: Vec3 lastWarpPos: Vec3 - constructor ( + constructor( canvas: HTMLCanvasElement, public adapter: DrawerAdapter ) { @@ -45,11 +45,11 @@ export class MinimapDrawer { this.adapter = adapter } - get canvas () { + get canvas() { return this._canvas } - set canvas (canvas: HTMLCanvasElement) { + set canvas(canvas: HTMLCanvasElement) { this.ctx = canvas.getContext('2d')! this.ctx.imageSmoothingEnabled = false this.radius = Math.min(canvas.width, canvas.height) / 2 @@ -59,16 +59,16 @@ export class MinimapDrawer { this._canvas = canvas } - get mapSize () { + get mapSize() { return this._mapSize } - set mapSize (mapSize: number) { + set mapSize(mapSize: number) { this._mapSize = mapSize this.draw(this.lastBotPos) } - draw ( + draw( botPos: Vec3, getHighestBlockColor?: DrawerAdapter['getHighestBlockColor'], ) { @@ -83,7 +83,7 @@ export class MinimapDrawer { this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) } - updateWorldColors ( + updateWorldColors( getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], x: number, z: number @@ -115,9 +115,9 @@ export class MinimapDrawer { } } - getHighestBlockColorCached ( - getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], - x: number, + getHighestBlockColorCached( + getHighestBlockColor: DrawerAdapter['getHighestBlockColor'], + x: number, z: number ) { const roundX = Math.floor(x) @@ -131,11 +131,11 @@ export class MinimapDrawer { return color } - getDistance (x1: number, z1: number, x2: number, z2: number): number { + getDistance(x1: number, z1: number, x2: number, z2: number): number { return Math.hypot((x2 - x1), (z2 - z1)) } - deleteOldWorldColors (currX: number, currZ: number) { + deleteOldWorldColors(currX: number, currZ: number) { for (const key of Object.keys(this.worldColors)) { const [x, z] = key.split(',').map(Number) if (this.getDistance(x, z, currX, currZ) > this.radius * 5) { @@ -145,15 +145,34 @@ export class MinimapDrawer { } } - setWarpPosOnClick (e: MouseEvent, botPos: Vec3) { + setWarpPosOnClick(e: MouseEvent, botPos: Vec3) { if (!e.target) return const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const z = (e.pageX - rect.left) * this.canvas.width / rect.width - const x = (e.pageY - rect.top) * this.canvas.height / rect.height + const z = (e.pageX - rect.left) * this.canvas.width / rect.width + const x = (e.pageY - rect.top) * this.canvas.height / rect.height const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 // console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) this.lastWarpPos = new Vec3(Math.floor(botPos.x + worldX), botPos.y, Math.floor(botPos.z + worldZ)) } + + drawWarps() { + for (const warp of this.adapter.warps) { + const distance = this.getDistance( + this.adapter.playerPosition.x, + this.adapter.playerPosition.z, + warp.x, + warp.z + ) + if (distance > this.mapSize * 2/3) continue + const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) + const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) + this.ctx.beginPath() + this.ctx.arc(z, x, 2, 0, Math.PI * 2, false) + this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' + this.ctx.fill() + this.ctx.closePath() + } + } } From 2fc14ec420763ae1c49b4c4257397a3a218b5bb2 Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:03:22 +0400 Subject: [PATCH 034/955] delay for warp on border --- src/react/MinimapDrawer.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index d097c302..c5e56035 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -168,8 +168,15 @@ export class MinimapDrawer { if (distance > this.mapSize * 2/3) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) + const dz = z - this.centerX + const dx = x - this.centerY + const circleDist = Math.sqrt(dx * dx + dz * dz) + + const angle = Math.atan2(dx, dz) + const worldZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.cos(angle) : z + const worldX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() - this.ctx.arc(z, x, 2, 0, Math.PI * 2, false) + this.ctx.arc(worldZ, worldX, 2, 0, Math.PI * 2, false) this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' this.ctx.fill() this.ctx.closePath() From 32a0f4c2204bb68db8dd687eadc9f082a716fafc Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:20:51 +0400 Subject: [PATCH 035/955] fix delay for warp on border --- src/react/MinimapDrawer.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index c5e56035..7fb08363 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -165,18 +165,18 @@ export class MinimapDrawer { warp.x, warp.z ) - if (distance > this.mapSize * 2/3) continue + if (distance > this.mapSize) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.sqrt(dx * dx + dz * dz) - const angle = Math.atan2(dx, dz) - const worldZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.cos(angle) : z - const worldX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x + const angle = Math.atan2(dz, dx) + const circleZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.sin(angle) : z + const circleX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() - this.ctx.arc(worldZ, worldX, 2, 0, Math.PI * 2, false) + this.ctx.arc(circleZ, circleX, circleDist > this.mapSize / 2 ? 1.5 : 2, 0, Math.PI * 2, false) this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' this.ctx.fill() this.ctx.closePath() From a61fc535e2dded3267ba27515a112d329905583a Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:27:19 +0400 Subject: [PATCH 036/955] localServer warps are in provider --- src/react/MinimapProvider.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 5e3b6726..89cee961 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -39,15 +39,13 @@ export class DrawerAdapterImpl extends TypedEventEmitter implements } else { this.warps[index] = warp } - if (localServer) void localServer.setWarp(warp) + // if (localServer) void localServer.setWarp(warp) this.emit('updateWarps') - // console.log('local server warps:', localServer?.warps) - // console.log('adapter warps:', this.warps) } } export default () => { - const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position)) + const [adapter] = useState(() => new DrawerAdapterImpl(bot.entity.position, localServer?.warps)) const updateMap = () => { if (!adapter) return From 65eae1583e244568e1d4eee82cf7133b8119b68c Mon Sep 17 00:00:00 2001 From: gguio Date: Fri, 28 Jun 2024 14:38:12 +0400 Subject: [PATCH 037/955] open map on click --- src/react/Minimap.tsx | 17 ++++++++++++++++- src/react/MinimapDrawer.ts | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/react/Minimap.tsx b/src/react/Minimap.tsx index d8ed7a7d..5b5238d0 100644 --- a/src/react/Minimap.tsx +++ b/src/react/Minimap.tsx @@ -78,6 +78,7 @@ export default ({ adapter, fullMap }: { adapter: DrawerAdapter, fullMap?: boolea return fullMapOpened || fullMap ?
+
{ + toggleFullMap() + }} + >
+ { + toggleFullMap() + }} >
@@ -227,7 +243,6 @@ const WarpInfo = (
} diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index cfa3b4cb..0037b645 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -53,8 +53,9 @@ export class MinimapDrawer { set canvas (canvas: HTMLCanvasElement) { this.ctx = canvas.getContext('2d', { willReadFrequently: true })! this.ctx.imageSmoothingEnabled = false - this.radius = Math.min(canvas.width, canvas.height) / 2 + this.radius = Math.floor(Math.min(canvas.width, canvas.height) / 2.2) this._mapSize = this.radius * 2 + this.mapPixel = Math.floor(this.radius * 2 / this.mapSize) this.centerX = canvas.width / 2 this.centerY = canvas.height / 2 this._canvas = canvas @@ -84,6 +85,7 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) this.drawWarps() + this.drawPartsOfWorld() } updateWorldColors ( @@ -190,20 +192,33 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 this.ctx.stroke() - this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? 'd3d3d3' + this.ctx.fillStyle = warp.disabled ? 'rgba(255, 255, 255, 0.4)' : warp.color ?? '#d3d3d3' this.ctx.fill() this.ctx.closePath() } } drawPartsOfWorld () { - this.ctx.font = '12px serif' + this.ctx.fillStyle = 'white' + this.ctx.shadowOffsetX = 1 + this.ctx.shadowOffsetY = 1 + this.ctx.shadowColor = 'black' + this.ctx.font = `${this.radius / 4}px serif` this.ctx.textAlign = 'center' this.ctx.textBaseline = 'middle' + this.ctx.strokeStyle = 'black' + this.ctx.lineWidth = 1 - this.ctx.fillText('N', this.centerX, 5) - this.ctx.fillText('S', this.centerX, this.centerY - 5) - this.ctx.fillText('W', 5, this.centerY) - this.ctx.fillText('E', this.centerX - 5, this.centerY) + this.ctx.strokeText('W', this.centerX, this.centerY - this.radius) + this.ctx.strokeText('E', this.centerX, this.centerY + this.radius) + this.ctx.strokeText('N', this.centerX - this.radius, this.centerY) + this.ctx.strokeText('S', this.centerX + this.radius, this.centerY) + this.ctx.fillText('W', this.centerX, this.centerY - this.radius) + this.ctx.fillText('E', this.centerX, this.centerY + this.radius) + this.ctx.fillText('N', this.centerX - this.radius, this.centerY) + this.ctx.fillText('S', this.centerX + this.radius, this.centerY) + + this.ctx.shadowOffsetX = 0 + this.ctx.shadowOffsetY = 0 } } From b357ea2e6ee8c7c8b5726ec0d77f6a31d42a6d83 Mon Sep 17 00:00:00 2001 From: gguio Date: Tue, 2 Jul 2024 22:10:01 +0400 Subject: [PATCH 042/955] mirror x axis --- src/react/MinimapDrawer.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 0037b645..8deb742d 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -106,7 +106,7 @@ export class MinimapDrawer { for (let col = 0; col < this.mapSize; col += 1) { this.ctx.fillStyle = this.getHighestBlockColorCached( getHighestBlockColor, - x - this.mapSize / 2 + row, + x - this.mapSize / 2 + this.mapSize - row, z - this.mapSize / 2 + col ) this.ctx.fillRect( @@ -119,11 +119,8 @@ export class MinimapDrawer { } const clippedImage = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height) - this.ctx.restore() - this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) - this.ctx.putImageData(clippedImage, 0, 0) } @@ -162,7 +159,7 @@ export class MinimapDrawer { const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() const z = (e.pageX - rect.left) * this.canvas.width / rect.width const x = (e.pageY - rect.top) * this.canvas.height / rect.height - const worldX = x - this.mapSize / 2 + const worldX = -1 * x + this.mapSize / 2 const worldZ = z - this.mapSize / 2 // console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) @@ -179,7 +176,7 @@ export class MinimapDrawer { ) if (distance > this.mapSize) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) - const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) + const x = Math.floor((this.mapSize / 2 + this.adapter.playerPosition.x - warp.x)) const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.hypot(dx, dz) @@ -209,12 +206,12 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - this.ctx.strokeText('W', this.centerX, this.centerY - this.radius) - this.ctx.strokeText('E', this.centerX, this.centerY + this.radius) + this.ctx.strokeText('E', this.centerX, this.centerY - this.radius) + this.ctx.strokeText('W', this.centerX, this.centerY + this.radius) this.ctx.strokeText('N', this.centerX - this.radius, this.centerY) this.ctx.strokeText('S', this.centerX + this.radius, this.centerY) - this.ctx.fillText('W', this.centerX, this.centerY - this.radius) - this.ctx.fillText('E', this.centerX, this.centerY + this.radius) + this.ctx.fillText('E', this.centerX, this.centerY - this.radius) + this.ctx.fillText('W', this.centerX, this.centerY + this.radius) this.ctx.fillText('N', this.centerX - this.radius, this.centerY) this.ctx.fillText('S', this.centerX + this.radius, this.centerY) From d35db9a9a565be9272a4e59a19df679b367f7353 Mon Sep 17 00:00:00 2001 From: gguio Date: Wed, 3 Jul 2024 13:12:18 +0400 Subject: [PATCH 043/955] fixed drawing direction --- src/react/MinimapDrawer.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 8deb742d..c33b8bb0 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -84,8 +84,8 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) - this.drawWarps() this.drawPartsOfWorld() + this.drawWarps() } updateWorldColors ( @@ -106,8 +106,8 @@ export class MinimapDrawer { for (let col = 0; col < this.mapSize; col += 1) { this.ctx.fillStyle = this.getHighestBlockColorCached( getHighestBlockColor, - x - this.mapSize / 2 + this.mapSize - row, - z - this.mapSize / 2 + col + x - this.mapSize / 2 + col, + z - this.mapSize / 2 + row ) this.ctx.fillRect( left + this.mapPixel * col, @@ -157,9 +157,9 @@ export class MinimapDrawer { setWarpPosOnClick (e: MouseEvent, botPos: Vec3) { if (!e.target) return const rect = (e.target as HTMLCanvasElement).getBoundingClientRect() - const z = (e.pageX - rect.left) * this.canvas.width / rect.width - const x = (e.pageY - rect.top) * this.canvas.height / rect.height - const worldX = -1 * x + this.mapSize / 2 + const z = (e.pageY - rect.top) * this.canvas.width / rect.width + const x = (e.pageX - rect.left) * this.canvas.height / rect.height + const worldX = x - this.mapSize / 2 const worldZ = z - this.mapSize / 2 // console.log([(botPos.x + worldX).toFixed(0), (botPos.z + worldZ).toFixed(0)]) @@ -176,7 +176,7 @@ export class MinimapDrawer { ) if (distance > this.mapSize) continue const z = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.z + warp.z)) - const x = Math.floor((this.mapSize / 2 + this.adapter.playerPosition.x - warp.x)) + const x = Math.floor((this.mapSize / 2 - this.adapter.playerPosition.x + warp.x)) const dz = z - this.centerX const dx = x - this.centerY const circleDist = Math.hypot(dx, dz) @@ -185,7 +185,7 @@ export class MinimapDrawer { const circleZ = circleDist > this.mapSize / 2 ? this.centerX + this.mapSize / 2 * Math.sin(angle) : z const circleX = circleDist > this.mapSize / 2 ? this.centerY + this.mapSize / 2 * Math.cos(angle) : x this.ctx.beginPath() - this.ctx.arc(circleZ, circleX, circleDist > this.mapSize / 2 ? 1.5 : 2, 0, Math.PI * 2, false) + this.ctx.arc(circleX, circleZ, circleDist > this.mapSize / 2 ? 1.5 : 2, 0, Math.PI * 2, false) this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 this.ctx.stroke() @@ -206,14 +206,14 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - this.ctx.strokeText('E', this.centerX, this.centerY - this.radius) - this.ctx.strokeText('W', this.centerX, this.centerY + this.radius) - this.ctx.strokeText('N', this.centerX - this.radius, this.centerY) - this.ctx.strokeText('S', this.centerX + this.radius, this.centerY) - this.ctx.fillText('E', this.centerX, this.centerY - this.radius) - this.ctx.fillText('W', this.centerX, this.centerY + this.radius) - this.ctx.fillText('N', this.centerX - this.radius, this.centerY) - this.ctx.fillText('S', this.centerX + this.radius, this.centerY) + this.ctx.strokeText('N', this.centerX, this.centerY - this.radius) + this.ctx.strokeText('S', this.centerX, this.centerY + this.radius) + this.ctx.strokeText('W', this.centerX - this.radius, this.centerY) + this.ctx.strokeText('E', this.centerX + this.radius, this.centerY) + this.ctx.fillText('N', this.centerX, this.centerY - this.radius) + this.ctx.fillText('S', this.centerX, this.centerY + this.radius) + this.ctx.fillText('W', this.centerX - this.radius, this.centerY) + this.ctx.fillText('E', this.centerX + this.radius, this.centerY) this.ctx.shadowOffsetX = 0 this.ctx.shadowOffsetY = 0 From 5f4a57234711ba94b9694fcabe86cf6f8c032134 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 4 Jul 2024 00:23:02 +0400 Subject: [PATCH 044/955] map rotation --- src/react/Minimap.stories.tsx | 1 + src/react/MinimapDrawer.ts | 10 ++++++++++ src/react/MinimapProvider.tsx | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/react/Minimap.stories.tsx b/src/react/Minimap.stories.tsx index d55f809a..3ecdf9b5 100644 --- a/src/react/Minimap.stories.tsx +++ b/src/react/Minimap.stories.tsx @@ -30,6 +30,7 @@ type Story = StoryObj; class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 + yaw: number warps: WorldWarp[] constructor (pos?: Vec3, warps?: WorldWarp[]) { diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index c33b8bb0..88772258 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -23,6 +23,7 @@ export interface DrawerAdapter extends TypedEventEmitter { playerPosition: Vec3 warps: WorldWarp[] world?: string + yaw: number setWarp: (name: string, pos: Vec3, color: string, disabled: boolean, world?: string) => void } @@ -86,6 +87,7 @@ export class MinimapDrawer { this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) this.drawPartsOfWorld() this.drawWarps() + this.rotateMap() } updateWorldColors ( @@ -218,4 +220,12 @@ export class MinimapDrawer { this.ctx.shadowOffsetX = 0 this.ctx.shadowOffsetY = 0 } + + rotateMap () { + this.ctx.setTransform(1, 0, 0, 1, 0, 0) + const angle = this.adapter.yaw % Math.PI + this.ctx.translate(this.centerX, this.centerY) + this.ctx.rotate(angle) + this.ctx.translate(-this.centerX, -this.centerY) + } } diff --git a/src/react/MinimapProvider.tsx b/src/react/MinimapProvider.tsx index 89cee961..5e56e585 100644 --- a/src/react/MinimapProvider.tsx +++ b/src/react/MinimapProvider.tsx @@ -9,6 +9,7 @@ import { DrawerAdapter, MapUpdates } from './MinimapDrawer' export class DrawerAdapterImpl extends TypedEventEmitter implements DrawerAdapter { playerPosition: Vec3 + yaw: number warps: WorldWarp[] world: string @@ -50,6 +51,7 @@ export default () => { const updateMap = () => { if (!adapter) return adapter.playerPosition = bot.entity.position + adapter.yaw = bot.entity.yaw adapter.emit('updateMap') } From 1bd85346505bf94c2e3d3023eb0159f894ca2283 Mon Sep 17 00:00:00 2001 From: gguio Date: Thu, 4 Jul 2024 00:52:05 +0400 Subject: [PATCH 045/955] map rotation. Fixes required: drawing has flaws + parts of world --- src/react/MinimapDrawer.ts | 55 +++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/react/MinimapDrawer.ts b/src/react/MinimapDrawer.ts index 88772258..eddc338e 100644 --- a/src/react/MinimapDrawer.ts +++ b/src/react/MinimapDrawer.ts @@ -85,9 +85,9 @@ export class MinimapDrawer { this.lastBotPos = botPos this.updateWorldColors(getHighestBlockColor ?? this.adapter.getHighestBlockColor, botPos.x, botPos.z) - this.drawPartsOfWorld() this.drawWarps() this.rotateMap() + this.drawPartsOfWorld() } updateWorldColors ( @@ -208,14 +208,51 @@ export class MinimapDrawer { this.ctx.strokeStyle = 'black' this.ctx.lineWidth = 1 - this.ctx.strokeText('N', this.centerX, this.centerY - this.radius) - this.ctx.strokeText('S', this.centerX, this.centerY + this.radius) - this.ctx.strokeText('W', this.centerX - this.radius, this.centerY) - this.ctx.strokeText('E', this.centerX + this.radius, this.centerY) - this.ctx.fillText('N', this.centerX, this.centerY - this.radius) - this.ctx.fillText('S', this.centerX, this.centerY + this.radius) - this.ctx.fillText('W', this.centerX - this.radius, this.centerY) - this.ctx.fillText('E', this.centerX + this.radius, this.centerY) + const angle = this.adapter.yaw % Math.PI + const angleS = angle + Math.PI + const angleW = angle + Math.PI * 3 / 2 + const angleE = angle + Math.PI / 2 + + this.ctx.strokeText( + 'N', + this.centerX + this.radius * Math.cos(angle), + this.centerY + this.radius * Math.sin(angle) + ) + this.ctx.strokeText( + 'S', + this.centerX + this.radius * Math.cos(angleS), + this.centerY + this.radius * Math.sin(angleS) + ) + this.ctx.strokeText( + 'W', + this.centerX + this.radius * Math.cos(angleW), + this.centerY + this.radius * Math.sin(angleW) + ) + this.ctx.strokeText( + 'E', + this.centerX + this.radius * Math.cos(angleE), + this.centerY + this.radius * Math.sin(angleE) + ) + this.ctx.fillText( + 'N', + this.centerX + this.radius * Math.cos(angle), + this.centerY + this.radius * Math.sin(angle) + ) + this.ctx.fillText( + 'S', + this.centerX + this.radius * Math.cos(angleS), + this.centerY + this.radius * Math.sin(angleS) + ) + this.ctx.fillText( + 'W', + this.centerX + this.radius * Math.cos(angleW), + this.centerY + this.radius * Math.sin(angleW) + ) + this.ctx.fillText( + 'E', + this.centerX + this.radius * Math.cos(angleE), + this.centerY + this.radius * Math.sin(angleE) + ) this.ctx.shadowOffsetX = 0 this.ctx.shadowOffsetY = 0 From 4127bf716986890d35f146000b88ffd173fc0d07 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sun, 7 Jul 2024 17:50:06 +0300 Subject: [PATCH 046/955] add test fullscreen map --- src/react/FullScreenMap.stories.tsx | 18 ++++ src/react/FullScreenMap.tsx | 132 ++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/react/FullScreenMap.stories.tsx create mode 100644 src/react/FullScreenMap.tsx diff --git a/src/react/FullScreenMap.stories.tsx b/src/react/FullScreenMap.stories.tsx new file mode 100644 index 00000000..54b7084a --- /dev/null +++ b/src/react/FullScreenMap.stories.tsx @@ -0,0 +1,18 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import FullScreenMap from './FullScreenMap' + +const meta: Meta = { + component: FullScreenMap +} + +export default meta +type Story = StoryObj + +export const Primary: Story = { + args: { + }, + parameters: { + noScaling: true + }, +} diff --git a/src/react/FullScreenMap.tsx b/src/react/FullScreenMap.tsx new file mode 100644 index 00000000..a0366722 --- /dev/null +++ b/src/react/FullScreenMap.tsx @@ -0,0 +1,132 @@ +import { useEffect, useRef } from 'react' +import * as THREE from 'three' +import { DragGesture, WheelGesture, ScrollGesture, MoveGesture, PinchGesture } from '@use-gesture/vanilla' +import Gesto from 'gesto' + +export default () => { + const ref = useRef(null) + + useEffect(() => { + const canvas = ref.current! + const { scene, camera, renderer, addCube, onDestroy } = initScene(canvas) + + // const size = 16 * 4 * 1 + const size = 10 + for (let x = -size / 2; x < size / 2; x++) { + for (let z = -size / 2; z < size / 2; z++) { + addCube(x, z) + } + } + return () => { + renderer.dispose() + onDestroy() + } + }, []) + + return +} + +const initScene = (canvas: HTMLCanvasElement) => { + const abortController = new AbortController() + + const renderer = new THREE.WebGLRenderer({ canvas }) + renderer.setSize(window.innerWidth, window.innerHeight) + renderer.setPixelRatio(window.devicePixelRatio || 1) + renderer.setClearColor(0x000000, 1) + + const scene = new THREE.Scene() + const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000) + + camera.position.set(0, 80, 0) + // look down + camera.rotation.set(-Math.PI / 2, 0, 0, 'ZYX') + + + const onResize = () => { + renderer.setSize(window.innerWidth, window.innerHeight) + camera.aspect = window.innerWidth / window.innerHeight + camera.updateProjectionMatrix() + } + window.addEventListener('resize', onResize, { signal: abortController.signal }) + onResize() + + let debugText = 'test' + const debugTextEl = document.createElement('div') + debugTextEl.style.position = 'fixed' + debugTextEl.style.top = '0' + debugTextEl.style.left = '0' + debugTextEl.style.background = 'rgba(0, 0, 0, 0.5)' + debugTextEl.style.color = 'white' + debugTextEl.style.fontSize = '10px' + debugTextEl.style.padding = '5px' + document.body.appendChild(debugTextEl) + + renderer.setAnimationLoop(() => { + renderer.render(scene, camera) + debugTextEl.innerText = debugText + }) + + // register controls + + const gestures = [] as { destroy: () => void }[] + const gesture = new DragGesture(canvas, ({ movement: [mx, my] }) => { + camera.position.x -= mx * 0.001 + camera.position.z -= my * 0.001 + }) + const wheel = new WheelGesture(canvas, ({ delta: [dx, dy] }) => { + camera.position.y += dy * 0.01 + }) + const pinch = new PinchGesture(canvas, ({ delta, movement: [ox, oy], pinching, origin }) => { + console.log([ox, oy], delta, pinching, origin) + }) + gestures.push(wheel) + gestures.push(gesture) + + let scale = 1 + // const gesto = new Gesto(canvas, { + // container: window, + // pinchOutside: true, + // }).on('drag', ({ deltaX, deltaY }) => { + // camera.position.x -= deltaX * 0.01 + // camera.position.z -= deltaY * 0.01 + // }).on('pinchStart', (e) => { + // e.datas.scale = scale + // }).on('pinch', ({ datas: { scale: newScale } }) => { + // scale = newScale + // console.log(scale) + // camera.position.y += newScale * 0.01 + // }) + + + return { + scene, + camera, + renderer, + onDestroy: () => { + abortController.abort() + for (const gesture of gestures) { + gesture.destroy() + } + // gesto.unset() + }, + addCube (x, z) { + const geometry = new THREE.BoxGeometry(1, 1, 1) + const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }) + const cube = new THREE.Mesh(geometry, material) + cube.position.set(x, 0, z) + scene.add(cube) + } + } +} + +document.addEventListener('gesturestart', (e) => e.preventDefault()) +document.addEventListener('gesturechange', (e) => e.preventDefault()) From d8261c2659acd6f90e6d95decbd45b665a7aac2d Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sun, 7 Jul 2024 19:18:48 +0300 Subject: [PATCH 047/955] fix: bundle pixealrticons with the app instead of fetching them from remote location in runtime --- .storybook/preview.tsx | 8 +- README.MD | 12 +- esbuild.mjs | 3 + package.json | 5 +- patches/pixelarticons@1.8.1.patch | 27 + pnpm-lock.yaml | 26 +- scripts/genPixelartTypes.ts | 16 + src/index.ts | 1 - src/packetsPatcher.ts | 16 +- src/react/Button.tsx | 5 +- src/react/ConceptCommandsGui.stories.tsx | 3 +- src/react/IndicatorEffects.stories.tsx | 12 +- src/react/KeybindingsScreen.tsx | 21 +- src/react/MainMenu.tsx | 5 +- src/react/PixelartIcon.tsx | 22 +- src/react/ServersList.stories.tsx | 1 - src/react/globals.d.ts | 9 +- src/react/pixelartIcons.generated.ts | 974 +++++++++++++++++++++++ src/styles.css | 5 + 19 files changed, 1102 insertions(+), 69 deletions(-) create mode 100644 patches/pixelarticons@1.8.1.patch create mode 100644 scripts/genPixelartTypes.ts create mode 100644 src/react/pixelartIcons.generated.ts diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index a8a219f1..74b0f05c 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,6 +1,6 @@ import React from 'react' -import type { Preview } from "@storybook/react"; +import type { Preview } from "@storybook/react" import '../src/styles.css' import './storybook.css' @@ -11,7 +11,7 @@ const preview: Preview = { const noScaling = c.parameters.noScaling return
-
; +
}, ], parameters: { @@ -23,6 +23,6 @@ const preview: Preview = { }, }, }, -}; +} -export default preview; +export default preview diff --git a/README.MD b/README.MD index ad120dbf..9a4ba24a 100644 --- a/README.MD +++ b/README.MD @@ -4,14 +4,14 @@ A true Minecraft client running in your browser! A port of the original game to the web, written in JavaScript using modern web technologies. -If you encounter any bugs or usability issues, please report them! +If you encounter any bugs or usability issues, please report them! For development, see [development](#development--debugging). You can try this out at [mcraft.fun](https://mcraft.fun/), [pcm.gg](https://pcm.gg) (short link) [mcon.vercel.app](https://mcon.vercel.app/) or the GitHub pages deploy. Every commit from the `develop` (default) branch is deployed to [s.mcraft.fun](https://s.mcraft.fun/) - so it's usually newer, but might be less stable. ### Big Features - Open any zip world file or even folder in read-write mode! -- Connect to cracked servers* (it's possible because of proxy servers, see below) +- Connect to Java servers running in both offline (cracked) and online mode* (it's possible because of proxy servers, see below) - Singleplayer mode with simple world generations! - Works offline - Play with friends over internet! (P2P is powered by Peer.js discovery servers) @@ -39,9 +39,9 @@ Whatever offline mode you used (zip, folder, just single player), you can always ### Servers -You can play almost on any server, supporting offline connections. +You can play almost on any Java server, vanilla servers are fully supported. See the [Mineflayer](https://github.com/PrismarineJS/mineflayer) repo for the list of supported versions (should support majority of versions). -There is a builtin proxy, but you can also host a your one! Just clone the repo, run `pnpm i` (following CONTRIBUTING.MD) and run `pnpm prod-start`, then you can specify `http://localhost:8080` in the proxy field. +There is a builtin proxy, but you can also host your one! Just clone the repo, run `pnpm i` (following CONTRIBUTING.MD) and run `pnpm prod-start`, then you can specify `http://localhost:8080` in the proxy field. MS account authentication will be supported soon. ### Rendering @@ -67,9 +67,9 @@ There are many many settings, that are not exposed in the UI yet. You can find o To open the console, press `F12`, or if you are on mobile, you can type `#debug` in the URL (browser address bar), it wont't reload the page, but you will see a button to open the console. This way you can change advanced settings and see all errors or warnings. Also this way you can access global variables (described below). -### Debugging +### Development & Debugging -It should be easy to build/start the project locally. See [CONTRIBUTING.MD](./CONTRIBUTING.md) for more info. +It should be easy to build/start the project locally. See [CONTRIBUTING.MD](./CONTRIBUTING.md) for more info. Also you can look at Dockerfile for reference. There is world renderer playground ([link](https://mcon.vercel.app/playground.html)). diff --git a/esbuild.mjs b/esbuild.mjs index 28b233bf..1f075a62 100644 --- a/esbuild.mjs +++ b/esbuild.mjs @@ -85,6 +85,9 @@ const buildOptions = { '.vert': 'text', '.frag': 'text', '.obj': 'text', + '.woff': 'dataurl', + '.woff2': 'dataurl', + '.ttf': 'dataurl', }, write: false, // todo would be better to enable? diff --git a/package.json b/package.json index 5bf32a69..07e9ff0b 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,6 @@ "flying-squid": "npm:@zardoy/flying-squid@^0.0.33", "fs-extra": "^11.1.1", "google-drive-browserfs": "github:zardoy/browserfs#google-drive", - "iconify-icon": "^1.0.8", "jszip": "^3.10.1", "lodash-es": "^4.17.21", "minecraft-assets": "^1.12.2", @@ -77,6 +76,7 @@ "net-browserify": "github:zardoy/prismarinejs-net-browserify", "node-gzip": "^1.1.2", "peerjs": "^1.5.0", + "pixelarticons": "^1.8.1", "pretty-bytes": "^6.1.1", "prismarine-provider-anvil": "github:zardoy/prismarine-provider-anvil#everything", "prosemirror-example-setup": "^1.2.2", @@ -169,7 +169,8 @@ }, "patchedDependencies": { "minecraft-protocol@1.47.0": "patches/minecraft-protocol@1.47.0.patch", - "three@0.154.0": "patches/three@0.154.0.patch" + "three@0.154.0": "patches/three@0.154.0.patch", + "pixelarticons@1.8.1": "patches/pixelarticons@1.8.1.patch" } }, "packageManager": "pnpm@9.0.4" diff --git a/patches/pixelarticons@1.8.1.patch b/patches/pixelarticons@1.8.1.patch new file mode 100644 index 00000000..10044536 --- /dev/null +++ b/patches/pixelarticons@1.8.1.patch @@ -0,0 +1,27 @@ +diff --git a/fonts/pixelart-icons-font.css b/fonts/pixelart-icons-font.css +index 3b2ebe839370d96bf93ef5ca94a827f07e49378d..103ab4d6b9f3b5c9f41d1407e3cbf4ac392fbf41 100644 +--- a/fonts/pixelart-icons-font.css ++++ b/fonts/pixelart-icons-font.css +@@ -1,16 +1,13 @@ + @font-face { + font-family: "pixelart-icons-font"; +- src: url('pixelart-icons-font.eot?t=1711815892278'); /* IE9*/ +- src: url('pixelart-icons-font.eot?t=1711815892278#iefix') format('embedded-opentype'), /* IE6-IE8 */ ++ src: + url("pixelart-icons-font.woff2?t=1711815892278") format("woff2"), + url("pixelart-icons-font.woff?t=1711815892278") format("woff"), + url('pixelart-icons-font.ttf?t=1711815892278') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ +- url('pixelart-icons-font.svg?t=1711815892278#pixelart-icons-font') format('svg'); /* iOS 4.1- */ + } + + [class^="pixelart-icons-font-"], [class*=" pixelart-icons-font-"] { + font-family: 'pixelart-icons-font' !important; +- font-size:24px; + font-style:normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +@@ -503,4 +500,3 @@ + .pixelart-icons-font-zap:before { content: "\ebe4"; } + .pixelart-icons-font-zoom-in:before { content: "\ebe5"; } + .pixelart-icons-font-zoom-out:before { content: "\ebe6"; } +- diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf890476..2208e681 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ patchedDependencies: minecraft-protocol@1.47.0: hash: 7otpchsbv7hxsuis4rrrwdtbve path: patches/minecraft-protocol@1.47.0.patch + pixelarticons@1.8.1: + hash: cclg2qo6d4yjs4evj64nr2mbwa + path: patches/pixelarticons@1.8.1.patch three@0.154.0: hash: sj7ocb4p23jym6bkfgueanti2e path: patches/three@0.154.0.patch @@ -115,9 +118,6 @@ importers: google-drive-browserfs: specifier: github:zardoy/browserfs#google-drive version: browserfs@https://codeload.github.com/zardoy/browserfs/tar.gz/ab58ae8ef00e3a31db01909e365e6cb5188436e0 - iconify-icon: - specifier: ^1.0.8 - version: 1.0.8 jszip: specifier: ^3.10.1 version: 3.10.1 @@ -148,6 +148,9 @@ importers: peerjs: specifier: ^1.5.0 version: 1.5.0 + pixelarticons: + specifier: ^1.8.1 + version: 1.8.1(patch_hash=cclg2qo6d4yjs4evj64nr2mbwa) pretty-bytes: specifier: ^6.1.1 version: 6.1.1 @@ -1723,9 +1726,6 @@ packages: '@humanwhocodes/object-schema@1.2.1': resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - '@iconify/types@2.0.0': - resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -5158,9 +5158,6 @@ packages: hyphenate-style-name@1.0.4: resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} - iconify-icon@1.0.8: - resolution: {integrity: sha512-jvbUKHXf8EnGGArmhlP2IG8VqQLFFyTvTqb9LVL2TKTh7/eCCD1o2HHE9thpbJJb6B8hzhcFb6rOKhvo7reNKA==} - iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -6633,6 +6630,9 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + pixelarticons@1.8.1: + resolution: {integrity: sha512-4taoDCleft9RtzVHLA73VDnRBwJNqlwbW8ShO6S0G9b+bM5ArGe1MVFW9xpromuPvQgVUYCSjRxNAQuNtADqyA==} + pixelmatch@4.0.2: resolution: {integrity: sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==} hasBin: true @@ -9985,8 +9985,6 @@ snapshots: '@humanwhocodes/object-schema@1.2.1': {} - '@iconify/types@2.0.0': {} - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -14722,10 +14720,6 @@ snapshots: hyphenate-style-name@1.0.4: {} - iconify-icon@1.0.8: - dependencies: - '@iconify/types': 2.0.0 - iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -16433,6 +16427,8 @@ snapshots: pirates@4.0.6: {} + pixelarticons@1.8.1(patch_hash=cclg2qo6d4yjs4evj64nr2mbwa): {} + pixelmatch@4.0.2: dependencies: pngjs: 3.4.0 diff --git a/scripts/genPixelartTypes.ts b/scripts/genPixelartTypes.ts new file mode 100644 index 00000000..e7c9649a --- /dev/null +++ b/scripts/genPixelartTypes.ts @@ -0,0 +1,16 @@ +import fs from 'fs' + +const icons = fs.readdirSync('node_modules/pixelarticons/svg') + +const addIconPath = '../../node_modules/pixelarticons/svg/' + +let str = 'export type PixelartIconsGenerated = {\n' +for (const icon of icons) { + const name = icon.replace('.svg', '') + // jsdoc + const jsdocImage = '![image](' + addIconPath + icon + ')' + str += ` /** ${jsdocImage} */\n` + str += ` '${name}': string;\n` +} +str += '}\n' +fs.writeFileSync('./src/react/pixelartIcons.generated.ts', str, 'utf8') diff --git a/src/index.ts b/src/index.ts index e73e8240..e34e81ab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,6 @@ import './importsWorkaround' import './styles.css' import './globals' -import 'iconify-icon' import './devtools' import './entities' import './globalDomListeners' diff --git a/src/packetsPatcher.ts b/src/packetsPatcher.ts index f877d6ed..587c41c9 100644 --- a/src/packetsPatcher.ts +++ b/src/packetsPatcher.ts @@ -2,13 +2,13 @@ // todo these fixes should be ported to mineflayer export default () => { - customEvents.on('mineflayerBotCreated', () => { - bot._client.on('packet', (data, meta) => { - if (meta.name === 'map_chunk') { - if (data.groundUp && data.bitMap === 1 && data.chunkData.every(x => x === 0)) { - data.chunkData = Buffer.from(Array.from({ length: 12_544 }).fill(0) as any) - } - } - }) + customEvents.on('mineflayerBotCreated', () => { + bot._client.on('packet', (data, meta) => { + if (meta.name === 'map_chunk') { + if (data.groundUp && data.bitMap === 1 && data.chunkData.every(x => x === 0)) { + data.chunkData = Buffer.from(Array.from({ length: 12_544 }).fill(0) as any) + } + } }) + }) } diff --git a/src/react/Button.tsx b/src/react/Button.tsx index 20dc0801..10ff2fb0 100644 --- a/src/react/Button.tsx +++ b/src/react/Button.tsx @@ -2,6 +2,7 @@ import classNames from 'classnames' import { createContext, FC, Ref, useContext } from 'react' import buttonCss from './button.module.css' import SharedHudVars from './SharedHudVars' +import PixelartIcon from './PixelartIcon' // testing in storybook from deathscreen @@ -17,7 +18,7 @@ const ButtonContext = createContext({ onClick () { }, }) -export const ButtonProvider: FC<{children, onClick}> = ({ children, onClick }) => { +export const ButtonProvider: FC<{ children, onClick }> = ({ children, onClick }) => { return {children} } @@ -39,7 +40,7 @@ export default (({ label, icon, children, inScreen, rootRef, type = 'button', .. return diff --git a/src/react/ConceptCommandsGui.stories.tsx b/src/react/ConceptCommandsGui.stories.tsx index 89cb6eff..4f3586d4 100644 --- a/src/react/ConceptCommandsGui.stories.tsx +++ b/src/react/ConceptCommandsGui.stories.tsx @@ -11,7 +11,6 @@ const Button2 = ({ title, icon }) => {
{title}
- {/* { // const sessionEndpoint = 'http://localhost:3000/session' let authEndpoint = '' let sessionEndpoint = '' + if (!proxyBaseUrl.startsWith('http')) proxyBaseUrl = `${isPageSecure() ? 'https' : 'http'}://${proxyBaseUrl}` + const url = proxyBaseUrl + '/api/vm/net/connect' + let result: Response + try { + result = await fetch(url) + } catch (err) { + throw new Error(`Selected proxy server ${proxyBaseUrl} most likely is down`) + } try { - if (!proxyBaseUrl.startsWith('http')) proxyBaseUrl = `${isPageSecure() ? 'https' : 'http'}://${proxyBaseUrl}` - const url = proxyBaseUrl + '/api/vm/net/connect' - const result = await fetch(url) const json = await result.json() authEndpoint = urlWithBase(json.capabilities.authEndpoint, proxyBaseUrl) sessionEndpoint = urlWithBase(json.capabilities.sessionEndpoint, proxyBaseUrl) diff --git a/src/react/AppStatus.tsx b/src/react/AppStatus.tsx index 10cc5793..9ebecf93 100644 --- a/src/react/AppStatus.tsx +++ b/src/react/AppStatus.tsx @@ -28,6 +28,7 @@ export default ({ status, isError, hideDots = false, lastStatus = '', backAction return ( diff --git a/src/react/Chat.css b/src/react/Chat.css index 41917783..cba0a1aa 100644 --- a/src/react/Chat.css +++ b/src/react/Chat.css @@ -24,6 +24,13 @@ div.chat-wrapper { left: 1px; box-sizing: border-box; background-color: rgba(0, 0, 0, 0); + display: flex; + align-items: center; + gap: 1px; +} + +.chat-input-wrapper form { + display: flex; } .chat-input { @@ -103,7 +110,8 @@ div.chat-wrapper { } .input-mobile #chatinput { - height: 20px; + height: 24px; + font-size: 13px; } .display-mobile { diff --git a/src/react/Chat.tsx b/src/react/Chat.tsx index 89b2aa8b..60467171 100644 --- a/src/react/Chat.tsx +++ b/src/react/Chat.tsx @@ -4,6 +4,8 @@ import { MessageFormatPart } from '../botUtils' import { MessagePart } from './MessageFormatted' import './Chat.css' import { isIos, reactKeyForMessage } from './utils' +import Button from './Button' +import { pixelartIcons } from './PixelartIcon' export type Message = { parts: MessageFormatPart[], @@ -221,6 +223,8 @@ export default ({
diff --git a/src/react/EnterFullscreenButton.tsx b/src/react/EnterFullscreenButton.tsx index ad78ddad..3901b9ae 100644 --- a/src/react/EnterFullscreenButton.tsx +++ b/src/react/EnterFullscreenButton.tsx @@ -1,6 +1,11 @@ import { useEffect, useState } from 'react' +import { useSnapshot } from 'valtio' +import { activeModalStack, miscUiState } from '../globalState' import Button from './Button' import { useUsingTouch } from './utilsApp' +import { pixelartIcons } from './PixelartIcon' + +const hideOnModals = new Set(['chat']) export default () => { const [fullScreen, setFullScreen] = useState(false) @@ -9,16 +14,23 @@ export default () => { setFullScreen(!!document.fullscreenElement) }) }, []) + const { gameLoaded } = useSnapshot(miscUiState) + + const activeStack = useSnapshot(activeModalStack) + + const inMainMenu = activeStack.length === 0 && !gameLoaded const usingTouch = useUsingTouch() - if (!usingTouch || !document.documentElement.requestFullscreen || fullScreen) return null + const hideButton = activeStack.some(x => hideOnModals.has(x.reactType)) + + if (hideButton || !usingTouch || !document.documentElement.requestFullscreen || fullScreen) return null return + {!lockConnect && <> + + }
} From d02008c2ef4bfff93fad0edbeaffca3d60399bcc Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Thu, 11 Jul 2024 18:33:16 +0300 Subject: [PATCH 057/955] fix(regression): signs lighting was compltely broken --- prismarine-viewer/viewer/lib/mesher/models.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prismarine-viewer/viewer/lib/mesher/models.ts b/prismarine-viewer/viewer/lib/mesher/models.ts index ab77d516..c978c240 100644 --- a/prismarine-viewer/viewer/lib/mesher/models.ts +++ b/prismarine-viewer/viewer/lib/mesher/models.ts @@ -624,7 +624,7 @@ export function getSectionGeometry (sx, sy, sz, world: World) { delete attr.t_uvs attr.positions = new Float32Array(attr.positions) as any - attr.normals = new Int8Array(attr.normals) as any + attr.normals = new Float32Array(attr.normals) as any attr.colors = new Float32Array(attr.colors) as any attr.uvs = new Float32Array(attr.uvs) as any From d0205a970b823ed49e4a01dea237e175a096d777 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Thu, 11 Jul 2024 20:08:10 +0300 Subject: [PATCH 058/955] up mineflayer for better vehicle move --- pnpm-lock.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 45ebdda4..9d370f17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -314,7 +314,7 @@ importers: version: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/c50afc54e39817f7e4d313ce0f6fdaad71e7e4f4(@types/react@18.2.20)(react@18.2.0) mineflayer: specifier: github:zardoy/mineflayer - version: https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479(encoding@0.1.13) + version: https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848(encoding@0.1.13) mineflayer-pathfinder: specifier: ^2.4.4 version: 2.4.4 @@ -6086,8 +6086,8 @@ packages: resolution: {integrity: sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==} engines: {node: '>=18'} - mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479: - resolution: {tarball: https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479} + mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848: + resolution: {tarball: https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848} version: 4.20.1 engines: {node: '>=18'} @@ -15825,7 +15825,7 @@ snapshots: - encoding - supports-color - mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/dddc683544317f117172077a9245a07be1b12479(encoding@0.1.13): + mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848(encoding@0.1.13): dependencies: minecraft-data: 3.65.0 minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13) From 07002a743748899f58767011c3bf99da2658c63b Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sat, 13 Jul 2024 05:49:38 +0300 Subject: [PATCH 059/955] fix: remove entities from the scene on login packet (usually on the world switch) --- pnpm-lock.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d370f17..9deb9a7e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -314,7 +314,7 @@ importers: version: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/c50afc54e39817f7e4d313ce0f6fdaad71e7e4f4(@types/react@18.2.20)(react@18.2.0) mineflayer: specifier: github:zardoy/mineflayer - version: https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848(encoding@0.1.13) + version: https://codeload.github.com/zardoy/mineflayer/tar.gz/7f65e46a048f1bc2b57775d84b32400dce707321(encoding@0.1.13) mineflayer-pathfinder: specifier: ^2.4.4 version: 2.4.4 @@ -6086,8 +6086,8 @@ packages: resolution: {integrity: sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==} engines: {node: '>=18'} - mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848: - resolution: {tarball: https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848} + mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/7f65e46a048f1bc2b57775d84b32400dce707321: + resolution: {tarball: https://codeload.github.com/zardoy/mineflayer/tar.gz/7f65e46a048f1bc2b57775d84b32400dce707321} version: 4.20.1 engines: {node: '>=18'} @@ -15825,7 +15825,7 @@ snapshots: - encoding - supports-color - mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/c03c76ef2acfc747bfe8cd1e290106c81f399848(encoding@0.1.13): + mineflayer@https://codeload.github.com/zardoy/mineflayer/tar.gz/7f65e46a048f1bc2b57775d84b32400dce707321(encoding@0.1.13): dependencies: minecraft-data: 3.65.0 minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/495eed56ab230b2615596590064671356d86a2dc(patch_hash=7otpchsbv7hxsuis4rrrwdtbve)(encoding@0.1.13) From 04b5d1ac3f03e5053df6a6142ede7d0c4539d480 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sat, 13 Jul 2024 06:17:47 +0300 Subject: [PATCH 060/955] add handled packets stats TODO make auto-updated --- docs-assets/handled-packets.md | 169 +++++++++++++++++++++++++++++++ scripts/updateHandledPackets.mjs | 60 +++++++++++ 2 files changed, 229 insertions(+) create mode 100644 docs-assets/handled-packets.md create mode 100644 scripts/updateHandledPackets.mjs diff --git a/docs-assets/handled-packets.md b/docs-assets/handled-packets.md new file mode 100644 index 00000000..0671987c --- /dev/null +++ b/docs-assets/handled-packets.md @@ -0,0 +1,169 @@ +# Handled Packets + +## Server -> Client + +❌ statistics +❌ advancements +❌ face_player +❌ nbt_query_response +❌ chat_suggestions +❌ trade_list +❌ vehicle_move +❌ open_book +❌ craft_recipe_response +❌ end_combat_event +❌ enter_combat_event +❌ unlock_recipes +❌ camera +❌ update_view_position +❌ update_view_distance +❌ entity_sound_effect +❌ stop_sound +❌ feature_flags +❌ select_advancement_tab +❌ declare_recipes +❌ tags +❌ acknowledge_player_digging +❌ initialize_world_border +❌ world_border_center +❌ world_border_lerp_size +❌ world_border_size +❌ world_border_warning_delay +❌ world_border_warning_reach +❌ simulation_distance +❌ chunk_biomes +❌ damage_event +❌ hurt_animation +✅ spawn_entity +✅ spawn_entity_experience_orb +✅ named_entity_spawn +✅ animation +✅ block_break_animation +✅ tile_entity_data +✅ block_action +✅ block_change +✅ boss_bar +✅ difficulty +✅ tab_complete +✅ declare_commands +✅ multi_block_change +✅ close_window +✅ open_window +✅ window_items +✅ craft_progress_bar +✅ set_slot +✅ set_cooldown +✅ custom_payload +✅ hide_message +✅ kick_disconnect +✅ profileless_chat +✅ entity_status +✅ explosion +✅ unload_chunk +✅ game_state_change +✅ open_horse_window +✅ keep_alive +✅ map_chunk +✅ world_event +✅ world_particles +✅ update_light +✅ login +✅ map +✅ rel_entity_move +✅ entity_move_look +✅ entity_look +✅ open_sign_entity +✅ abilities +✅ player_chat +✅ death_combat_event +✅ player_remove +✅ player_info +✅ position +✅ entity_destroy +✅ remove_entity_effect +✅ resource_pack_send +✅ respawn +✅ entity_head_rotation +✅ held_item_slot +✅ scoreboard_display_objective +✅ entity_metadata +✅ attach_entity +✅ entity_velocity +✅ entity_equipment +✅ experience +✅ update_health +✅ scoreboard_objective +✅ set_passengers +✅ teams +✅ scoreboard_score +✅ spawn_position +✅ update_time +✅ sound_effect +✅ system_chat +✅ playerlist_header +✅ collect +✅ entity_teleport +✅ entity_update_attributes +✅ entity_effect +✅ server_data +✅ clear_titles +✅ action_bar +✅ ping +✅ set_title_subtitle +✅ set_title_text +✅ set_title_time +✅ packet + +## Client -> Server + +❌ query_block_nbt +❌ set_difficulty +❌ query_entity_nbt +❌ pick_item +❌ set_beacon_effect +❌ update_command_block_minecart +❌ update_structure_block +❌ generate_structure +❌ lock_difficulty +❌ craft_recipe_request +❌ displayed_recipe +❌ recipe_book +❌ update_jigsaw_block +❌ spectate +❌ advancement_tab +✅ teleport_confirm +✅ chat_command +✅ chat_message +✅ message_acknowledgement +✅ edit_book +✅ name_item +✅ select_trade +✅ update_command_block +✅ tab_complete +✅ client_command +✅ settings +✅ enchant_item +✅ window_click +✅ close_window +✅ custom_payload +✅ use_entity +✅ keep_alive +✅ position +✅ position_look +✅ look +✅ flying +✅ vehicle_move +✅ steer_boat +✅ abilities +✅ block_dig +✅ entity_action +✅ steer_vehicle +✅ resource_pack_receive +✅ held_item_slot +✅ set_creative_slot +✅ update_sign +✅ arm_animation +✅ block_place +✅ use_item +✅ pong +✅ chat_session_update diff --git a/scripts/updateHandledPackets.mjs b/scripts/updateHandledPackets.mjs new file mode 100644 index 00000000..080eaf44 --- /dev/null +++ b/scripts/updateHandledPackets.mjs @@ -0,0 +1,60 @@ +import fs from 'fs' +import path from 'path' +import minecraftData from 'minecraft-data' + +const lastVersion = minecraftData.versions.pc[0] +// console.log('last proto ver', lastVersion.minecraftVersion) +const allPackets = minecraftData(lastVersion.minecraftVersion).protocol +const getPackets = ({ types }) => { + return Object.keys(types).map(type => type.replace('packet_', '')) +} +// todo test against all versions +const allFromServerPackets = getPackets(allPackets.play.toClient) +const allToServerPackets = getPackets(allPackets.play.toServer).filter(x => !['packet'].includes(x)) + +const buildFile = './dist/index.js' + +const file = fs.readFileSync(buildFile, 'utf8') + +const packetsReceiveRegex = /client\.on\("(\w+)"/g +const packetsReceiveSend = /client\.write\("(\w+)"/g + +let allSupportedReceive = [...new Set([...file.matchAll(packetsReceiveRegex)].map(x => x[1]))] +let allSupportedSend = [...new Set([...file.matchAll(packetsReceiveSend)].map(x => x[1]))] + +let md = '# Handled Packets\n' + +md += '\n## Server -> Client\n\n' +let notSupportedRows = [] +let supportedRows = [] +for (const packet of allFromServerPackets) { + const includes = allSupportedReceive.includes(packet); + (includes ? supportedRows : notSupportedRows).push(packet) +} + +for (const row of notSupportedRows) { + md += `❌ ${row}\n` +} +for (const row of supportedRows) { + md += `✅ ${row}\n` +} + +md += '\n' + +notSupportedRows = [] +supportedRows = [] + +md += '## Client -> Server\n\n' +for (const packet of allToServerPackets) { + const includes = allSupportedSend.includes(packet); + (includes ? supportedRows : notSupportedRows).push(packet) +} + +for (const row of notSupportedRows) { + md += `❌ ${row}\n` +} +for (const row of supportedRows) { + md += `✅ ${row}\n` +} + +fs.writeFileSync('./docs-assets/handled-packets.md', md) From 6c5f72e1f286f2b73f8b940d117b9cec4b197ae1 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sat, 13 Jul 2024 20:31:27 +0300 Subject: [PATCH 061/955] feat: implement pitch which was required for note blocks to work properly --- prismarine-viewer/viewer/lib/viewer.ts | 5 +++-- src/soundSystem.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/prismarine-viewer/viewer/lib/viewer.ts b/prismarine-viewer/viewer/lib/viewer.ts index c95127f2..504c4637 100644 --- a/prismarine-viewer/viewer/lib/viewer.ts +++ b/prismarine-viewer/viewer/lib/viewer.ts @@ -32,7 +32,7 @@ export class Viewer { this.world.camera = camera } - constructor(public renderer: THREE.WebGLRenderer, worldConfig = defaultWorldRendererConfig) { + constructor (public renderer: THREE.WebGLRenderer, worldConfig = defaultWorldRendererConfig) { // https://discourse.threejs.org/t/updates-to-color-management-in-three-js-r152/50791 THREE.ColorManagement.enabled = false renderer.outputColorSpace = THREE.LinearSRGBColorSpace @@ -118,7 +118,7 @@ export class Viewer { this.world.updateCamera(pos?.offset(0, yOffset, 0) ?? null, yaw, pitch) } - playSound (position: Vec3, path: string, volume = 1) { + playSound (position: Vec3, path: string, volume = 1, pitch = 1) { if (!this.audioListener) { this.audioListener = new THREE.AudioListener() this.camera.add(this.audioListener) @@ -134,6 +134,7 @@ export class Viewer { sound.setBuffer(buffer) sound.setRefDistance(20) sound.setVolume(volume) + sound.setPlaybackRate(pitch) // set the pitch this.scene.add(sound) // set sound position sound.position.set(position.x, position.y, position.z) diff --git a/src/soundSystem.ts b/src/soundSystem.ts index e7fdaee7..d49b6a8c 100644 --- a/src/soundSystem.ts +++ b/src/soundSystem.ts @@ -50,7 +50,7 @@ subscribeKey(miscUiState, 'gameLoaded', async () => { const isMuted = options.mutedSounds.includes(soundKey) || options.volume === 0 if (position) { if (!isMuted) { - viewer.playSound(position, url, soundVolume * Math.max(Math.min(volume, 1), 0) * (options.volume / 100)) + viewer.playSound(position, url, soundVolume * Math.max(Math.min(volume, 1), 0) * (options.volume / 100), Math.max(Math.min(pitch ?? 1, 2), 0.5)) } if (getDistance(bot.entity.position, position) < 4 * 16) { lastPlayedSounds.lastServerPlayed[soundKey] ??= { count: 0, last: 0 } From b13ef443bb84d4f2f84a4d11bc0f25ffc8d4840c Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sat, 13 Jul 2024 21:30:44 +0300 Subject: [PATCH 062/955] feat: rework sound system. Now sounds are 100% implemented for all current & future supported versions --- prismarine-viewer/viewer/prepare/utils.ts | 14 ++++++ src/globals.d.ts | 2 +- src/soundSystem.ts | 53 ++++++++++++----------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/prismarine-viewer/viewer/prepare/utils.ts b/prismarine-viewer/viewer/prepare/utils.ts index a33909a9..958273f3 100644 --- a/prismarine-viewer/viewer/prepare/utils.ts +++ b/prismarine-viewer/viewer/prepare/utils.ts @@ -2,3 +2,17 @@ export const versionToNumber = (ver: string) => { const [x, y = '0', z = '0'] = ver.split('.') return +`${x.padStart(2, '0')}${y.padStart(2, '0')}${z.padStart(2, '0')}` } + +export const versionToMajor = (version: string) => { + const [x, y = '0'] = version.split('.') + return `${x.padStart(2, '0')}.${y.padStart(2, '0')}` +} + +export const versionsMapToMajor = (versionsMap: Record) => { + const majorVersions = {} as Record + for (const [ver, data] of Object.entries(versionsMap)) { + const major = versionToMajor(ver) + majorVersions[major] = data + } + return majorVersions +} diff --git a/src/globals.d.ts b/src/globals.d.ts index 05b29a14..f8699f21 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -17,7 +17,7 @@ declare const worldView: import('prismarine-viewer/viewer/lib/worldDataEmitter') declare const localServer: import('flying-squid/dist/index').FullServer & { options } | undefined /** all currently loaded mc data */ declare const mcData: Record -declare const loadedData: import('minecraft-data').IndexedData +declare const loadedData: import('minecraft-data').IndexedData & { sounds: Record } declare const customEvents: import('typed-emitter').default<{ /** Singleplayer load requested */ singleplayer (): void diff --git a/src/soundSystem.ts b/src/soundSystem.ts index d49b6a8c..0187a9b0 100644 --- a/src/soundSystem.ts +++ b/src/soundSystem.ts @@ -1,6 +1,6 @@ import { subscribeKey } from 'valtio/utils' import { Vec3 } from 'vec3' -import { versionToNumber } from 'prismarine-viewer/viewer/prepare/utils' +import { versionToMajor, versionToNumber, versionsMapToMajor } from 'prismarine-viewer/viewer/prepare/utils' import { loadScript } from 'prismarine-viewer/viewer/lib/utils' import type { Block } from 'prismarine-block' import { miscUiState } from './globalState' @@ -22,32 +22,26 @@ subscribeKey(miscUiState, 'gameLoaded', async () => { return } - // todo also use major versioned hardcoded sounds - const soundsMap = allSoundsMap[bot.version] + const allSoundsMajor = versionsMapToMajor(allSoundsMap) + const soundsMap = allSoundsMajor[versionToMajor(bot.version)] ?? Object.values(allSoundsMajor)[0] - if (!soundsMap || !miscUiState.gameLoaded || !soundsMap) { + if (!soundsMap || !miscUiState.gameLoaded || !loadedData.sounds) { return } - const soundsPerId = Object.fromEntries(Object.entries(soundsMap).map(([id, sound]) => [+id.split(';')[0], sound])) + // const soundsPerId = Object.fromEntries(Object.entries(soundsMap).map(([id, sound]) => [+id.split(';')[0], sound])) const soundsPerName = Object.fromEntries(Object.entries(soundsMap).map(([id, sound]) => [id.split(';')[1], sound])) - const soundIdToName = Object.fromEntries(Object.entries(soundsMap).map(([id, sound]) => [+id.split(';')[0], id.split(';')[1]])) - const playGeneralSound = async (soundId: string, soundString: string | undefined, position?: Vec3, volume = 1, pitch?: number) => { - if (!soundString) { - console.warn('Unknown sound received from server to play', soundId) - return - } + const playGeneralSound = async (soundKey: string, position?: Vec3, volume = 1, pitch?: number) => { if (!options.volume) return - const parts = soundString.split(';') - const soundVolume = +parts[0]! - const soundName = parts[1]! - // console.log('pitch', pitch) - const versionedSound = getVersionedSound(bot.version, soundName, Object.entries(soundsLegacyMap)) + const soundStaticData = soundsPerName[soundKey]?.split(';') + if (!soundStaticData) return + const soundVolume = +soundStaticData[0]! + const soundPath = soundStaticData[1]! + const versionedSound = getVersionedSound(bot.version, soundPath, Object.entries(soundsLegacyMap)) // todo test versionedSound - const url = allSoundsMeta.baseUrl.replace(/\/$/, '') + (versionedSound ? `/${versionedSound}` : '') + '/minecraft/sounds/' + soundName + '.' + allSoundsMeta.format - const soundKey = soundIdToName[+soundId] ?? soundId - const isMuted = options.mutedSounds.includes(soundKey) || options.volume === 0 + const url = allSoundsMeta.baseUrl.replace(/\/$/, '') + (versionedSound ? `/${versionedSound}` : '') + '/minecraft/sounds/' + soundPath + '.' + allSoundsMeta.format + const isMuted = options.mutedSounds.includes(soundKey) || options.mutedSounds.includes(soundPath) || options.volume === 0 if (position) { if (!isMuted) { viewer.playSound(position, url, soundVolume * Math.max(Math.min(volume, 1), 0) * (options.volume / 100), Math.max(Math.min(pitch ?? 1, 2), 0.5)) @@ -67,17 +61,24 @@ subscribeKey(miscUiState, 'gameLoaded', async () => { } } } - const playHardcodedSound = async (soundId: string, position?: Vec3, volume = 1, pitch?: number) => { - const sound = soundsPerName[soundId] - await playGeneralSound(soundId, sound, position, volume, pitch) + const playHardcodedSound = async (soundKey: string, position?: Vec3, volume = 1, pitch?: number) => { + await playGeneralSound(soundKey, position, volume, pitch) } bot.on('soundEffectHeard', async (soundId, position, volume, pitch) => { - console.debug('soundEffectHeard', soundId, volume) await playHardcodedSound(soundId, position, volume, pitch) }) - bot.on('hardcodedSoundEffectHeard', async (soundId, soundCategory, position, volume, pitch) => { - const sound = soundsPerId[soundId] - await playGeneralSound(soundId.toString(), sound, position, volume, pitch) + bot.on('hardcodedSoundEffectHeard', async (soundIdNum, soundCategory, position, volume, pitch) => { + const fixOffset = versionToNumber('1.20.4') === versionToNumber(bot.version) ? -1 : 0 + const soundKey = loadedData.sounds[soundIdNum + fixOffset]?.name + if (soundKey === undefined) return + await playGeneralSound(soundKey, position, volume, pitch) + }) + // workaround as mineflayer doesn't support soundEvent + bot._client.on('sound_effect', async (packet) => { + const soundResource = packet['soundEvent']?.resource as string | undefined + if (packet.soundId !== 0 || !soundResource) return + const pos = new Vec3(packet.x / 8, packet.y / 8, packet.z / 8) + await playHardcodedSound(soundResource.replace('minecraft:', ''), pos, packet.volume, packet.pitch) }) bot.on('entityHurt', async (entity) => { if (entity.id === bot.entity.id) { From 698779f6b5302165dd3dff731de0b223ac837513 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sat, 13 Jul 2024 21:31:29 +0300 Subject: [PATCH 063/955] fix: toggle entity visiiblity even after it's creation --- prismarine-viewer/viewer/lib/entities.js | 10 +++++----- prismarine-viewer/viewer/lib/worldDataEmitter.ts | 9 ++++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/prismarine-viewer/viewer/lib/entities.js b/prismarine-viewer/viewer/lib/entities.js index 94f06e0c..d36b6936 100644 --- a/prismarine-viewer/viewer/lib/entities.js +++ b/prismarine-viewer/viewer/lib/entities.js @@ -405,14 +405,14 @@ export class Entities extends EventEmitter { } //@ts-ignore + // set visibility const isInvisible = entity.metadata?.[0] & 0x20 - if (isInvisible) { - for (const child of this.entities[entity.id].children.find(c => c.name === 'mesh').children) { - if (child.name !== 'nametag') { - child.visible = false - } + for (const child of this.entities[entity.id].children.find(c => c.name === 'mesh').children) { + if (child.name !== 'nametag') { + child.visible = !isInvisible } } + // --- // not player const displayText = entity.metadata?.[3] && this.parseEntityLabel(entity.metadata[2]) if (entity.name !== 'player' && displayText) { diff --git a/prismarine-viewer/viewer/lib/worldDataEmitter.ts b/prismarine-viewer/viewer/lib/worldDataEmitter.ts index 5df5cc73..761509c2 100644 --- a/prismarine-viewer/viewer/lib/worldDataEmitter.ts +++ b/prismarine-viewer/viewer/lib/worldDataEmitter.ts @@ -44,7 +44,14 @@ export class WorldDataEmitter extends EventEmitter { listenToBot (bot: typeof __type_bot) { const emitEntity = (e) => { if (!e || e === bot.entity) return - this.emitter.emit('entity', { ...e, pos: e.position, username: e.username }) + this.emitter.emit('entity', { + ...e, + pos: e.position, + username: e.username, + // set debugTree (obj) { + // e.debugTree = obj + // } + }) } this.eventListeners[bot.username] = { From 512bc09477aa96352f4d19a165a7e110d5c76f81 Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Sun, 14 Jul 2024 01:55:41 +0300 Subject: [PATCH 064/955] make main docker build 5x smaller, add only proxy dockerfile --- Dockerfile | 32 +++++++++++++++++++++----------- Dockerfile.proxy | 11 +++++++++++ README.MD | 15 +++++++++++---- 3 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 Dockerfile.proxy diff --git a/Dockerfile b/Dockerfile index 086240b5..0ae1c6e0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,32 @@ -FROM node:18-alpine +# ---- Build Stage ---- +FROM node:18-alpine AS build # Without git installing the npm packages fails -RUN apk add git -RUN mkdir /app +RUN apk add --no-cache git python3 make g++ cairo-dev pango-dev jpeg-dev giflib-dev librsvg-dev WORKDIR /app COPY . /app -# install python and other dependencies -RUN apk add python3 make g++ cairo-dev pango-dev jpeg-dev giflib-dev librsvg-dev # install pnpm RUN npm i -g pnpm@9.0.4 RUN pnpm install -# only for prod -RUN pnpm run build -# --- -EXPOSE 8080 -# uncomment for development + +# TODO for development # EXPOSE 9090 # VOLUME /app/src # VOLUME /app/prismarine-viewer # ENTRYPOINT ["pnpm", "run", "run-all"] + # only for prod -ENTRYPOINT ["npm", "run", "prod-start"] +RUN pnpm run build + +# ---- Run Stage ---- +FROM node:18-alpine +RUN apk add git +WORKDIR /app +# Copy build artifacts from the build stage +COPY --from=build /app/dist /app/dist +COPY server.js /app/server.js +# Install express +RUN npm i -g pnpm@9.0.4 +RUN npm init -yp +RUN pnpm i express github:zardoy/prismarinejs-net-browserify compression cors +EXPOSE 8080 +ENTRYPOINT ["node", "server.js"] diff --git a/Dockerfile.proxy b/Dockerfile.proxy new file mode 100644 index 00000000..746eef72 --- /dev/null +++ b/Dockerfile.proxy @@ -0,0 +1,11 @@ +# ---- Run Stage ---- +FROM node:18-alpine +RUN apk add git +WORKDIR /app +COPY server.js /app/server.js +# Install server dependencies +RUN npm i -g pnpm@9.0.4 +RUN npm init -yp +RUN pnpm i express github:zardoy/prismarinejs-net-browserify compression cors +EXPOSE 8080 +ENTRYPOINT ["node", "server.js"] diff --git a/README.MD b/README.MD index 9a4ba24a..7576f6ba 100644 --- a/README.MD +++ b/README.MD @@ -44,6 +44,13 @@ See the [Mineflayer](https://github.com/PrismarineJS/mineflayer) repo for the li There is a builtin proxy, but you can also host your one! Just clone the repo, run `pnpm i` (following CONTRIBUTING.MD) and run `pnpm prod-start`, then you can specify `http://localhost:8080` in the proxy field. MS account authentication will be supported soon. +### Docker Files + +- [Main Dockerfile](./Dockerfile) - for production build & offline/private usage. Includes full web-app + proxy server for connecting to Minecraft servers. +- [Proxy Dockerfile](./Dockerfile.proxy) - for proxy server only - that one you would be able to specify in the proxy field on the client (`docker build . -f Dockerfile.proxy -t minecraft-web-proxy`) + +In case of using docker, you don't have to follow preparation steps from CONTRIBUTING.MD, like installing Node.js, pnpm, etc. + ### Rendering #### Three.js Renderer @@ -55,10 +62,6 @@ MS account authentication will be supported soon. -### Things that are not planned yet - -- Mods, plugins (basically JARs) support, shaders - since they all are related to specific game pipelines - ### Advanced Settings There are many many settings, that are not exposed in the UI yet. You can find or change them by opening the browser console and typing `options`. You can also change them by typing `options. = `. @@ -131,6 +134,10 @@ Press `Y` to set query parameters to url of your current game state. - [Peer.js](https://peerjs.com/) - P2P networking (when you open to wan) - [Three.js](https://threejs.org/) - Helping in 3D rendering +### Things that are not planned yet + +- Mods, plugins (basically JARs) support, shaders - since they all are related to specific game pipelines + ### Alternatives - [https://github.com/ClassiCube/ClassiCube](ClassiCube - Better C# Rewrite) [DEMO](https://www.classicube.net/server/play/?warned=true) From b49e9880906f269b1be6456abcdb24f78e45f21e Mon Sep 17 00:00:00 2001 From: Vitaly Turovsky Date: Tue, 16 Jul 2024 10:35:01 +0300 Subject: [PATCH 065/955] fix: inventory didn't update after dropping an item --- src/controls.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/controls.ts b/src/controls.ts index a3a22029..98cc6afb 100644 --- a/src/controls.ts +++ b/src/controls.ts @@ -353,7 +353,7 @@ contro.on('trigger', ({ command }) => { document.exitPointerLock?.() openPlayerInventory() break - case 'general.drop': + case 'general.drop': { // if (bot.heldItem/* && ctrl */) bot.tossStack(bot.heldItem) bot._client.write('block_dig', { 'status': 4, @@ -365,7 +365,14 @@ contro.on('trigger', ({ command }) => { 'face': 0, sequence: 0 }) + const slot = bot.inventory.hotbarStart + bot.quickBarSlot + const item = bot.inventory.slots[slot] + if (item) { + item.count-- + bot.inventory.updateSlot(slot, item.count > 0 ? item : null!) + } break + } case 'general.chat': showModal({ reactType: 'chat' }) break From 9ee67cc8270e79e5b2d9025a30148bb083e8c36d Mon Sep 17 00:00:00 2001 From: Wolf2323 Date: Tue, 16 Jul 2024 10:37:01 +0200 Subject: [PATCH 066/955] fix: ignoring exception ResizeObserver loop exceptions (#161) --- src/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/index.ts b/src/index.ts index e34e81ab..2a190785 100644 --- a/src/index.ts +++ b/src/index.ts @@ -330,6 +330,9 @@ async function connect (connectOptions: ConnectOptions) { } const handleError = (err) => { console.error(err) + if (err === 'ResizeObserver loop completed with undelivered notifications.') { + return + } errorAbortController.abort() if (isCypress()) throw err miscUiState.hasErrors = true From cda1d59d3bd59580d91f4107a8b4a8bfae57c976 Mon Sep 17 00:00:00 2001 From: Wolf2323 Date: Tue, 16 Jul 2024 11:05:57 +0200 Subject: [PATCH 067/955] improved query parameters handling (#162) Co-authored-by: Vitaly --- README.MD | 25 ++++++++++------- src/react/AddServerOrConnect.tsx | 46 +++++++++++++++++++------------- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/README.MD b/README.MD index 7576f6ba..cafa3ac9 100644 --- a/README.MD +++ b/README.MD @@ -110,19 +110,26 @@ world chunks have a *yellow* border, hostile mobs have a *red* outline, passive Press `Y` to set query parameters to url of your current game state. -- `?ip=` - Display connect screen to the server on load -- `?username=` - Set the username for server -- `?proxy=` - Set the proxy server address to use for server -- `?version=` - Set the version for server -- `?lockConnect=true` - Disable cancel / save buttons, useful for integrates iframes +There are some parameters you can set in the url to archive some specific behaviors: + +Server specific: +- `?ip=` - Display connect screen to the server on load with predefined server ip. `:` is optional and can be added to the ip. +- `?name=` - Set the server name for saving to the server list +- `?version=` - Set the version for the server +- `?proxy=` - Set the proxy server address to use for the server +- `?username=` - Set the username for the server +- `?lockConnect=true` - Only works then `ip` parameter is set. Disables cancel/save buttons and all inputs in the connect screen already set as parameters. Useful for integrates iframes. - `?reconnect=true` - Reconnect to the server on page reloads. Available in **dev mode only** and very useful on server testing. + +Single player specific: - `?loadSave=` - Load the save on load with the specified folder name (not title) - `?singleplayer=1` - Create empty world on load. Nothing will be saved -- `?noSave=true` - Disable auto save on unload / disconnect / export. Only manual save with `/save` command will work - - +- `?version=` - Set the version for the singleplayer world (when used with `?singleplayer=1`) +- `?noSave=true` - Disable auto save on unload / disconnect / export whenever a world is loaded. Only manual save with `/save` command will work. - `?map=` - Load the map from ZIP. You can use any url, but it must be CORS enabled. -- `?setting=:` - Set the and lock the setting on load. You can set multiple settings by separating them with `&` e.g. `?setting=autoParkour:true&setting=renderDistance:4` + +General: +- `?setting=:` - Set and lock the setting on load. You can set multiple settings by separating them with `&` e.g. `?setting=autoParkour:true&setting=renderDistance:4` ### Notable Things that Power this Project diff --git a/src/react/AddServerOrConnect.tsx b/src/react/AddServerOrConnect.tsx index 729f1ec2..535e3ee9 100644 --- a/src/react/AddServerOrConnect.tsx +++ b/src/react/AddServerOrConnect.tsx @@ -30,19 +30,25 @@ const ELEMENTS_WIDTH = 190 export default ({ onBack, onConfirm, title = 'Add a Server', initialData, parseQs, onQsConnect, defaults, accounts, authenticatedAccounts }: Props) => { const qsParams = parseQs ? new URLSearchParams(window.location.search) : undefined + const qsParamName = qsParams?.get('name') + const qsParamIp = qsParams?.get('ip') + const qsParamVersion = qsParams?.get('version') + const qsParamProxy = qsParams?.get('proxy') + const qsParamUsername = qsParams?.get('username') + const qsParamLockConnect = qsParams?.get('lockConnect') - const [serverName, setServerName] = React.useState(initialData?.name ?? qsParams?.get('name') ?? '') + const qsIpParts = qsParamIp?.split(':') + const ipParts = initialData?.ip.split(':') - const ipWithoutPort = initialData?.ip.split(':')[0] - const port = initialData?.ip.split(':')[1] + const [serverName, setServerName] = React.useState(initialData?.name ?? qsParamName ?? '') + const [serverIp, setServerIp] = React.useState(ipParts?.[0] ?? qsIpParts?.[0] ?? '') + const [serverPort, setServerPort] = React.useState(ipParts?.[1] ?? qsIpParts?.[1] ?? '') + const [versionOverride, setVersionOverride] = React.useState(initialData?.versionOverride ?? /* legacy */ initialData?.['version'] ?? qsParamVersion ?? '') + const [proxyOverride, setProxyOverride] = React.useState(initialData?.proxyOverride ?? qsParamProxy ?? '') + const [usernameOverride, setUsernameOverride] = React.useState(initialData?.usernameOverride ?? qsParamUsername ?? '') + const lockConnect = qsParamLockConnect === 'true' - const [serverIp, setServerIp] = React.useState(ipWithoutPort ?? qsParams?.get('ip') ?? '') - const [serverPort, setServerPort] = React.useState(port ?? '') - const [versionOverride, setVersionOverride] = React.useState(initialData?.versionOverride ?? /* legacy */ initialData?.['version'] ?? qsParams?.get('version') ?? '') - const [proxyOverride, setProxyOverride] = React.useState(initialData?.proxyOverride ?? qsParams?.get('proxy') ?? '') - const [usernameOverride, setUsernameOverride] = React.useState(initialData?.usernameOverride ?? qsParams?.get('username') ?? '') const smallWidth = useIsSmallWidth() - const lockConnect = qsParams?.get('lockConnect') === 'true' const initialAccount = initialData?.authenticatedAccountOverride const [accountIndex, setAccountIndex] = React.useState(initialAccount === true ? -2 : initialAccount ? (accounts?.includes(initialAccount) ? accounts.indexOf(initialAccount) : -2) : -1) @@ -61,7 +67,7 @@ export default ({ onBack, onConfirm, title = 'Add a Server', initialData, parseQ authenticatedAccountOverride, } - return + return
-
- setServerName(value)} placeholder='Defaults to IP' /> -
- setServerIp(value)} /> - setServerPort(value)} placeholder='25565' /> + {!lockConnect && <> +
+ setServerName(value)} placeholder='Defaults to IP' /> +
+ } + setServerIp(value)} /> + setServerPort(value)} placeholder='25565' />
Overrides:
- setVersionOverride(value)} placeholder='Optional, but recommended to specify' /> - setProxyOverride(value)} placeholder={defaults?.proxyOverride} /> - setUsernameOverride(value)} placeholder={defaults?.usernameOverride} disabled={!noAccountSelected} /> + setVersionOverride(value)} placeholder='Optional, but recommended to specify' /> + setProxyOverride(value)} placeholder={defaults?.proxyOverride} /> + setUsernameOverride(value)} placeholder={defaults?.usernameOverride} />