mirror of
https://github.com/artegoser/pimi-launcher.git
synced 2024-11-05 12:03:58 +03:00
feat: terminal
This commit is contained in:
parent
bff72b3ff8
commit
4b332b8aa2
7 changed files with 136 additions and 77 deletions
|
@ -18,7 +18,7 @@ import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
|||
import react from '@vitejs/plugin-react'
|
||||
import commonjsExternals from 'vite-plugin-commonjs-externals'
|
||||
|
||||
const externals = ['pimi-launcher-core', 'path', 'process', 'fs']
|
||||
const externals = ['pimi-launcher-core', 'path', 'process', 'fs', 'console']
|
||||
|
||||
export default defineConfig({
|
||||
main: {
|
||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "pimi-launcher",
|
||||
"version": "1.1.0-alpha",
|
||||
"version": "1.2.0-alpha",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pimi-launcher",
|
||||
"version": "1.1.0-alpha",
|
||||
"version": "1.2.0-alpha",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@electron-toolkit/preload": "^2.0.0",
|
||||
|
@ -16,6 +16,7 @@
|
|||
"pimi-launcher-core": "^1.1.1",
|
||||
"react-router-dom": "^6.13.0",
|
||||
"react-select": "^5.7.3",
|
||||
"react-terminal-ui": "^1.0.5",
|
||||
"vite-plugin-commonjs-externals": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -7530,6 +7531,15 @@
|
|||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-terminal-ui": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/react-terminal-ui/-/react-terminal-ui-1.0.5.tgz",
|
||||
"integrity": "sha512-yR19ej58dwU3koLiTR0m0nLbqJZoOyeThGWg1B3VrwUs+PLraqjP2C4AkRgiGNUwWMn4u6T0djY5DZXq0Zlvjg==",
|
||||
"peerDependencies": {
|
||||
"react": ">16.13.0",
|
||||
"react-dom": ">16.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "pimi-launcher",
|
||||
"version": "1.1.1-alpha",
|
||||
"version": "1.2.0-alpha",
|
||||
"description": "Modern Minecraft Launcher",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "artegoser",
|
||||
|
@ -27,6 +27,7 @@
|
|||
"pimi-launcher-core": "^1.1.1",
|
||||
"react-router-dom": "^6.13.0",
|
||||
"react-select": "^5.7.3",
|
||||
"react-terminal-ui": "^1.0.5",
|
||||
"vite-plugin-commonjs-externals": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -5,3 +5,7 @@
|
|||
.inputs {
|
||||
@apply bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
|
|
21
src/renderer/src/components/MinecraftTerminal.jsx
Normal file
21
src/renderer/src/components/MinecraftTerminal.jsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import Terminal, { ColorMode, TerminalOutput } from 'react-terminal-ui'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
function MinecraftTerminal({ lines, height = '300px' }) {
|
||||
const terminalLineData = lines.map((line, index) => (
|
||||
<TerminalOutput key={index}>{line}</TerminalOutput>
|
||||
))
|
||||
|
||||
return (
|
||||
<Terminal name="Minecraft Console" height={height} colorMode={ColorMode.Light}>
|
||||
{terminalLineData}
|
||||
</Terminal>
|
||||
)
|
||||
}
|
||||
|
||||
MinecraftTerminal.propTypes = {
|
||||
lines: PropTypes.arrayOf(PropTypes.string),
|
||||
height: PropTypes.string
|
||||
}
|
||||
|
||||
export default MinecraftTerminal
|
|
@ -1,7 +1,14 @@
|
|||
import { Client, Authenticator } from 'pimi-launcher-core'
|
||||
|
||||
async function launch(version, setProgress, setDownload, setGameStarted, setStarted) {
|
||||
async function launch(
|
||||
version,
|
||||
setProgress,
|
||||
setDownload,
|
||||
setGameStarted,
|
||||
setStarted,
|
||||
setTerminalLines
|
||||
) {
|
||||
const launcher = new Client()
|
||||
let terminalLines = []
|
||||
|
||||
let opts = {
|
||||
authorization: Authenticator.getAuth(
|
||||
|
@ -23,13 +30,20 @@ async function launch(version, setProgress, setDownload, setGameStarted, setStar
|
|||
|
||||
launcher.on('progress', (e) => setProgress(e))
|
||||
launcher.on('download', (e) => setDownload(e))
|
||||
launcher.on('debug', (e) => console.log(e))
|
||||
launcher.on('data', (e) => console.log(e))
|
||||
launcher.on('debug', (e) => {
|
||||
terminalLines = terminalLines.concat(e)
|
||||
setTerminalLines(terminalLines)
|
||||
})
|
||||
launcher.on('data', (e) => {
|
||||
terminalLines = terminalLines.concat(e)
|
||||
setTerminalLines(terminalLines)
|
||||
})
|
||||
|
||||
launcher.on('arguments', () => setGameStarted(true))
|
||||
launcher.on('close', () => {
|
||||
setGameStarted(false)
|
||||
setStarted(false)
|
||||
setTerminalLines([])
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import { launch } from '../components/utils'
|
|||
import Select from 'react-select'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import MinecraftTerminal from '../components/MinecraftTerminal'
|
||||
function Main() {
|
||||
const [versions, setVersions] = useState(false)
|
||||
const [version, setVersion] = useState(false)
|
||||
|
@ -27,6 +28,7 @@ function Main() {
|
|||
const [started, setStarted] = useState(false)
|
||||
const [gameStarted, setGameStarted] = useState(false)
|
||||
const [installed_versions, setInstalledVersions] = useState(false)
|
||||
const [terminalLines, setTerminalLines] = useState([])
|
||||
|
||||
useEffect(() => {
|
||||
if (!versions) {
|
||||
|
@ -38,79 +40,86 @@ function Main() {
|
|||
}
|
||||
})
|
||||
|
||||
console.log('hi')
|
||||
|
||||
return (
|
||||
versions && (
|
||||
<div className="grid grid-cols-3 gap-4 m-5">
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
className="inputs"
|
||||
placeholder="Your name"
|
||||
defaultValue={localStorage.getItem('name') || 'Steve'}
|
||||
onChange={(e) => {
|
||||
localStorage.setItem('name', e.target.value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Select
|
||||
onChange={(e) => {
|
||||
setVersion(versions[e.value])
|
||||
}}
|
||||
defaultValue={{ value: versions[0], label: versions[0].id }}
|
||||
options={versions.map((version, index) => {
|
||||
return {
|
||||
value: index,
|
||||
label: version.id,
|
||||
type: version.type,
|
||||
installed: installed_versions?.includes(version.id)
|
||||
}
|
||||
})}
|
||||
styles={{
|
||||
control: (styles) => ({
|
||||
...styles,
|
||||
backgroundColor: 'white'
|
||||
}),
|
||||
option: (styles, { data, isFocused }) => ({
|
||||
...styles,
|
||||
backgroundColor: isFocused ? '#c9d2e7' : data.installed ? '#cccccc' : 'white'
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type="button"
|
||||
value="Start"
|
||||
className="inputs"
|
||||
onClick={() => {
|
||||
launch(version, setProgress, setDownload, setGameStarted, setStarted)
|
||||
setStarted(true)
|
||||
}}
|
||||
disabled={started}
|
||||
/>
|
||||
</div>
|
||||
<>
|
||||
<div className="grid grid-cols-3 gap-4 m-5">
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
className="inputs"
|
||||
placeholder="Your name"
|
||||
defaultValue={localStorage.getItem('name') || 'Steve'}
|
||||
onChange={(e) => {
|
||||
localStorage.setItem('name', e.target.value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Select
|
||||
onChange={(e) => {
|
||||
setVersion(versions[e.value])
|
||||
}}
|
||||
defaultValue={{ value: versions[0], label: versions[0].id }}
|
||||
options={versions.map((version, index) => {
|
||||
return {
|
||||
value: index,
|
||||
label: version.id,
|
||||
type: version.type,
|
||||
installed: installed_versions?.includes(version.id)
|
||||
}
|
||||
})}
|
||||
styles={{
|
||||
control: (styles) => ({
|
||||
...styles,
|
||||
backgroundColor: 'white'
|
||||
}),
|
||||
option: (styles, { data, isFocused }) => ({
|
||||
...styles,
|
||||
backgroundColor: isFocused ? '#c9d2e7' : data.installed ? '#cccccc' : 'white'
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
type="button"
|
||||
value="Start"
|
||||
className="inputs"
|
||||
onClick={() => {
|
||||
launch(
|
||||
version,
|
||||
setProgress,
|
||||
setDownload,
|
||||
setGameStarted,
|
||||
setStarted,
|
||||
setTerminalLines
|
||||
)
|
||||
setStarted(true)
|
||||
}}
|
||||
disabled={started}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{started && gameStarted && (
|
||||
<>
|
||||
<div className="text-2xl font-bold">Minecraft launches...</div>
|
||||
</>
|
||||
{started && !gameStarted && (
|
||||
<>
|
||||
<div className="text-2xl font-bold">Downloading{'.'.repeat(progress.task % 3)}</div>
|
||||
<div className="break-words text-2xl font-bold">
|
||||
{download || 'please wait'} {`(${progress.type})` || ''}
|
||||
</div>
|
||||
<div className="text-2xl font-bold">
|
||||
{((progress.task / progress.total) * 100 || 0).toFixed(2)}%
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{started && (
|
||||
<div className="m-5">
|
||||
<MinecraftTerminal lines={terminalLines} />
|
||||
</div>
|
||||
)}
|
||||
{started && !gameStarted && (
|
||||
<>
|
||||
<div className="text-2xl font-bold">Downloading{'.'.repeat(progress.task % 3)}</div>
|
||||
<div className="break-words text-2xl font-bold">
|
||||
{download || 'please wait'} {`(${progress.type})` || ''}
|
||||
</div>
|
||||
<div className="text-2xl font-bold">
|
||||
{((progress.task / progress.total) * 100 || 0).toFixed(2)}%
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue