Skip to content

Commit

Permalink
Begin waypoints
Browse files Browse the repository at this point in the history
  • Loading branch information
GreenAppers committed Nov 16, 2024
1 parent d5c0e4a commit f3802c3
Show file tree
Hide file tree
Showing 10 changed files with 305 additions and 118 deletions.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
"electron-is-dev": "^3.0.1",
"electron-log": "^5.2.0",
"electron-squirrel-startup": "^1.0.1",
"electron-store": "^8.2.0",
"framer-motion": "^11.5.6",
"p-settle": "^5.1.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"recharts": "^2.13.0",
"split2": "^4.2.0",
"tail": "^2.1.1",
"zod": "^3.23.8"
"zod": "^3.23.8",
"zod-electron-store": "^1.0.5"
},
"devDependencies": {
"@babel/core": "^7.25.2",
Expand Down Expand Up @@ -80,5 +80,8 @@
},
"engines": {
"node": "v20.16.0"
},
"resolutions": {
"superagent": "6.0.0"
}
}
2 changes: 2 additions & 0 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import React from 'react'
import { Analytics } from './Analytics'
import { Launcher } from './Launcher'
import { PieRayHelper } from './PieRayHelper'
import { Waypoints } from './Waypoints'

function App() {
const [selectedTab, setSelectedTab] = React.useState(2)
Expand Down Expand Up @@ -58,6 +59,7 @@ function App() {
<TabPanel>{selectedTab === 1 && <PieRayHelper />}</TabPanel>
<TabPanel>{selectedTab === 2 && <Launcher />}</TabPanel>
<TabPanel></TabPanel>
<TabPanel>{selectedTab === 4 && <Waypoints />}</TabPanel>
</TabPanels>
</Tabs>
)
Expand Down
53 changes: 6 additions & 47 deletions src/components/PieRayHelper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,37 +46,7 @@ import type {
PieRaySample,
PieRaySolution,
} from '../types'

const vanillaCoords =
/tp @s (-?\d+\.\d+) (-?\d+\.\d+) (-?\d+\.\d+) (-?\d+\.\d+)/
const lunarClientCoords = /X: (-?\d+) Y: (-?\d+) Z: (-?\d+)/

function getDirectionFromRotation(
rotation?: number
): ChunkDirection | undefined {
if (typeof rotation !== 'number') return undefined
const angleInRadians = rotation * (Math.PI / 180)
const x = -Math.sin(angleInRadians)
const z = Math.cos(angleInRadians)
return {
x: Math.abs(x) > 0.5 ? (x > 0 ? 1 : -1) : 0,
z: Math.abs(z) > 0.5 ? (z > 0 ? 1 : -1) : 0,
}
}

function getDirectionArrow(direction?: ChunkDirection) {
if (!direction) return ''
switch (direction.z) {
case 1:
return direction.x === 1 ? '↗' : direction.x === -1 ? '↖' : '↑'
case -1:
return direction.x === 1 ? '↘' : direction.x === -1 ? '↙' : '↓'
case 0:
return direction.x === 1 ? '→' : direction.x === -1 ? '←' : ''
}
}

const lerp = (a: number, b: number, t: number) => a + (b - a) * t
import { getDirectionArrow, getDirectionFromRotation, lerp, usePastedCoordinates } from '../utils/coords'

const ScatterArrow = (
props: ScatterPointItem & { fill?: string; direction?: ChunkDirection }
Expand Down Expand Up @@ -138,19 +108,8 @@ export function PieRayHelper() {
window.api.getLogfilePath().then(setLogfilePath)
}, [setLogfilePath])

useEffect(() => {
const handle = window.api.onClipboardTextUpdated((text: string) => {
let rotation: number | undefined
let match = text.match(vanillaCoords)
if (match) rotation = parseFloat(match[4])

if (!match) match = text.match(lunarClientCoords)
if (!match) return

const x = parseInt(match[1])
const y = parseInt(match[2])
const z = parseInt(match[3])

usePastedCoordinates(
(x, y, z, rotation) => {
const sample: PieRaySample = {
chunk: { x: Math.floor(x / 16), z: Math.floor(z / 16) },
position: { x, y, z },
Expand Down Expand Up @@ -181,9 +140,9 @@ export function PieRayHelper() {
log.info(`Added sample: ${x}, ${y}, ${z}`)
return [...samples, sample]
})
})
return () => window.api.removeListener(handle)
}, [setSamples])
},
[setSamples]
)

useEffect(() => {
let minX, maxX, minZ, maxZ
Expand Down
60 changes: 60 additions & 0 deletions src/components/Waypoints.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
Flex,
Heading,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
} from '@chakra-ui/react'

import { QUERY_KEYS, STORE_KEYS, Waypoint } from '../constants'
import { useQuery } from '@tanstack/react-query'

export const useWaypointsQuery = () =>
useQuery<Waypoint[]>({
queryKey: [QUERY_KEYS.useWaypoints],
queryFn: () => window.api.store.get(STORE_KEYS.waypoints),
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
})

export function Waypoints() {
const waypoints = useWaypointsQuery()

return (
<>
<Flex>
<Heading>Waypoints</Heading>
</Flex>

<TableContainer>
<Table>
<Thead>
<Tr>
<Th>Name</Th>
<Th>Date</Th>
<Th>X</Th>
<Th>Y</Th>
<Th>Z</Th>
</Tr>
</Thead>
<Tbody>
{(waypoints.data ?? []).map((waypoint, i) => (
<Tr key={i} _hover={{ backgroundColor: 'blue.50' }}>
<Td>{waypoint.name}</Td>
<Td>{waypoint.date.toLocaleDateString()}</Td>
<Td>{waypoint.x}</Td>
<Td>{waypoint.y}</Td>
<Td>{waypoint.z}</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</>
)
}
26 changes: 16 additions & 10 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const minecraftLoginResponse = z.object({
})

export const minecraftProfileState = z.enum(['ACTIVE', 'INACTIVE'])
export const minecraftSkinVariant = z.enum(['SLIM', 'CLASSIC'])
export const minecraftSkinVariant = z.enum(['CLASSIC', 'SLIM'])

export const minecraftSkin = z.object({
id: z.string(),
Expand Down Expand Up @@ -194,9 +194,16 @@ export const gameInstall = z.object({
mods: z.optional(z.array(z.string())),
})

export type MinecraftLoginResponse = z.infer<
typeof minecraftLoginResponse
>
export const waypoint = z.object({
name: z.string(),
date: z.coerce.date(),
x: z.number(),
y: z.number(),
z: z.number(),
})

export type MinecraftLoginResponse = z.infer<typeof minecraftLoginResponse>
export type MinecraftProfile = z.infer<typeof minecraftProfile>
export type MojangLibrary = z.infer<typeof mojangLibrary>
export type MojangRule = z.infer<typeof mojangRule>
export type MojangVersionDetails = z.infer<typeof mojangVersionDetails>
Expand All @@ -207,21 +214,20 @@ export type XSTSAuthorizeResponse = z.infer<typeof xstsAuthorizeResponse>

export type GameAccount = z.infer<typeof gameAccount>
export type GameInstall = z.infer<typeof gameInstall>
export type Waypoint = z.infer<typeof waypoint>

export type StoreSchema = {
gameInstalls: GameInstall[]
gameLogDirectories: string[]
}

export const STORE_KEYS: { [key: string]: keyof StoreSchema } = {
export const STORE_KEYS = {
gameAccounts: 'gameAccounts',
gameInstalls: 'gameInstalls',
gameLogDirectories: 'gameLogDirectories',
waypoints: 'waypoints',
}

export const QUERY_KEYS = {
useGameInstalls: 'useGameInstalls',
useGameLogDirectories: 'useGameLogDirectories',
useMojangVersionManifests: 'useMojangVersionManifests',
useWaypoints: 'useWaypoints',
}

export const CHANNELS = {
Expand Down
53 changes: 18 additions & 35 deletions src/store.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,28 @@
import Store, { Schema } from 'electron-store'
import { z } from 'zod'
import Store from 'zod-electron-store'

import { getDefaultGameLogDirectories } from './utils/gamelog'
import {
gameAccount,
GameAccount,
gameInstall,
GameInstall,
STORE_KEYS,
type StoreSchema,
waypoint,
} from './constants'
import { getDefaultGameLogDirectories } from './utils/gamelog'

export const schema: Schema<StoreSchema> = {
gameInstalls: {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' },
path: { type: 'string' },
uuid: { type: 'string' },
versionManifest: {
type: 'object',
properties: {
id: { type: 'string' },
type: { type: 'string' },
url: { type: 'string' },
time: { type: 'string' },
releaseTime: { type: 'string' },
},
},
fabricLoaderVersion: { type: 'string', default: '' },
mods: { type: 'array', items: { type: 'string' }, default: [] },
},
},
default: [],
},
gameLogDirectories: {
type: 'array',
items: { type: 'string' },
default: getDefaultGameLogDirectories(),
},
}
export { Store }

export const storeSchema = z.object({
gameAccounts: z.array(gameAccount).default([]),
gameInstalls: z.array(gameInstall).default([]),
gameLogDirectories: z.array(z.string()).default(getDefaultGameLogDirectories()),
waypoints: z.array(waypoint).default([]),
})

export type StoreSchema = z.infer<typeof storeSchema>

export const newStore = () => new Store<StoreSchema>({ schema })
export const newStore = () => new Store<StoreSchema>({ schema: storeSchema })

export const updateGameAccount = (
store: Store<StoreSchema>,
Expand Down
4 changes: 1 addition & 3 deletions src/utils/auth.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import axios from 'axios'
import Store from 'electron-store'
import {
GameAccount,
minecraftLoginResponse,
minecraftProfile,
StoreSchema,
xboxLiveProfile,
xstsAuthorizeResponse,
} from '../constants'
import { updateGameAccount } from '../store'
import { Store, StoreSchema, updateGameAccount } from '../store'

// References:
// - https://mojang-api-docs.gapple.pw/
Expand Down
54 changes: 54 additions & 0 deletions src/utils/coords.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { DependencyList, useEffect } from 'react'
import type { ChunkDirection } from '../types'

const vanillaCoords =
/tp @s (-?\d+\.\d+) (-?\d+\.\d+) (-?\d+\.\d+) (-?\d+\.\d+)/
const lunarClientCoords = /X: (-?\d+) Y: (-?\d+) Z: (-?\d+)/

export const lerp = (a: number, b: number, t: number) => a + (b - a) * t

export function getDirectionFromRotation(
rotation?: number
): ChunkDirection | undefined {
if (typeof rotation !== 'number') return undefined
const angleInRadians = rotation * (Math.PI / 180)
const x = -Math.sin(angleInRadians)
const z = Math.cos(angleInRadians)
return {
x: Math.abs(x) > 0.5 ? (x > 0 ? 1 : -1) : 0,
z: Math.abs(z) > 0.5 ? (z > 0 ? 1 : -1) : 0,
}
}

export function getDirectionArrow(direction?: ChunkDirection) {
if (!direction) return ''
switch (direction.z) {
case 1:
return direction.x === 1 ? '↗' : direction.x === -1 ? '↖' : '↑'
case -1:
return direction.x === 1 ? '↘' : direction.x === -1 ? '↙' : '↓'
case 0:
return direction.x === 1 ? '→' : direction.x === -1 ? '←' : ''
}
}

export const usePastedCoordinates = (
cb: (x: number, y: number, z: number, rotation?: number) => void,
deps?: DependencyList
) =>
useEffect(() => {
const handle = window.api.onClipboardTextUpdated((text: string) => {
let rotation: number | undefined
let match = text.match(vanillaCoords)
if (match) rotation = parseFloat(match[4])

if (!match) match = text.match(lunarClientCoords)
if (!match) return

const x = parseInt(match[1])
const y = parseInt(match[2])
const z = parseInt(match[3])
cb(x, y, z, rotation)
})
return () => window.api.removeListener(handle)
}, deps)
3 changes: 1 addition & 2 deletions src/utils/launcher.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import axios from 'axios'
import Store from 'electron-store'
import { spawn } from 'child_process'
import { app } from 'electron'
import fs from 'fs'
Expand All @@ -12,10 +11,10 @@ import {
GameInstall,
mojangVersionDetails,
parseLibraryName,
StoreSchema,
updateVersionDetailsLibrary,
} from '../constants'
import { AuthProvider } from '../msal/AuthProvider'
import { Store, StoreSchema } from '../store'
import { loginToMinecraft } from './auth'
import {
checkFileExists,
Expand Down
Loading

0 comments on commit f3802c3

Please sign in to comment.