Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Vitaly Turovsky
c1086ebdcb add monaco 2025-08-21 13:14:21 +03:00
7 changed files with 286 additions and 15 deletions

View file

@ -54,6 +54,7 @@
"dependencies": {
"@dimaka/interface": "0.0.3-alpha.0",
"@floating-ui/react": "^0.26.1",
"@monaco-editor/react": "^4.7.0",
"@nxg-org/mineflayer-auto-jump": "^0.7.18",
"@nxg-org/mineflayer-tracker": "1.3.0",
"@react-oauth/google": "^0.12.1",

58
pnpm-lock.yaml generated
View file

@ -42,6 +42,9 @@ importers:
'@floating-ui/react':
specifier: ^0.26.1
version: 0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@monaco-editor/react':
specifier: ^4.7.0
version: 4.7.0(monaco-editor@0.52.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@nxg-org/mineflayer-auto-jump':
specifier: ^0.7.18
version: 0.7.18
@ -430,13 +433,13 @@ importers:
version: 1.3.9
prismarine-block:
specifier: github:zardoy/prismarine-block#next-era
version: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0)
version: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9
prismarine-chunk:
specifier: github:zardoy/prismarine-chunk#master
version: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/c5feac83b61d95feb4d4f22c063dacfb8c192a9f(minecraft-data@3.92.0)
prismarine-schematic:
specifier: ^1.2.0
version: 1.2.3(prismarine-registry@1.11.0)
version: 1.2.3
process:
specifier: ^0.11.10
version: 0.11.10
@ -1989,6 +1992,16 @@ packages:
'@module-federation/webpack-bundler-runtime@0.11.2':
resolution: {integrity: sha512-WdwIE6QF+MKs/PdVu0cKPETF743JB9PZ62/qf7Uo3gU4fjsUMc37RnbJZ/qB60EaHHfjwp1v6NnhZw1r4eVsnw==}
'@monaco-editor/loader@1.5.0':
resolution: {integrity: sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==}
'@monaco-editor/react@4.7.0':
resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==}
peerDependencies:
monaco-editor: '>= 0.25.0 < 1'
react: ^18.2.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
'@msgpack/msgpack@2.8.0':
resolution: {integrity: sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==}
engines: {node: '>= 10'}
@ -6769,6 +6782,9 @@ packages:
mojangson@2.0.4:
resolution: {integrity: sha512-HYmhgDjr1gzF7trGgvcC/huIg2L8FsVbi/KacRe6r1AswbboGVZDS47SOZlomPuMWvZLas8m9vuHHucdZMwTmQ==}
monaco-editor@0.52.2:
resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==}
moo@0.5.2:
resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==}
@ -8373,6 +8389,9 @@ packages:
stacktrace-js@2.0.2:
resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==}
state-local@1.0.7:
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
static-extend@0.1.2:
resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==}
engines: {node: '>=0.10.0'}
@ -11254,6 +11273,17 @@ snapshots:
'@module-federation/runtime': 0.11.2
'@module-federation/sdk': 0.11.2
'@monaco-editor/loader@1.5.0':
dependencies:
state-local: 1.0.7
'@monaco-editor/react@4.7.0(monaco-editor@0.52.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@monaco-editor/loader': 1.5.0
monaco-editor: 0.52.2
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
'@msgpack/msgpack@2.8.0': {}
'@ndelangen/get-tarball@3.0.9':
@ -11309,7 +11339,7 @@ snapshots:
'@nxg-org/mineflayer-util-plugin': 1.8.4
minecraft-data: 3.92.0
mineflayer: https://codeload.github.com/zardoy/mineflayer/tar.gz/86e65631e79c490021afc63c80091a7bb6019fa8(encoding@0.1.13)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9
prismarine-item: 1.17.0
prismarine-physics: https://codeload.github.com/zardoy/prismarine-physics/tar.gz/353e25b800149393f40539ec381218be44cbb03b
vec3: 0.1.10
@ -17344,7 +17374,7 @@ snapshots:
minecraft-data: 3.92.0
minecraft-protocol: https://codeload.github.com/PrismarineJS/node-minecraft-protocol/tar.gz/c561917bf7e7966911321512c2a6895a3f9da074(patch_hash=4ebdae314c68d01ce7879445c0b8bde5f90373abba8b66ed00d42e7a5f542f8b)(encoding@0.1.13)
prismarine-biome: 1.3.0(minecraft-data@3.92.0)(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9
prismarine-chat: 1.11.0
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/c5feac83b61d95feb4d4f22c063dacfb8c192a9f(minecraft-data@3.92.0)
prismarine-entity: 2.5.0
@ -17461,6 +17491,8 @@ snapshots:
dependencies:
nearley: 2.20.1
monaco-editor@0.52.2: {}
moo@0.5.2: {}
morgan@1.10.0:
@ -18135,7 +18167,7 @@ snapshots:
minecraft-data: 3.92.0
prismarine-registry: 1.11.0
prismarine-block@https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0):
prismarine-block@https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9:
dependencies:
minecraft-data: 3.92.0
prismarine-biome: 1.3.0(minecraft-data@3.92.0)(prismarine-registry@1.11.0)
@ -18143,8 +18175,6 @@ snapshots:
prismarine-item: 1.17.0
prismarine-nbt: 2.7.0
prismarine-registry: 1.11.0
transitivePeerDependencies:
- prismarine-registry
prismarine-chat@1.11.0:
dependencies:
@ -18155,7 +18185,7 @@ snapshots:
prismarine-chunk@https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/c5feac83b61d95feb4d4f22c063dacfb8c192a9f(minecraft-data@3.92.0):
dependencies:
prismarine-biome: 1.3.0(minecraft-data@3.92.0)(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9
prismarine-nbt: 2.7.0
prismarine-registry: 1.11.0
smart-buffer: 4.2.0
@ -18189,7 +18219,7 @@ snapshots:
prismarine-provider-anvil@https://codeload.github.com/zardoy/prismarine-provider-anvil/tar.gz/1d548fac63fe977c8281f0a9a522b37e4d92d0b7(minecraft-data@3.92.0):
dependencies:
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9
prismarine-chunk: https://codeload.github.com/zardoy/prismarine-chunk/tar.gz/c5feac83b61d95feb4d4f22c063dacfb8c192a9f(minecraft-data@3.92.0)
prismarine-nbt: 2.7.0
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/ab2146c9933eef3247c3f64446de4ccc2c484c7c
@ -18213,18 +18243,16 @@ snapshots:
prismarine-registry@1.11.0:
dependencies:
minecraft-data: 3.92.0
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9
prismarine-nbt: 2.7.0
prismarine-schematic@1.2.3(prismarine-registry@1.11.0):
prismarine-schematic@1.2.3:
dependencies:
minecraft-data: 3.92.0
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9(prismarine-registry@1.11.0)
prismarine-block: https://codeload.github.com/zardoy/prismarine-block/tar.gz/853c559bff2b402863ee9a75b125a3ca320838f9
prismarine-nbt: 2.7.0
prismarine-world: https://codeload.github.com/zardoy/prismarine-world/tar.gz/ab2146c9933eef3247c3f64446de4ccc2c484c7c
vec3: 0.1.10
transitivePeerDependencies:
- prismarine-registry
prismarine-windows@2.9.0:
dependencies:
@ -19521,6 +19549,8 @@ snapshots:
stack-generator: 2.0.10
stacktrace-gps: 3.1.2
state-local@1.0.7: {}
static-extend@0.1.2:
dependencies:
define-property: 0.2.5

106
src/core/ideChannels.ts Normal file
View file

@ -0,0 +1,106 @@
import { proxy } from 'valtio'
export const ideState = proxy({
id: '',
contents: '',
line: 0,
column: 0,
language: 'typescript',
title: '',
})
globalThis.ideState = ideState
export const registerIdeChannels = () => {
registerIdeOpenChannel()
registerIdeSaveChannel()
}
const registerIdeOpenChannel = () => {
const CHANNEL_NAME = 'minecraft-web-client:ide-open'
const packetStructure = [
'container',
[
{
name: 'id',
type: ['pstring', { countType: 'i16' }]
},
{
name: 'language',
type: ['pstring', { countType: 'i16' }]
},
{
name: 'contents',
type: ['pstring', { countType: 'i16' }]
},
{
name: 'line',
type: 'i32'
},
{
name: 'column',
type: 'i32'
},
{
name: 'title',
type: ['pstring', { countType: 'i16' }]
}
]
]
bot._client.registerChannel(CHANNEL_NAME, packetStructure, true)
bot._client.on(CHANNEL_NAME as any, (data) => {
const { id, language, contents, line, column, title } = data
ideState.contents = contents
ideState.line = line
ideState.column = column
ideState.id = id
ideState.language = language || 'typescript'
ideState.title = title
})
console.debug(`registered custom channel ${CHANNEL_NAME} channel`)
}
const IDE_SAVE_CHANNEL_NAME = 'minecraft-web-client:ide-save'
const registerIdeSaveChannel = () => {
const packetStructure = [
'container',
[
{
name: 'id',
type: ['pstring', { countType: 'i16' }]
},
{
name: 'contents',
type: ['pstring', { countType: 'i16' }]
},
{
name: 'language',
type: ['pstring', { countType: 'i16' }]
},
{
name: 'line',
type: 'i32'
},
{
name: 'column',
type: 'i32'
},
]
]
bot._client.registerChannel(IDE_SAVE_CHANNEL_NAME, packetStructure, true)
}
export const saveIde = () => {
bot._client.writeChannel(IDE_SAVE_CHANNEL_NAME, {
id: ideState.id,
contents: ideState.contents,
language: ideState.language,
// todo: reflect updated
line: ideState.line,
column: ideState.column,
})
}

View file

@ -2,6 +2,7 @@ import PItem from 'prismarine-item'
import { getThreeJsRendererMethods } from 'renderer/viewer/three/threeJsMethods'
import { options } from './optionsStorage'
import { jeiCustomCategories } from './inventoryWindows'
import { registerIdeChannels } from './core/ideChannels'
export default () => {
customEvents.on('mineflayerBotCreated', async () => {
@ -17,6 +18,7 @@ export default () => {
registeredJeiChannel()
registerBlockInteractionsCustomizationChannel()
registerWaypointChannels()
registerIdeChannels()
})
}

View file

@ -0,0 +1,58 @@
.monaco-editor-container {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 16px;
background-color: rgba(0, 0, 0, 0.5);
}
.monaco-editor-title {
font-size: 20px;
font-weight: bold;
color: #fff;
margin-bottom: 8px;
}
.monaco-editor-wrapper {
position: relative;
width: 100%;
height: 100%;
max-width: 80vw;
max-height: 80vh;
border: 3px solid #000;
background-color: #000;
padding: 3px;
box-shadow: inset 0 0 0 1px #fff, inset 0 0 0 2px #000;
}
.monaco-editor-close {
position: fixed;
top: 16px;
left: 16px;
z-index: 1001;
cursor: pointer;
padding: 8px;
}
@media (max-width: 768px) {
.monaco-editor-container {
padding: 0;
}
.monaco-editor-wrapper {
max-width: 100%;
max-height: 100%;
border-radius: 0;
}
.monaco-editor-close {
top: 8px;
left: 8px;
}
.monaco-editor-title {
/* todo: make it work on mobile */
display: none;
}
}

View file

@ -0,0 +1,73 @@
import { proxy, useSnapshot } from 'valtio'
import { useEffect } from 'react'
import { Editor } from '@monaco-editor/react'
import PixelartIcon, { pixelartIcons } from '../react/PixelartIcon'
import { useIsModalActive } from '../react/utilsApp'
import { showNotification } from '../react/NotificationProvider'
import { hideModal, showModal } from '../globalState'
import { ideState, saveIde } from '../core/ideChannels'
import './MonacoEditor.css'
export default () => {
const { contents, line, column, id, language, title } = useSnapshot(ideState)
const isModalActive = useIsModalActive('monaco-editor')
const bodyFont = getComputedStyle(document.body).fontFamily
useEffect(() => {
if (id && !isModalActive) {
showModal({ reactType: 'monaco-editor' })
}
if (!id && isModalActive) {
hideModal()
}
}, [id])
useEffect(() => {
if (!isModalActive && id) {
try {
saveIde()
} catch (err) {
reportError(err)
showNotification('Failed to save the editor', 'Please try again', true)
}
ideState.id = ''
ideState.contents = ''
}
}, [isModalActive])
if (!isModalActive) return null
return <div className="monaco-editor-container">
<div className="monaco-editor-close">
<PixelartIcon
iconName={pixelartIcons.close}
width={26}
onClick={() => {
hideModal()
}}
/>
</div>
<div className="monaco-editor-title">
{title}
</div>
<div className="monaco-editor-wrapper">
<Editor
height="100%"
width="100%"
language={language}
theme='vs-dark'
line={line}
onChange={(value) => {
ideState.contents = value ?? ''
}}
value={contents}
options={{
fontFamily: bodyFont,
minimap: {
enabled: true,
},
}}
/>
</div>
</div>
}

View file

@ -67,6 +67,7 @@ import GlobalOverlayHints from './react/GlobalOverlayHints'
import FullscreenTime from './react/FullscreenTime'
import StorageConflictModal from './react/StorageConflictModal'
import FireRenderer from './react/FireRenderer'
import MonacoEditor from './react/MonacoEditor'
const isFirefox = ua.getBrowser().name === 'Firefox'
if (isFirefox) {
@ -248,7 +249,6 @@ const App = () => {
<PacketsReplayProvider />
<NotificationProvider />
<ModsPage />
<SelectOption />
<CreditsAboutModal />
<NoModalFoundProvider />
@ -259,6 +259,7 @@ const App = () => {
</div>
<div />
<DebugEdges />
<MonacoEditor />
<DebugResponseTimeIndicator />
</RobustPortal>
</ButtonAppProvider>