Skip to content

Commit

Permalink
fix: Should fail to install instance in some corner case
Browse files Browse the repository at this point in the history
  • Loading branch information
doabackflip authored and ci010 committed Jan 29, 2024
1 parent c320fa2 commit d2690d5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 21 deletions.
46 changes: 27 additions & 19 deletions xmcl-keystone-ui/src/views/HomeInstanceUpdateDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,21 @@
</template>

<script lang="ts" setup>
import ErrorView from '@/components/ErrorView.vue'
import InstanceManifestFileTree from '@/components/InstanceManifestFileTree.vue'
import { useRefreshable, useService, useServiceBusy } from '@/composables'
import { kInstances } from '@/composables/instances'
import { useRefreshable, useService } from '@/composables'
import { kInstance } from '@/composables/instance'
import { InstanceFileNode, provideFileNodes } from '@/composables/instanceFileNodeData'
import { InstanceInstallDialog } from '@/composables/instanceUpdate'
import { kInstances } from '@/composables/instances'
import { kJavaContext } from '@/composables/java'
import { useVuetifyColor } from '@/composables/vuetify'
import { basename } from '@/util/basename'
import { getFTBTemplateAndFile } from '@/util/ftb'
import { injection } from '@/util/inject'
import { getUpstreamFromResource } from '@/util/upstream'
import { EditInstanceOptions, InstanceFileOperation, InstanceFileUpdate, InstanceInstallServiceKey, InstanceServiceKey, InstanceUpdateServiceKey, Resource } from '@xmcl/runtime-api'
import { EditInstanceOptions, InstanceData, InstanceFileOperation, InstanceFileUpdate, InstanceInstallServiceKey, InstanceUpdateServiceKey, Resource } from '@xmcl/runtime-api'
import { useDialog } from '../composables/dialog'
import { kInstance } from '@/composables/instance'
import ErrorView from '@/components/ErrorView.vue'
import { getFTBTemplateAndFile } from '@/util/ftb'
import { kJavaContext } from '@/composables/java'
const selected = ref([] as string[])
Expand All @@ -150,10 +150,10 @@ const { isShown, dialog } = useDialog(InstanceInstallDialog, () => {
}, () => {
upgrade.value = undefined
})
const oldResource = computed(() => dialog.value.parameter.type !== 'ftb' ? dialog.value.parameter?.currentResource as Resource : undefined)
const newResource = computed(() => dialog.value.parameter.type !== 'ftb' ? dialog.value.parameter?.resource : undefined)
const oldManifest = computed(() => dialog.value.parameter.type === 'ftb' ? dialog.value.parameter?.oldManifest : undefined)
const newManifest = computed(() => dialog.value.parameter.type === 'ftb' ? dialog.value.parameter?.newManifest : undefined)
const oldResource = computed(() => dialog.value.parameter?.type !== 'ftb' ? dialog.value.parameter?.currentResource as Resource : undefined)
const newResource = computed(() => dialog.value.parameter?.type !== 'ftb' ? dialog.value.parameter?.resource : undefined)
const oldManifest = computed(() => dialog.value.parameter?.type === 'ftb' ? dialog.value.parameter?.oldManifest : undefined)
const newManifest = computed(() => dialog.value.parameter?.type === 'ftb' ? dialog.value.parameter?.newManifest : undefined)
const { getInstanceUpdateProfile, getInstanceUpdateProfileRaw } = useService(InstanceUpdateServiceKey)
const { installInstanceFiles } = useService(InstanceInstallServiceKey)
Expand All @@ -163,6 +163,7 @@ const { t } = useI18n()
const upgrade = ref(undefined as undefined | {
instance: EditInstanceOptions
files: InstanceFileUpdate[]
upstream: InstanceData['upstream']
})
const tOperations = computed(() => ({
Expand Down Expand Up @@ -235,23 +236,30 @@ const { refresh, refreshing, error } = useRefreshable(async () => {
oldVersionFiles,
newVersionFiles,
})),
upstream: {
type: 'ftb-modpack',
id: newManifest.value.parent,
versionId: newManifest.value.id,
},
}
return
}
const path = newResource.value?.path
if (path) {
upgrade.value = await getInstanceUpdateProfile({
instancePath: instancePath.value,
oldModpack: oldResource.value && 'path' in oldResource.value ? oldResource.value.path : undefined,
newModpack: newResource.value.path,
})
upgrade.value = {
...await getInstanceUpdateProfile({
instancePath: instancePath.value,
oldModpack: oldResource.value && 'path' in oldResource.value ? oldResource.value.path : undefined,
newModpack: newResource.value.path,
}),
upstream: getUpstreamFromResource(newResource.value),
}
}
})
const confirm = async () => {
if (upgrade.value) {
const { instance, files } = upgrade.value
const upstream = newResource.value
const { instance, files, upstream } = upgrade.value
isShown.value = false
await installInstanceFiles({
path: instancePath.value,
Expand All @@ -267,7 +275,7 @@ const confirm = async () => {
neoForged: instance.runtime?.neoForged,
},
modpackVersion: instance.modpackVersion,
upstream: getUpstreamFromResource(upstream!),
upstream,
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion xmcl-runtime/instanceIO/InstanceFileOperationHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class InstanceFileOperationHandler {
}

if (file.operation === 'backup-remove') {
await rename(destination, destination + '.backup')
await rename(destination, destination + '.backup').catch(() => {})
return
}

Expand Down
17 changes: 17 additions & 0 deletions xmcl-runtime/instanceIO/InstanceManifestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { isNonnull } from '../util/object'
import { decoareteInstanceFileFromResourceCache, discover } from './InstanceFileDiscover'
import { ResolveInstanceFileTask } from './ResolveInstanceFileTask'
import { AnyError } from '~/util/error'
import { join } from 'path'

@ExposeServiceKey(InstanceManifestServiceKey)
export class InstanceManifestService extends AbstractService implements IInstanceManifestService {
Expand Down Expand Up @@ -54,6 +55,22 @@ export class InstanceManifestService extends AbstractService implements IInstanc
})),
)

if (options.hashes) {
const hashes = options.hashes
await Promise.all(_files.filter(([f]) => {
for (const h of hashes) {
if (!f.hashes[h]) {
return true
}
}
return false
}).map(([f]) => Promise.all(hashes.map(async (a) => {
if (!f.hashes[a]) {
f.hashes[a] = await worker.checksum(join(instancePath, f.path), a)
}
}))))
}

files = _files.map(([file]) => file)

await this.yield(resolveTask).catch(() => undefined)
Expand Down
2 changes: 1 addition & 1 deletion xmcl-runtime/instanceIO/InstanceUpdateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class InstanceUpdateService extends AbstractService implements IInstanceU
const a = toAdd[f.path]
if (a.hashes.sha1 !== f.hashes.sha1) {
// backup this file
result.push({ currentFile: f, file: f, operation: 'backup-add' })
result.push({ currentFile: f, file: a, operation: 'backup-add' })
} else {
result.push({ file: f, operation: 'keep' })
}
Expand Down

0 comments on commit d2690d5

Please sign in to comment.