Skip to content

Commit

Permalink
New Progressbar system and updated game launcher
Browse files Browse the repository at this point in the history
New Progressbar system and updated game launcher
  • Loading branch information
Kensaa committed Jan 12, 2024
2 parents fe22f70 + fe22226 commit c645f6d
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 118 deletions.
75 changes: 51 additions & 24 deletions launcher/electron/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from 'path'
import * as os from 'os'
import * as fs from 'fs'
import * as msmc from 'msmc'
import { Client } from '@kensaa/minecraft-launcher-core'
import { Client } from 'minecraft-launcher-core'
import { Profile } from '../src/types'
import { createLogger } from './logger'
import decompress from 'decompress'
Expand Down Expand Up @@ -34,8 +34,7 @@ let win: BrowserWindow | null = null
const platform = os.platform()
const supportedPlatforms = ['win32', 'linux']

let startProgress = 0
let loginProgress = 0
let currentTask: { title: string; progress: number } | undefined = undefined
let gameStarting = false

if (!supportedPlatforms.includes(platform)) {
Expand Down Expand Up @@ -145,9 +144,16 @@ ipcMain.handle('msmc-connect', (event, arg) => {
logger.debug('msmc-connect (async)')
return new Promise<boolean>(resolve => {
logger.info('Connecting to Microsoft sevices...')
currentTask = {
title: 'Logging in',
progress: 0
}
msmc.fastLaunch('electron', info => {
if (!info.percent) return
loginProgress = info.percent
currentTask = {
title: 'Logging in',
progress: info.percent ?? 0
}
})
.then(res => {
logger.info('Connected')
Expand Down Expand Up @@ -269,6 +275,11 @@ ipcMain.handle('start-game', async (event, args: Profile) => {
checkExist(path.join(config.rootDir, 'addedMods'))
checkExist(path.join(config.rootDir, 'java'))

currentTask = {
title: 'Starting Game',
progress: 0
}

// cdn check
const primaryServer = config.servers[config.selectedServer]
let downloadServer = primaryServer
Expand Down Expand Up @@ -425,17 +436,19 @@ ipcMain.handle('start-game', async (event, args: Profile) => {
logger.info('Updating file "%s"', localPath)
await download(fileUrl, filepath)
count++
startProgress = Math.round(
(count / fileCount) * 100
)
currentTask = {
title: 'Updating Mods',
progress: (count / fileCount) * 100
}
}
} else {
logger.info('Downloading file "%s"', localPath)
await download(fileUrl, filepath)
count++
startProgress = Math.round(
(count / fileCount) * 100
)
currentTask = {
title: 'Updating Mods',
progress: (count / fileCount) * 100
}
}
} else {
// Element is a folder
Expand Down Expand Up @@ -512,27 +525,41 @@ ipcMain.handle('start-game', async (event, args: Profile) => {
}
launcher.launch(opts as any)

let gameStarted = false
launcher.on('data', e => {
if (!gameStarted) {
gameStarted = true
if (config.closeLauncher) setTimeout(app.quit, 5000)
gameStarting = false
resolve()
}
// sometimes multiple lines arrive at once
for (const s of e.trim().split('\n')) logger.game(s.trim())
})
launcher.on('start', () => {
if (!config) return
if (config.closeLauncher) setTimeout(app.quit, 5000)
gameStarting = false
resolve()
})

launcher.on('progress', progress => {
if (typeof progress !== 'number') return
startProgress = progress
console.log(progress)
const {
type,
task: current,
total
} = progress as { type: string; task: number; total: number }

if (['assets', 'natives'].includes(type)) {
currentTask = {
title: `Downloading ${type}`,
progress: (current / total) * 100
}
} else {
currentTask = {
title: 'Starting Game',
progress: (current / total) * 100
}
}
})
})
})

ipcMain.on('get-start-progress', event => {
event.returnValue = startProgress
})

ipcMain.on('get-login-progress', event => {
event.returnValue = loginProgress
ipcMain.on('get-current-task', event => {
event.returnValue = currentTask
})
4 changes: 2 additions & 2 deletions launcher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
"description": "A Minecraft launcher with auto-update feature to facilitate playing modded minecraft",
"author": "Kensa",
"private": true,
"version": "2.4.4",
"version": "2.5.0",
"main": "dist-electron/electron.js",
"scripts": {
"dev": "vite",
"build": "rm -r -f release && yarn && tsc && vite build && electron-builder --x64 -wl && rm -r dist-electron && rm -r dist",
"release": "tsx github-release.ts"
},
"dependencies": {
"@kensaa/minecraft-launcher-core": "^3.17.3",
"bootstrap": "^5.3.0",
"decompress": "^4.2.1",
"electron-fetch": "^1.9.1",
"lucide-react": "^0.104.1",
"minecraft-launcher-core": "^3.17.3",
"msmc": "^3.1.3",
"pino": "^8.14.1",
"pino-pretty": "^10.0.1",
Expand Down
5 changes: 1 addition & 4 deletions launcher/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ export default function App() {
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Settings
setOverlay={setOverlay}
hide={() => setSettingsShown(false)}
/>
<Settings hide={() => setSettingsShown(false)} />
</Modal.Body>
</Modal>
</div>
Expand Down
26 changes: 26 additions & 0 deletions launcher/src/components/TaskOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ProgressBar } from 'react-bootstrap'
import { useTask } from '../utils'

interface TaskOverlayProps {
title?: string
}

export default function TaskOverlay({ title }: TaskOverlayProps) {
const task = useTask()

return (
<div className='overlay'>
{title && <h1>{title}</h1>}
{task && (
<div className='w-100 d-flex flex-column align-items-center mt-2'>
<h4>{task.title}</h4>
<ProgressBar
className='w-75'
now={task.progress}
label={`${task.progress.toFixed(1)}%`}
/>
</div>
)}
</div>
)
}
4 changes: 2 additions & 2 deletions launcher/src/components/UserElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import authStore from '../stores/auth'
import { Button, Dropdown, DropdownButton } from 'react-bootstrap'
import { User, UserPlus } from 'lucide-react'

import ConnectingOverlay from '../overlays/ConnectingOverlay'
import TaskOverlay from './TaskOverlay'

export default function UserElement({
setOverlay
Expand All @@ -11,7 +11,7 @@ export default function UserElement({
}) {
const auth = authStore(state => ({ ...state }))
const login = () => {
setOverlay(<ConnectingOverlay />)
setOverlay(<TaskOverlay />)
auth.connect().then(() => setOverlay(undefined))
}

Expand Down
21 changes: 0 additions & 21 deletions launcher/src/overlays/ConnectingOverlay.tsx

This file was deleted.

25 changes: 0 additions & 25 deletions launcher/src/overlays/GameStartingOverlay.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions launcher/src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ipcRenderer } from 'electron'
import { useEffect, useState } from 'react'
import { Alert, Button } from 'react-bootstrap'
import GameStartingOverlay from '../overlays/GameStartingOverlay'
import HomeHeader from '../components/HomeHeader'

import authStore from '../stores/auth'
Expand All @@ -10,6 +9,7 @@ import { Profile } from '../types'

import minecraft from '../img/minecraft.png'
import AlertStack from '../components/AlertStack'
import TaskOverlay from '../components/TaskOverlay'

export default function Home({
setOverlay,
Expand Down Expand Up @@ -66,10 +66,10 @@ export default function Home({
}, [])

const startGame = () => {
setOverlay(<GameStartingOverlay />)
setOverlay(<TaskOverlay title='Starting Game' />)
ipcRenderer
.invoke('start-game', profiles[selectedProfile])
.then(res => setOverlay(undefined))
.then(() => setOverlay(undefined))
.catch(error => console.log(error))
}
return (
Expand Down
3 changes: 1 addition & 2 deletions launcher/src/pages/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import configStore from '../stores/config'

interface SettingsProps {
hide: () => void
setOverlay: (overlay: JSX.Element | undefined) => void
}

type SettingValue = string | number | boolean
type Setter = (s: SettingValue) => void

export default function Settings({ hide, setOverlay }: SettingsProps) {
export default function Settings({ hide }: SettingsProps) {
const config = configStore(store => ({ ...store }))

const [rootDir, setRootDir] = useState(config.rootDir)
Expand Down
23 changes: 17 additions & 6 deletions launcher/src/style/style.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "~bootstrap/scss/bootstrap";
@import '~bootstrap/scss/bootstrap';

html,
body,
Expand All @@ -15,6 +15,15 @@ body,
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99;

width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
user-select: none;
color: #fff;
}

.small {
Expand All @@ -31,7 +40,9 @@ body,
}

.btn {
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, backdrop-filter 0.15s ease-in-out;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out,
backdrop-filter 0.15s ease-in-out;
}

.btn-transparent {
Expand All @@ -55,7 +66,7 @@ body,
& ~ .dropdown-menu {
backdrop-filter: blur(4px) brightness(80%);
box-shadow: 4px 7px 14px 0.1rem rgb(0 0 0 / 50%);

--bs-dropdown-bg: rgba(0, 0, 0, 0.05);
--bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);
}
Expand All @@ -71,15 +82,15 @@ h6 {
}

.smooth-background-down {
background: linear-gradient(#1e1e1e, rgba(0, 0, 0, 0.0));
background: linear-gradient(#1e1e1e, rgba(0, 0, 0, 0));
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}

.smooth-background-up {
background: linear-gradient(rgba(0, 0, 0, 0.0), #1e1e1e);
background: linear-gradient(rgba(0, 0, 0, 0), #1e1e1e);
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
}
5 changes: 5 additions & 0 deletions launcher/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ export interface Profile {
}
gameFolder?: string
}

export interface Task {
title: string
progress: number
}
14 changes: 14 additions & 0 deletions launcher/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useEffect, useState } from 'react'
import type { Task } from './types'
import { ipcRenderer } from 'electron'

export function useFetch(address: string, options: RequestInit) {
const [data, setData] = useState([])
Expand Down Expand Up @@ -27,3 +29,15 @@ export function urlJoin(...args: string[]) {
.replace(/\/+/g, '/')
)
}

export function useTask() {
const [task, setTask] = useState<Task | undefined>(undefined)
useEffect(() => {
let interval = setInterval(() => {
setTask(ipcRenderer.sendSync('get-current-task'))
}, 1000)
return () => clearInterval(interval)
}, [])

return task
}
Loading

0 comments on commit c645f6d

Please sign in to comment.