Skip to content

Commit

Permalink
feat: Instance mods upgrade and
Browse files Browse the repository at this point in the history
  • Loading branch information
ci010 committed Oct 4, 2023
1 parent dee32f1 commit 19d7d1c
Show file tree
Hide file tree
Showing 53 changed files with 672 additions and 424 deletions.
4 changes: 0 additions & 4 deletions xmcl-keystone-ui/src/assets/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,6 @@ html ::-webkit-scrollbar {
/* background: transparent; */
}

.dark .v-dialog .v-card {
background-color: #424242 !important;
border-color: #424242 !important;
}

:not(.dark) .v-dialog .v-card {
/* background-color: unset;
Expand Down
3 changes: 3 additions & 0 deletions xmcl-keystone-ui/src/components/AppSharedTooltip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const { currentTooltip, x, y, isShown, color, left } = useSharedTooltipData()
const router = useRouter()
router.afterEach(() => {
isShown.value = false
nextTick(() => {
isShown.value = false
})
})
</script>
4 changes: 2 additions & 2 deletions xmcl-keystone-ui/src/components/ErrorView.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<template>
<div
v-if="!!error"
class="my-10 flex flex-col items-center gap-4"
class="mx-5 my-10 flex flex-col items-center gap-4"
>
<v-icon
color="error"
size="100"
>
error
</v-icon>
<div class="text-3xl font-bold">
<div class="max-w-full select-text break-all text-3xl font-bold">
{{ tError(error) }}
</div>
<v-btn
Expand Down
61 changes: 3 additions & 58 deletions xmcl-keystone-ui/src/components/ForgeIcon.vue
Original file line number Diff line number Diff line change
@@ -1,63 +1,8 @@
<template>
<svg
id="Ebene_1"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="0px"
viewBox="10 0 90 66.7"
style="enable-background:new 0 0 316 66.7;"
xml:space="preserve"
<img
:src="'image://builtin/forge'"
width="24"
>
<g>
<!-- <g>
<polygon
class="st0"
points="114.1,55.6 125,55.6 125,38.7 143,38.7 143,28.4 125,28.4 125,21.4 144.1,21.4 144.1,11.1
114.1,11.1 "
/>
<path
class="st0"
d="M185.3,16.3c-2.1-2.1-4.6-3.6-7.5-4.7c-2.7-1-5.8-1.5-9-1.5l-0.4,0c-3.4,0-6.5,0.6-9.3,1.7
c-2.9,1.1-5.4,2.7-7.4,4.8c-2.1,2.1-3.7,4.6-4.9,7.5c-1.2,2.9-1.7,6.1-1.7,9.6c0,3.4,0.6,6.6,1.8,9.4c1.2,2.8,2.8,5.3,4.9,7.3
c2.1,2,4.6,3.6,7.4,4.7c2.8,1.1,6,1.7,9.3,1.7h0h0c3.4,0,6.6-0.6,9.4-1.8c2.9-1.1,5.4-2.8,7.5-4.8c2.1-2,3.7-4.5,4.9-7.4
c1.2-2.8,1.8-6,1.8-9.4c0-3.5-0.6-6.7-1.7-9.6C189,20.9,187.3,18.4,185.3,16.3z M180.6,33.1c0,2-0.3,3.8-0.9,5.4
c-0.6,1.6-1.4,3-2.5,4.2c-1,1.1-2.3,2.1-3.8,2.7c-1.5,0.7-3.2,1-5,1c-1.8,0-3.5-0.3-5-1c-1.5-0.7-2.7-1.6-3.8-2.7
c-1.1-1.2-1.9-2.6-2.5-4.2c-0.6-1.6-0.9-3.5-0.9-5.4c0-1.8,0.3-3.5,0.9-5c0.6-1.5,1.4-2.9,2.5-4c1-1.1,2.3-2,3.8-2.7
c1.5-0.6,3.1-1,5-1c1.8,0,3.5,0.3,5,1c1.5,0.6,2.8,1.5,3.8,2.7c1.1,1.1,1.9,2.5,2.5,4C180.3,29.6,180.6,31.3,180.6,33.1z"
/>
<path
class="st0"
d="M224.2,33.3c1.9-2.3,2.9-5.2,2.9-8.6c0-2.6-0.5-4.8-1.5-6.6c-1-1.8-2.4-3.2-4-4.2c-1.6-1-3.4-1.7-5.5-2.1
c-1.9-0.4-4-0.6-6-0.6h-16v44.5h11V38.3h2.3l9.4,17.3h13.1l-11.2-18.6C220.9,36.2,222.8,35,224.2,33.3z M204.9,21h4.4
c0.8,0,1.7,0.1,2.6,0.2c0.8,0.1,1.5,0.3,2.1,0.6c0.5,0.2,0.9,0.6,1.2,1c0.3,0.4,0.4,1,0.4,1.8c0,0.9-0.2,1.6-0.5,2.1
c-0.3,0.5-0.8,0.8-1.3,1c-0.7,0.3-1.5,0.5-2.3,0.6c-1,0.1-2,0.1-2.9,0.1h-3.8V21z"
/>
<path
class="st0"
d="M242.7,24c1-1.1,2.3-2,3.8-2.7c1.5-0.6,3.1-1,5-1c1.8,0,3.6,0.3,5.3,0.9c1.6,0.6,3,1.4,4.1,2.5l1.3,1.3l8-8.1
l-1.5-1.3c-2.4-2.1-5.1-3.6-8.1-4.4c-2.9-0.8-6-1.2-9.2-1.2c-3.4,0-6.5,0.6-9.3,1.7c-2.9,1.1-5.4,2.7-7.4,4.8
c-2.1,2.1-3.7,4.6-4.9,7.5c-1.2,2.9-1.7,6.1-1.7,9.6c0,3.4,0.6,6.6,1.8,9.4c1.2,2.8,2.8,5.3,4.9,7.3c2.1,2,4.6,3.6,7.4,4.7
c2.8,1.1,6,1.7,9.3,1.7c6.5,0,12.5-1.4,17.8-4.3l1-0.5V28h-19.3v10.3h8.4V45c-0.9,0.4-1.8,0.7-2.9,0.9c-1.5,0.3-3.1,0.5-4.8,0.5
c-1.8,0-3.5-0.3-5-1c-1.5-0.7-2.7-1.6-3.8-2.7c-1.1-1.2-1.9-2.6-2.5-4.2c-0.6-1.6-0.9-3.5-0.9-5.4c0-1.8,0.3-3.5,0.9-5
C240.9,26.5,241.7,25.1,242.7,24z"
/>
<polygon
class="st0"
points="285.6,45.3 285.6,38 304.3,38 304.3,27.7 285.6,27.7 285.6,21.4 305.4,21.4 305.4,11.1 274.6,11.1
274.6,55.6 306.4,55.6 306.4,45.3 "
/>
</g> -->
<path
class="st1"
d="M91.6,16.7l-37.8-1.9l46.2,0v-3.7H47.8l0,7.8v6.2c0,0.1-1.5-9.1-1.9-11.7h-4.1v6.8v6.2
c0,0.1-1.8-10.9-1.9-12.3c-10.4,0-27.9,0-27.9,0c1.9,1.6,12.4,10.6,19.9,14.3c3.7,1.8,8.3,1.9,12.4,2c2.1,0.1,4.2,0.2,5.8,1.8
c2.3,2.2,2.8,5.7,0.8,8.3c-1.9,2.6-7.3,3.2-7.3,3.2L39,49.1v6.4h10.3l0.3-6.3l8.9-6.3c-0.9,0.8-3.1,2.8-6.2,7.7
c-0.7,1.1-1.3,2.3-1.7,3.5c2.2-1.9,6.8-3.2,12.2-3.2c5.3,0,9.9,1.3,12.1,3.2c-0.4-1.2-1-2.4-1.7-3.5c-3.2-4.9-5.3-6.9-6.2-7.7
l8.9,6.3l0.3,6.3h9.6v-6.4l-4.5-5.5c0,0-6.7-0.4-8.4-3.2C67.7,32.6,74.8,20.4,91.6,16.7z"
/>
</g>
</svg>
</template>
<style type="text/css" scoped>
.st0 {
Expand Down
8 changes: 8 additions & 0 deletions xmcl-keystone-ui/src/components/NeoForgedIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<img
:src="'image://builtin/neoForged'"
width="24"
>
</template>
<style type="text/css" scoped>
</style>
6 changes: 3 additions & 3 deletions xmcl-keystone-ui/src/composables/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ export function clearInMemoryCache(key: string) {

const LOCAL_STORAGE_CACHE: Record<string, Ref<any>> = {}

export function useLocalStorageCache<T>(key: string, defaultValue: () => T, toString: (t: T) => string, fromString: (s: string) => T, legacyKey?: string): Ref<T> {
export function useLocalStorageCache<T>(key: string, defaultValue: () => T, toString: (t: T) => string, fromString: (s: string) => T, deep = false): Ref<T> {
if (LOCAL_STORAGE_CACHE[key]) {
const ref = LOCAL_STORAGE_CACHE[key]
watch(ref, (n) => {
localStorage.setItem(key, toString(n))
})
}, { deep })
return ref
}
const result = localStorage.getItem(key)
Expand All @@ -46,7 +46,7 @@ export function useLocalStorageCache<T>(key: string, defaultValue: () => T, toSt
}
watch(v, (n) => {
localStorage.setItem(key, toString(n))
})
}, { deep })

const onStorage = (e: StorageEvent) => {
if (e.key === key) {
Expand Down
2 changes: 1 addition & 1 deletion xmcl-keystone-ui/src/composables/curseforge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export function useCurseforgeProjectFiles(projectId: Ref<number>, gameVersion: R
index: data.index,
gameVersion: gameVersion.value,
pageSize: data.pageSize,
modLoaderType: modLoaderType.value,
modLoaderType: modLoaderType.value === 0 ? undefined : modLoaderType.value,
}))
}, inject(kSWRVConfig))
watch(_data, (f) => {
Expand Down
28 changes: 17 additions & 11 deletions xmcl-keystone-ui/src/composables/curseforgeInstall.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { clientCurseforgeV1 } from '@/util/clients'
import { File, FileIndex } from '@xmcl/curseforge'
import { CurseForgeServiceKey, ProjectType, Resource, ResourceServiceKey, getCurseforgeFileUri } from '@xmcl/runtime-api'
import { CurseForgeServiceKey, InstanceModsServiceKey, ProjectType, Resource, ResourceServiceKey, getCurseforgeFileUri } from '@xmcl/runtime-api'
import { InjectionKey, Ref } from 'vue'
import { useCurseforgeProject } from './curseforge'
import { useDialog } from './dialog'
Expand All @@ -13,8 +13,22 @@ import { useService } from './service'

export const kCurseforgeInstall: InjectionKey<ReturnType<typeof useCurseforgeInstall>> = Symbol('CurseforgeInstall')

export function useCurseforgeInstallModFile(path: Ref<string>) {
const { getResourcesByUris } = useService(ResourceServiceKey)
const { install: installMod } = useService(InstanceModsServiceKey)
const { installFile } = useService(CurseForgeServiceKey)
const installCurseforgeFile = async (v: File, icon?: string) => {
const resources = await getResourcesByUris([getCurseforgeFileUri(v)])
if (resources.length > 0) {
await installMod({ mods: resources, path: path.value })
} else {
await installFile({ file: v, icon, type: 'mc-mods', instancePath: path.value })
}
}
return installCurseforgeFile
}

export function useCurseforgeInstall(modId: Ref<number>, files: Ref<Pick<File, 'modId' | 'id'>[]>, from: Ref<string | undefined>, type: Ref<ProjectType>, currentFileResource: Ref<Resource | undefined>) {
const installList = inject(kInstallList, undefined)
const { install: installResource } = useService(ResourceServiceKey)
const { t } = useI18n()
const { notify } = useNotifier()
Expand Down Expand Up @@ -52,15 +66,7 @@ export function useCurseforgeInstall(modId: Ref<number>, files: Ref<Pick<File, '
})
}
} else {
if (project.value && type.value === 'mc-mods' && installList) {
installList.add(file, {
uri: file.modId.toString(),
name: project.value.name,
icon: project.value.logo.url,
})
} else {
await installFile({ file, type: type.value })
}
await installFile({ file, type: type.value, icon: project.value?.logo.url })
}
}
return {
Expand Down
3 changes: 2 additions & 1 deletion xmcl-keystone-ui/src/composables/ftb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CachedFTBModpackVersionManifest, FTBVersion } from '@xmcl/runtime-api'
import useSWRV from 'swrv'
import { Ref } from 'vue'
import { kSWRVConfig } from './swrvConfig'
import { useLocalStorageCache } from './cache'

interface FeedTheBeastProps {
keyword?: string
Expand Down Expand Up @@ -68,7 +69,7 @@ export function useFeedTheBeastProjectVersion(project: Ref<number>, version: Ref
}

export function useFeedTheBeastVersionsCache() {
const ftb: Ref<CachedFTBModpackVersionManifest[]> = ref([])
const ftb: Ref<CachedFTBModpackVersionManifest[]> = useLocalStorageCache('cachedFTB', () => [], JSON.stringify, JSON.parse, true)

function dispose() {
ftb.value = []
Expand Down
2 changes: 1 addition & 1 deletion xmcl-keystone-ui/src/composables/installList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { InjectionKey, Ref } from 'vue'
import { useService } from './service'
import { clientCurseforgeV1, clientModrinthV2 } from '@/util/clients'
import { resolveCurseforgeDependies } from '@/util/curseforgeDependencies'
import { resolveModrinthDependencies } from '@/util/modrinthDependencies'
import { resolveModrinthDependencies } from '@/util/modrinth'
import { getCurseforgeRelationType } from '@/util/curseforge'

export interface ProjectMetadata {
Expand Down
7 changes: 6 additions & 1 deletion xmcl-keystone-ui/src/composables/instanceMods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function useInstanceMods(instancePath: Ref<string>, instanceRuntime: Ref<
const { watch: watchMods } = useService(InstanceModsServiceKey)
const { isValidating, error, state } = useState(async () => {
if (!instancePath.value) { return undefined }
console.log('watch mods', instancePath.value)
const mods = await watchMods(instancePath.value)
mods.mods = mods.mods.map(m => markRaw(m))
return mods as any
Expand All @@ -28,10 +29,14 @@ export function useInstanceMods(instancePath: Ref<string>, instanceRuntime: Ref<

const enabledModCounts = computed(() => mods.value.filter(v => v.enabled).length)

watch([computed(() => state.value?.mods), instanceRuntime], () => {
watch([computed(() => state.value?.mods)], () => {
if (!state.value?.mods) return
updateItems(state.value?.mods, instanceRuntime.value)
})
watch(instanceRuntime, () => {
if (!state.value?.mods) return
updateItems(state.value?.mods, instanceRuntime.value)
}, { deep: true })

function updateItems(resources: Resource[], runtimeVersions: RuntimeVersions) {
const newItems = resources.map(r => getModFileFromResource(r, runtimeVersions))
Expand Down
83 changes: 5 additions & 78 deletions xmcl-keystone-ui/src/composables/instanceTemplates.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getFTBPath } from '@/util/ftb'
import { getFTBTemplateAndFile } from '@/util/ftb'
import { resolveModpackInstanceConfig } from '@/util/modpackFilesResolver'
import { CachedFTBModpackVersionManifest, InstanceFile, InstanceManifest, JavaRecord, ModpackInstallProfile, ModpackServiceKey, PeerConnection, Resource } from '@xmcl/runtime-api'
import { Ref } from 'vue'
Expand Down Expand Up @@ -84,6 +84,7 @@ export function useInstanceTemplates(javas: Ref<JavaRecord[]>, modpackResources:
fabricLoader: man.runtime.fabricLoader ?? '',
quiltLoader: man.runtime.quiltLoader ?? '',
optifine: man.runtime.optifine ?? '',
neoForged: man.runtime.neoForged ?? '',
yarn: '',
liteloader: '',
},
Expand All @@ -101,86 +102,12 @@ export function useInstanceTemplates(javas: Ref<JavaRecord[]>, modpackResources:
}

function getFtbTemplate(man: CachedFTBModpackVersionManifest): Template {
const getVersion = (str?: string) => {
if (!str) { return undefined }
const match = /(\d+)\.(\d)+\.(\d+)(_\d+)?/.exec(str)
if (match === null) { return undefined }
if (match[1] === '1') {
return {
version: str,
majorVersion: Number.parseInt(match[2]),
patch: Number.parseInt(match[4].substring(1)),
}
}
return {
version: str,
majorVersion: Number.parseInt(match[1]),
patch: Number.parseInt(match[3]),
}
}

const getRuntime = () => {
const javaRuntime = man.targets.find(v => v.name === 'java')
if (javaRuntime) {
const parsedVersion = getVersion(javaRuntime.version)
if (!parsedVersion) {
return
}
const majorMatched = javas.value.filter(v => v.majorVersion === parsedVersion.majorVersion)
let selectedRecord = majorMatched[0]
for (const v of majorMatched.slice(1)) {
const currentPatch = getVersion(v.version)?.patch
const selectedPatch = getVersion(selectedRecord.version)?.patch
if (!currentPatch || !selectedPatch) continue
const diff = Math.abs(currentPatch - parsedVersion.patch)
const selectedDiff = Math.abs(selectedPatch - parsedVersion.patch)
if (diff < selectedDiff) {
selectedRecord = v
}
}
if (selectedRecord) {
return selectedRecord.path
}
}
}
const runtime = {
minecraft: man.targets.find(f => f.name === 'minecraft')?.version || '',
forge: man.targets.find(f => f.name === 'forge')?.version || '',
fabricLoader: '',
quiltLoader: '',
optifine: '',
liteloader: '',
yarn: '',
}
const files = markRaw(man.files.map(f => ({
path: getFTBPath(f),
hashes: {
sha1: f.sha1,
},
curseforge: f.curseforge
? {
projectId: f.curseforge.project,
fileId: f.curseforge.file,
}
: undefined,
downloads: f.url ? [f.url] : undefined,
size: f.size,
})))
const [instanceConfig, files] = getFTBTemplateAndFile(man, javas.value)
return reactive({
filePath: `${man.parent}-${man.id.toString()}`,
name: '',
name: `${man.projectName}-${man.name}`,
description: computed(() => t('instanceTemplate.ftb')),
instance: markRaw({
name: `${man.projectName}-${man.name}`,
author: man.authors[0].name,
java: getRuntime() ?? '',
runtime,
upstream: {
type: 'ftb-modpack',
id: man.id,
},
icon: man.iconUrl,
}),
instance: markRaw(instanceConfig),
loadingFiles: false,
loadFiles: () => Promise.resolve(files),
files,
Expand Down
9 changes: 5 additions & 4 deletions xmcl-keystone-ui/src/composables/instanceVersion.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EMPTY_VERSION, Instance, LocalVersionHeader, RuntimeVersions, VersionServiceKey, getResolvedVersion } from '@xmcl/runtime-api'
import { EMPTY_VERSION, Instance, LocalVersionHeader, RuntimeVersions, VersionServiceKey, getExpectVersion, getResolvedVersion } from '@xmcl/runtime-api'
import useSWRV from 'swrv'
import { Ref, InjectionKey } from 'vue'
import { useService } from './service'
Expand Down Expand Up @@ -37,12 +37,13 @@ export function useInstanceVersion(instance: Ref<Instance>, local: Ref<LocalVers
instance.value.runtime.neoForged,
instance.value.runtime.fabricLoader,
instance.value.runtime.optifine,
instance.value.runtime.quiltLoader) || markRaw(EMPTY_VERSION))
instance.value.runtime.quiltLoader) || { ...EMPTY_VERSION, id: getExpectVersion(instance.value.runtime) })
const folder = computed(() => versionHeader.value?.id || 'unknown')

const { isValidating, mutate, data: resolvedVersion, error } = useSWRV(() => instance.value.path && `/instance/${instance.value.path}/version`, async () => {
if (versionHeader.value === EMPTY_VERSION || !versionHeader.value.id) {
return { requirements: instance.value.runtime }
console.log('update instance version')
if (!versionHeader.value.path) {
return { requirements: { ...instance.value.runtime } }
}
const resolvedVersion = await resolveLocalVersion(versionHeader.value.id)
return resolvedVersion
Expand Down

0 comments on commit 19d7d1c

Please sign in to comment.