Files
launcher/src/app/main/game/page.tsx
T

398 lines
15 KiB
TypeScript

'use client'
import '../Installs.css'
import { useEffect } from 'react'
import { useGlobal } from '@/providers/GlobalProvider'
import { useSearchParams } from 'next/navigation'
import { platform } from '@tauri-apps/plugin-os'
import { faWarning } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { ask } from '@tauri-apps/plugin-dialog'
import { BaseDirectory, exists } from '@tauri-apps/plugin-fs'
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
export default function Installs () {
const {
versionsList,
serverVersionList,
showPopup,
setShowPopup,
setPopupMode,
setFadeOut,
setSelectedVersionList,
setManagingVersion,
setSelectedGame,
category,
setCategory,
downloadVersions,
downloadProgress,
linuxUseWine,
customDataLocation,
needsRevisionUpdate,
launchGame,
developerMode,
theme,
accountSession,
accountId,
accountName,
version
} = useGlobal()
const params = useSearchParams()
const id = Number(params.get('id') || 0)
const game = serverVersionList?.games.find(g => g.id === id)
useEffect(() => {
if (!showPopup) return
setSelectedVersionList([])
}, [setSelectedVersionList, showPopup])
if (!id || !game) return null
const filteredVersions = Object.keys(versionsList).filter(v => {
const info = serverVersionList?.versions.find(vf => vf.id == v)
if (!info) return false
if (platform() == 'linux' && info.wine && !linuxUseWine) return false
return (
info.game === id &&
(category == -1 ? info.category == -1 : info.category == category)
)
})
return (
<div className='mx-4 mt-4'>
<div className='flex justify-between items-center mb-4'>
<p className='text-3xl truncate min-w-0 flex-1'>{game.name} Installs</p>
<div className='flex gap-2'>
{game.id == 1 && (
<>
<button
className='button btntheme1'
onClick={async () => {
const window = await WebviewWindow.getByLabel(
'berrydashchatroom'
)
if (window) {
await window.setFocus()
return
}
new WebviewWindow('berrydashchatroom', {
title: 'Berry Dash Chatroom',
url: `https://games.lncvrt.xyz/game/berry-dash/chatroom?launcher=${version}&theme=${theme}&accountToken=${accountSession}&accountId=${accountId}&accountName=${accountName}`,
width: 800,
height: 600,
minWidth: 800,
minHeight: 600
})
}}
title='View the chatroom for this game.'
>
Chatroom
</button>
<button
className='button btntheme1'
onClick={async () => {
const window = await WebviewWindow.getByLabel(
'berrydashleaderboards'
)
if (window) {
await window.setFocus()
return
}
new WebviewWindow('berrydashleaderboards', {
title: 'Berry Dash Leaderboards',
url: `https://games.lncvrt.xyz/game/berry-dash/leaderboards?launcher=${version}&theme=${theme}`,
width: 800,
height: 600,
minWidth: 800,
minHeight: 600
})
}}
title='View the leaderboards for this game.'
>
Leaderboards
</button>
</>
)}
{game.id == 9 && category == -1 && (
<button
className='button btntheme1'
onClick={async () => {
const window = await WebviewWindow.getByLabel('xpsdashboard')
if (window) {
await window.setFocus()
return
}
new WebviewWindow('xpsdashboard', {
title: 'XPS Dashboard',
url: 'https://xps.lncvrt.xyz/dashboard/',
width: 1280,
height: 720,
minWidth: 1280,
minHeight: 720
})
}}
title='Open the GDPS Dashboard!'
>
Dashboard
</button>
)}
{game.id == 11 && category == -1 && (
<button
className='button btntheme1'
onClick={async () => {
const window = await WebviewWindow.getByLabel('georayschatroom')
if (window) {
await window.setFocus()
return
}
new WebviewWindow('georayschatroom', {
title: 'Geometry Rays Chatroom',
url: `https://games.lncvrt.xyz/game/geometry-rays/chatroom?launcher=${version}&theme=${theme}`,
width: 800,
height: 600,
minWidth: 800,
minHeight: 600
})
}}
title='View the chatroom for this game.'
>
Chatroom
</button>
)}
{category != -1 && (
<button
className='button btntheme1'
onClick={() => {
setCategory(-1)
}}
title='Click to go up a level.'
>
Back
</button>
)}
<button
className='button btntheme1'
onClick={() => {
setSelectedGame(id)
setPopupMode(0)
setShowPopup(true)
setFadeOut(false)
}}
title='Click to download more versions of this game.'
>
Download versions
</button>
</div>
</div>
<div className='downloads-container'>
<div
className={`downloads-scroll ${
platform() == 'windows'
? 'h-[calc(100vh-116px)]'
: 'h-[calc(100vh-84px)]'
}`}
>
{category == -1 &&
Object.entries(game.categoryNames)
.filter(([key]) => {
const count = Object.keys(versionsList).filter(v => {
const info = serverVersionList?.versions.find(
vf => vf.id == v
)
if (!info) return false
if (platform() == 'linux' && info.wine && !linuxUseWine)
return false
return info.game === id && info.category === Number(key)
}).length
return count >= 1
})
.sort(([a], [b]) => Number(b) - Number(a))
.map(([key, value]) => {
return (
<div
key={key}
className='downloads-entry'
title='Click to view category.'
onClick={() => setCategory(Number(key))}
>
<div className='h-18 w-screen relative'>
{developerMode && (
<p className='absolute bottom-0 right-0 text-sm'>
{key}
</p>
)}
<p className='text-2xl'>{value}</p>
<div
className='entry-info-item flex absolute left-0 bottom-0'
title='The amount of versions installed of this game in installed/installable format.'
onClick={e => e.stopPropagation()}
>
<p>
{(() => {
const count =
Object.keys(versionsList).filter(v => {
const info = serverVersionList?.versions.find(
vf => vf.id == v
)
if (!info) return false
if (
platform() == 'linux' &&
info.wine &&
!linuxUseWine
)
return false
return (
info.game === id &&
info.category == Number(key)
)
}).length ?? 0
return `${count} install${count === 1 ? '' : 's'}`
})()}
</p>
</div>
</div>
</div>
)
})}
{filteredVersions.length === 0 &&
(category !== -1 ||
Object.keys(versionsList).filter(v => {
const info = serverVersionList?.versions.find(vf => vf.id == v)
if (!info) return false
if (platform() == 'linux' && info.wine && !linuxUseWine)
return false
return info.game === id
}).length === 0) && (
<div className='flex justify-center items-center h-full'>
<p className='text-3xl'>No versions installed</p>
</div>
)}
{filteredVersions
.sort((a, b) => {
const infoA = serverVersionList?.versions.find(vf => vf.id == a)
const infoB = serverVersionList?.versions.find(vf => vf.id == b)
if (!infoA || !infoB) return 0
return infoB.place - infoA.place
})
.map(v => {
const versionInfo = serverVersionList?.versions.find(
vf => vf.id == v
)
if (!versionInfo) return
return (
<div
key={v}
className='downloads-entry'
title='Click to launch game. Right-click to manage this version install.'
onClick={async () => await launchGame(versionInfo)}
onContextMenu={e => {
e.preventDefault()
setManagingVersion(v)
setPopupMode(2)
setShowPopup(true)
setFadeOut(false)
}}
>
<div className='h-18 w-screen relative'>
{developerMode && (
<p className='absolute bottom-0 right-0 text-sm'>
{versionInfo.id}
</p>
)}
<p className='text-2xl'>{versionInfo.displayName}</p>
<div className='flex gap-2 absolute left-0 bottom-0'>
<div
className='entry-info-item'
title='The date the game was installed.'
>
<p>
Installed{' '}
{new Intl.DateTimeFormat(undefined).format(
versionsList[v]
)}
</p>
</div>
{platform() == 'linux' &&
versionInfo.wine &&
!needsRevisionUpdate(versionInfo.lastRevision, v) && (
<div
className='entry-info-item'
title='This version is using wine. It cannot be guarenteed to work fully and might not work at all.'
>
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
<p>Uses wine</p>
</div>
)}
{needsRevisionUpdate(versionInfo.lastRevision, v) && (
<div className='entry-info-item'>
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
<p>Needs revision update!</p>
</div>
)}
</div>
{versionInfo.modSupportDownload && (
<button
className='absolute right-0 bottom-0 button'
title='Click to manage mods for this game!'
onClick={async e => {
e.stopPropagation()
if (
!(await exists(
customDataLocation
? customDataLocation + '/'
: null + 'game/' + v + '/BepInEx',
{
baseDir: customDataLocation
? undefined
: BaseDirectory.AppLocalData
}
))
) {
if (
(await ask(
"You don't have BepInEx (the mod loader for Unity Games), would you like to install it now? It is about 1MB in size. If you choose yes, it will download the recommended BepInEx version for " +
versionInfo.displayName +
'.',
{ title: 'BepInEx not found!', kind: 'error' }
)) &&
!downloadProgress.find(d => d.version == v)
) {
await downloadVersions([
{
id: v,
type: 1
}
])
}
return
}
setManagingVersion(v)
setPopupMode(3)
setShowPopup(true)
setFadeOut(false)
}}
>
Mod Manager
</button>
)}
</div>
</div>
)
})}
</div>
</div>
</div>
)
}