Skip to content

Commit f755385

Browse files
committed
refactor: rm loadedGameState, add a way to copy server resource pack to local
1 parent 14b7cb0 commit f755385

9 files changed

+66
-36
lines changed

src/controls.ts

+20-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ControMax } from 'contro-max/build/controMax'
77
import { CommandEventArgument, SchemaCommandInput } from 'contro-max/build/types'
88
import { stringStartsWith } from 'contro-max/build/stringUtils'
99
import { UserOverrideCommand, UserOverridesConfig } from 'contro-max/build/types/store'
10-
import { isGameActive, showModal, gameAdditionalState, activeModalStack, hideCurrentModal, miscUiState, loadedGameState, hideModal, hideAllModals } from './globalState'
10+
import { isGameActive, showModal, gameAdditionalState, activeModalStack, hideCurrentModal, miscUiState, hideModal, hideAllModals } from './globalState'
1111
import { goFullscreen, pointerLock, reloadChunks } from './utils'
1212
import { options } from './optionsStorage'
1313
import { openPlayerInventory } from './inventoryWindows'
@@ -19,7 +19,7 @@ import { showOptionsModal } from './react/SelectOption'
1919
import widgets from './react/widgets'
2020
import { getItemFromBlock } from './chatUtils'
2121
import { gamepadUiCursorState, moveGamepadCursorByPx } from './react/GamepadUiCursor'
22-
import { completeTexturePackInstall, resourcePackState } from './resourcePack'
22+
import { completeTexturePackInstall, copyServerResourcePackToRegular, resourcePackState } from './resourcePack'
2323
import { showNotification } from './react/NotificationProvider'
2424
import { lastConnectOptions } from './react/AppStatusProvider'
2525

@@ -450,7 +450,12 @@ contro.on('release', ({ command }) => {
450450

451451
// hard-coded keybindings
452452

453-
export const f3Keybinds = [
453+
export const f3Keybinds: Array<{
454+
key?: string,
455+
action: () => void,
456+
mobileTitle: string
457+
enabled?: () => boolean
458+
}> = [
454459
{
455460
key: 'KeyA',
456461
action () {
@@ -496,9 +501,9 @@ export const f3Keybinds = [
496501
key: 'KeyT',
497502
async action () {
498503
// TODO!
499-
if (resourcePackState.resourcePackInstalled || loadedGameState.usingServerResourcePack) {
504+
if (resourcePackState.resourcePackInstalled || gameAdditionalState.usingServerResourcePack) {
500505
showNotification('Reloading textures...')
501-
await completeTexturePackInstall('default', 'default', loadedGameState.usingServerResourcePack)
506+
await completeTexturePackInstall('default', 'default', gameAdditionalState.usingServerResourcePack)
502507
}
503508
},
504509
mobileTitle: 'Reload Textures'
@@ -539,7 +544,15 @@ export const f3Keybinds = [
539544
const proxyPing = await bot['pingProxy']()
540545
void showOptionsModal(`${username}: last known total latency (ping): ${playerPing}. Connected to ${lastConnectOptions.value?.proxy} with current ping ${proxyPing}. Player UUID: ${uuid}`, [])
541546
},
542-
mobileTitle: 'Show Proxy & Ping Details'
547+
mobileTitle: 'Show Proxy & Ping Details',
548+
enabled: () => !!lastConnectOptions.value?.proxy
549+
},
550+
{
551+
action () {
552+
void copyServerResourcePackToRegular()
553+
},
554+
mobileTitle: 'Copy Server Resource Pack',
555+
enabled: () => !!gameAdditionalState.usingServerResourcePack
543556
}
544557
]
545558

@@ -548,7 +561,7 @@ document.addEventListener('keydown', (e) => {
548561
if (!isGameActive(false)) return
549562
if (hardcodedPressedKeys.has('F3')) {
550563
const keybind = f3Keybinds.find((v) => v.key === e.code)
551-
if (keybind) {
564+
if (keybind && (keybind.enabled?.() ?? true)) {
552565
keybind.action()
553566
e.stopPropagation()
554567
}

src/globalState.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,6 @@ export const miscUiState = proxy({
146146
displaySearchInput: false,
147147
})
148148

149-
export const loadedGameState = proxy({
150-
username: '',
151-
serverIp: '' as string | null,
152-
usingServerResourcePack: false,
153-
})
154-
155149
export const isGameActive = (foregroundCheck: boolean) => {
156150
if (foregroundCheck && activeModalStack.length) return false
157151
return miscUiState.gameLoaded
@@ -165,7 +159,9 @@ export const gameAdditionalState = proxy({
165159
isSprinting: false,
166160
isSneaking: false,
167161
isZooming: false,
168-
warps: [] as WorldWarp[]
162+
warps: [] as WorldWarp[],
163+
164+
usingServerResourcePack: false,
169165
})
170166

171167
window.gameAdditionalState = gameAdditionalState

src/index.ts

-7
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import {
5353
hideModal,
5454
insertActiveModalStack,
5555
isGameActive,
56-
loadedGameState,
5756
miscUiState,
5857
showModal
5958
} from './globalState'
@@ -884,12 +883,6 @@ async function connect (connectOptions: ConnectOptions) {
884883

885884
console.log('Done!')
886885

887-
// todo
888-
onGameLoad(async () => {
889-
loadedGameState.serverIp = server.host ?? null
890-
loadedGameState.username = username
891-
})
892-
893886
if (appStatusState.isError) return
894887
setTimeout(() => {
895888
// todo

src/optionsGuiScheme.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useRef, useState } from 'react'
22
import { useSnapshot } from 'valtio'
33
import { openURL } from 'prismarine-viewer/viewer/lib/simpleUtils'
44
import { noCase } from 'change-case'
5-
import { loadedGameState, miscUiState, openOptionsMenu, showModal } from './globalState'
5+
import { gameAdditionalState, miscUiState, openOptionsMenu, showModal } from './globalState'
66
import { AppOptions, options } from './optionsStorage'
77
import Button from './react/Button'
88
import { OptionMeta, OptionSlider } from './react/OptionsItems'
@@ -157,7 +157,7 @@ export const guiOptionsScheme: {
157157
{
158158
custom () {
159159
const { resourcePackInstalled } = useSnapshot(resourcePackState)
160-
const { usingServerResourcePack } = useSnapshot(loadedGameState)
160+
const { usingServerResourcePack } = useSnapshot(gameAdditionalState)
161161
const { enabledResourcepack } = useSnapshot(options)
162162
return <Button
163163
label={`Resource Pack: ${usingServerResourcePack ? 'SERVER ON' : resourcePackInstalled ? enabledResourcepack ? 'ON' : 'OFF' : 'NO'}`} inScreen onClick={async () => {

src/react/ChatProvider.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'
22
import { useSnapshot } from 'valtio'
33
import { formatMessage } from '../chatUtils'
44
import { getBuiltinCommandsList, tryHandleBuiltinCommand } from '../builtinCommands'
5-
import { hideCurrentModal, loadedGameState, miscUiState } from '../globalState'
5+
import { hideCurrentModal, miscUiState } from '../globalState'
66
import { options } from '../optionsStorage'
77
import Chat, { Message, fadeMessage } from './Chat'
88
import { useIsModalActive } from './utilsApp'
@@ -54,7 +54,7 @@ export default () => {
5454
updateLoadedServerData((server) => {
5555
server.autoLogin ??= {}
5656
const password = message.split(' ')[1]
57-
server.autoLogin[loadedGameState.username] = password
57+
server.autoLogin[bot.player.username] = password
5858
return server
5959
})
6060
hideNotification()

src/react/MinimapProvider.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ import { useSnapshot } from 'valtio'
1515
import BlockData from '../../prismarine-viewer/viewer/lib/moreBlockDataGenerated.json'
1616
import preflatMap from '../preflatMap.json'
1717
import { contro } from '../controls'
18-
import { gameAdditionalState, showModal, hideModal, miscUiState, loadedGameState, activeModalStack } from '../globalState'
18+
import { gameAdditionalState, showModal, hideModal, miscUiState, activeModalStack } from '../globalState'
1919
import { options } from '../optionsStorage'
2020
import Minimap, { DisplayMode } from './Minimap'
2121
import { ChunkInfo, DrawerAdapter, MapUpdates, MinimapDrawer } from './MinimapDrawer'
2222
import { useIsModalActive } from './utilsApp'
23+
import { lastConnectOptions } from './AppStatusProvider'
2324

2425
const getBlockKey = (x: number, z: number) => {
2526
return `${x},${z}`
@@ -167,9 +168,9 @@ export class DrawerAdapterImpl extends TypedEventEmitter<MapUpdates> implements
167168
// type suppressed until server is updated. It works fine
168169
void (localServer as any).setWarp(warp, remove)
169170
} else if (remove) {
170-
localStorage.removeItem(`warps: ${loadedGameState.username} ${loadedGameState.serverIp}`)
171+
localStorage.removeItem(`warps: ${bot.player.username} ${lastConnectOptions.value!.server}`)
171172
} else {
172-
localStorage.setItem(`warps: ${loadedGameState.username} ${loadedGameState.serverIp}`, JSON.stringify(this.warps))
173+
localStorage.setItem(`warps: ${bot.player.username} ${lastConnectOptions.value!.server}`, JSON.stringify(this.warps))
173174
}
174175
this.emit('updateWarps')
175176
}

src/react/MobileTopButtons.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export default () => {
2121
}, [])
2222

2323
const onLongPress = async () => {
24-
const select = await showOptionsModal('', f3Keybinds.filter(f3Keybind => f3Keybind.mobileTitle).map(f3Keybind => f3Keybind.mobileTitle))
24+
const select = await showOptionsModal('', f3Keybinds.filter(f3Keybind => f3Keybind.mobileTitle && (f3Keybind.enabled?.() ?? true)).map(f3Keybind => f3Keybind.mobileTitle))
2525
if (!select) return
2626
const f3Keybind = f3Keybinds.find(f3Keybind => f3Keybind.mobileTitle === select)
2727
if (f3Keybind) f3Keybind.action()

src/react/PlayerListOverlayProvider.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { useSnapshot } from 'valtio'
22
import { useState, useEffect, useMemo } from 'react'
3-
import { isGameActive, loadedGameState } from '../globalState'
3+
import { isGameActive } from '../globalState'
44
import PlayerListOverlay from './PlayerListOverlay'
55
import './PlayerListOverlay.css'
6+
import { lastConnectOptions } from './AppStatusProvider'
67

78
const MAX_ROWS_PER_COL = 10
89

910
type Players = typeof bot.players
1011

1112
export default () => {
12-
const { serverIp } = useSnapshot(loadedGameState)
13+
const serverIp = lastConnectOptions.value?.server
1314
const [clientId, setClientId] = useState('')
1415
const [players, setPlayers] = useState<Players>({})
1516
const [isOpen, setIsOpen] = useState(false)

src/resourcePack.ts

+31-5
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import fs from 'fs'
44
import JSZip from 'jszip'
55
import { proxy, subscribe } from 'valtio'
66
import { WorldRendererThree } from 'prismarine-viewer/viewer/lib/worldrendererThree'
7-
import { mkdirRecursive, removeFileRecursiveAsync } from './browserfs'
7+
import { collectFilesToCopy, copyFilesAsyncWithProgress, mkdirRecursive, removeFileRecursiveAsync } from './browserfs'
88
import { setLoadingScreenStatus } from './utils'
99
import { showNotification } from './react/NotificationProvider'
1010
import { options } from './optionsStorage'
1111
import { showOptionsModal } from './react/SelectOption'
1212
import { appStatusState } from './react/AppStatusProvider'
1313
import { appReplacableResources, resourcesContentOriginal } from './generated/resources'
14-
import { loadedGameState, miscUiState } from './globalState'
14+
import { gameAdditionalState, miscUiState } from './globalState'
1515
import { watchUnloadForCleanup } from './gameUnload'
1616

1717
export const resourcePackState = proxy({
@@ -32,7 +32,7 @@ const texturePackBasePath = '/data/resourcePacks/'
3232
export const uninstallTexturePack = async (name = 'default') => {
3333
if (await existsAsync('/resourcepack/pack.mcmeta')) {
3434
await removeFileRecursiveAsync('/resourcepack')
35-
loadedGameState.usingServerResourcePack = false
35+
gameAdditionalState.usingServerResourcePack = false
3636
}
3737
const basePath = texturePackBasePath + name
3838
if (!(await existsAsync(basePath))) return
@@ -113,7 +113,7 @@ export const installTexturePack = async (file: File | ArrayBuffer, displayName =
113113
done++
114114
upStatus()
115115
}))
116-
console.log('done')
116+
console.log('resource pack install done')
117117
await completeTexturePackInstall(displayName, name, isServer)
118118
}
119119

@@ -129,7 +129,7 @@ export const completeTexturePackInstall = async (displayName: string | undefined
129129
showNotification('Texturepack installed & enabled')
130130
await updateTexturePackInstalledState()
131131
if (isServer) {
132-
loadedGameState.usingServerResourcePack = true
132+
gameAdditionalState.usingServerResourcePack = true
133133
} else {
134134
options.enabledResourcepack = name
135135
}
@@ -463,3 +463,29 @@ const updateTextures = async () => {
463463
export const resourcepackReload = async (version) => {
464464
await updateTextures()
465465
}
466+
467+
export const copyServerResourcePackToRegular = async (name = 'default') => {
468+
// Check if server resource pack exists
469+
if (!(await existsAsync('/resourcepack/pack.mcmeta'))) {
470+
throw new Error('No server resource pack is currently installed')
471+
}
472+
473+
// Get display name from server resource pack if available
474+
let displayName
475+
try {
476+
displayName = await fs.promises.readFile('/resourcepack/name.txt', 'utf8')
477+
} catch {
478+
displayName = 'Server Resource Pack'
479+
}
480+
481+
// Copy all files from server resource pack to regular location
482+
const destPath = texturePackBasePath + name
483+
await mkdirRecursive(destPath)
484+
485+
setLoadingScreenStatus('Copying server resource pack to regular location')
486+
await copyFilesAsyncWithProgress('/resourcepack', destPath, true, ' (server -> regular)')
487+
488+
// Complete the installation
489+
await completeTexturePackInstall(displayName, name, false)
490+
showNotification('Server resource pack copied to regular location')
491+
}

0 commit comments

Comments
 (0)