Skip to content

Commit

Permalink
fix: Fix glitchs
Browse files Browse the repository at this point in the history
  • Loading branch information
ci010 committed Dec 31, 2024
1 parent 1730705 commit 8143a72
Show file tree
Hide file tree
Showing 15 changed files with 77 additions and 57 deletions.
4 changes: 2 additions & 2 deletions xmcl-electron-app/main/ElectronLauncherApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ export default class ElectronLauncherApp extends LauncherApp {
app.commandLine?.appendSwitch('ozone-platform-hint', 'auto')
}

fetch: typeof fetch = (...args: any[]) => {
fetch: typeof fetch = async (...args: any[]) => {
try {
return net.fetch(args[0], args[1] ? { ...args[1], bypassCustomProtocolHandlers: true } : undefined) as any
return await net.fetch(args[0], args[1] ? { ...args[1], bypassCustomProtocolHandlers: true } : undefined) as any
} catch (e) {
if (e instanceof Error) {
let code: NetworkErrorCode | undefined
Expand Down
10 changes: 5 additions & 5 deletions xmcl-electron-app/preload/service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-dupe-class-members */

import { AllStates, ServiceChannels, ServiceKey, MutableState, StateMetadata } from '@xmcl/runtime-api'
import { AllStates, ServiceChannels, ServiceKey, SharedState, StateMetadata } from '@xmcl/runtime-api'
import { contextBridge, ipcRenderer } from 'electron'
import EventEmitter from 'events'

Expand All @@ -24,7 +24,7 @@ const typeToStatePrototype: Record<string, StateMetadata> = AllStates.reduce((ob
const kEmitter = Symbol('Emitter')
const kMethods = Symbol('Methods')

function createMutableState<T extends object>(val: T, id: string, methods: StateMetadata['methods']): MutableState<T> {
function createSharedState<T extends object>(val: T, id: string, methods: StateMetadata['methods']): SharedState<T> {
const emitter = new EventEmitter()
Object.defineProperty(val, kEmitter, { value: emitter })
Object.defineProperty(val, kMethods, { value: methods })
Expand Down Expand Up @@ -55,7 +55,7 @@ if (process.env.NODE_ENV === 'development') {
console.log('serivce.ts preload')
}

async function receive(_result: any, states: Record<string, WeakRef<MutableState<any>>>, pendingCommits: Record<string, { type: string; payload: any }[]>, gc: FinalizationRegistry<string>) {
async function receive(_result: any, states: Record<string, WeakRef<SharedState<any>>>, pendingCommits: Record<string, { type: string; payload: any }[]>, gc: FinalizationRegistry<string>) {
if (typeof _result !== 'object') {
return
}
Expand Down Expand Up @@ -86,7 +86,7 @@ async function receive(_result: any, states: Record<string, WeakRef<MutableState
}

delete result.__state__
const state = createMutableState(result, id, prototype.methods)
const state = createSharedState(result, id, prototype.methods)

for (const [method, handler] of prototype.methods) {
// explictly bind to the state object under electron context isolation
Expand Down Expand Up @@ -127,7 +127,7 @@ function createServiceChannels(): ServiceChannels {
console.log(`deref ${id}`)
})
const servicesEmitters = new Map<ServiceKey<any>, WeakRef<EventEmitter>>()
const states: Record<string, WeakRef<MutableState<object>>> = {}
const states: Record<string, WeakRef<SharedState<object>>> = {}
const pendingCommits: Record<string, { type: string; payload: any }[]> = {}

ipcRenderer.on('state-validating', (_, { id, semaphore }) => {
Expand Down
15 changes: 13 additions & 2 deletions xmcl-keystone-ui/src/components/HomeCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@
</v-icon>
{{ title }}
</v-card-title>
<v-card-text class="flex-grow relative">
<v-card-text class="flex-grow relative pb-0">
<template v-if="refreshing && icons.length === 0">
<v-skeleton-loader type="paragraph" />
</template>
<template v-else-if="slots.default">
<slot />
</template>
<template v-else>
<span v-if="!error">
<span
v-if="!error"
class="text-content"
>
{{ text }}
</span>
<span
Expand Down Expand Up @@ -104,4 +107,12 @@ const highlighted = computed(() => globalDragover.value && dragover.value > 0)
.highlighted {
transform: scale(1.05);
}
.text-content {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
3 changes: 2 additions & 1 deletion xmcl-keystone-ui/src/components/InstanceManifestFileItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

<div class="flex-grow flex flex-col justify-center">
<div :style="{ fontSize: '16px', lineHeight: '100%', ...item.style }">
{{ item.name }}
{{ basename(item.name, '/') }}
</div>
<div
v-if="description"
Expand Down Expand Up @@ -81,6 +81,7 @@

<script lang="ts" setup>
import { InstanceFileNode } from '@/composables/instanceFileNodeData'
import { basename } from '@/util/basename'
import { getExpectedSize } from '@/util/size'
import { TreeItem } from '@/util/tree'
Expand Down
4 changes: 2 additions & 2 deletions xmcl-keystone-ui/src/composables/instanceLaunch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export function useInstanceLaunch(
error.value = undefined
const options = await generateLaunchOptions(instancePath, operationId, side, overrides)

if (!options.skipAssetsCheck) {
if (!options.skipAssetsCheck && side === 'client') {
console.log('refreshing user')
try {
await track(instancePath, refreshUser(userProfile.value.id, { validate: true }), 'refreshing-user', operationId)
Expand All @@ -237,7 +237,7 @@ export function useInstanceLaunch(
}
}

if (shouldEnableVoiceChat()) {
if (shouldEnableVoiceChat() && side === 'client') {
try {
await track(instancePath, windowController.queryAudioPermission(), 'checking-permission', operationId)
} catch (e) {
Expand Down
7 changes: 6 additions & 1 deletion xmcl-keystone-ui/src/composables/useAggregateProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ export function useProjectsFilterSort<T extends ProjectEntry>(
})
: theMode === 'local'
? items.value.filter(p => p.installed.length > 0)
: items.value
: items.value.filter(p => {
if (p.installed.length > 0) return true
if (!get(isCurseforgeActive) && p.curseforge && !p.modrinth) return false
if (!get(isModrinthActive) && p.modrinth && !p.curseforge) return false
return true
})

if (!keyword.value) return filtered

Expand Down
9 changes: 9 additions & 0 deletions xmcl-keystone-ui/src/views/AppExportDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,11 @@ function reset() {
data.version = inc(modpackVersion.value || '0.0.0', 'patch') ?? '0.0.1'
}
const exclusions = [
'usernamecache.json',
'usercache.json',
]
// loading
const { refresh, refreshing } = useRefreshable(async () => {
const manifest = await getInstanceManifest({ path: instance.value.path })
Expand All @@ -406,6 +411,10 @@ const { refresh, refreshing } = useRefreshable(async () => {
.filter(file => !file.path.startsWith('crash-reports'))
.filter(file => !file.path.startsWith('saves'))
.filter(file => !file.path.startsWith('resourcepacks'))
.filter(file => !file.path.startsWith('screenshots'))
.filter(file => !file.path.startsWith('data'))
.filter(file => !file.path.startsWith('server'))
.filter(file => !exclusions.includes(file.path))
.map(file => file.path)
nextTick().then(() => { data.selected = selected })
data.files = files
Expand Down
50 changes: 19 additions & 31 deletions xmcl-keystone-ui/src/views/AppLaunchBlockedDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@
</template>

<script lang=ts setup>
import { getExpectVersion, LaunchException, LaunchExceptions, LaunchServiceKey } from '@xmcl/runtime-api'
import { useDialog } from '../composables/dialog'
import { useService } from '@/composables'
import { useExceptionHandler } from '@/composables/exception'
import { isException, LaunchException, LaunchExceptions, LaunchServiceKey } from '@xmcl/runtime-api'
import FeedbackCard from '../components/FeedbackCard.vue'
import { useDialog } from '../composables/dialog'
const { on } = useService(LaunchServiceKey)
const { isShown, hide } = useDialog('launch-blocked')
Expand All @@ -70,22 +70,7 @@ const extraText = ref('')
const { t } = useI18n()
function onException(e: LaunchExceptions) {
if (e.type === 'launchGeneralException') {
title.value = t('launchBlocked.launchGeneralException.title')
description.value = t('launchBlocked.launchGeneralException.description')
unexpected.value = true
if (e.error) {
if (typeof (e.error as any).stack === 'string') {
extraText.value += (e.error as any).stack
} else if (typeof (e.error as any).message === 'string') {
extraText.value = (e.error as any).message
} else if (typeof (e.error as any).toString === 'function') {
extraText.value = (e.error as any).toString()
} else {
extraText.value = e as any
}
}
} else if (e.type === 'launchInvalidJavaPath') {
if (e.type === 'launchInvalidJavaPath') {
title.value = t('launchBlocked.launchInvalidJavaPath.title')
description.value = t('launchBlocked.launchInvalidJavaPath.description', { javaPath: e.javaPath })
unexpected.value = true
Expand All @@ -110,18 +95,6 @@ function onException(e: LaunchExceptions) {
description.value = t('launchBlocked.launchBadVersion.description', { version: e.version })
unexpected.value = true
extraText.value = ''
} else if (e.type === 'launchUserStatusRefreshFailed') {
title.value = t('launchBlocked.launchUserStatusRefreshFailed.title')
description.value = t('launchBlocked.launchUserStatusRefreshFailed.description') + '<br>'
if (e.userException.type === 'userAcquireMicrosoftTokenFailed') {
description.value += t('launchBlocked.userAcquireMicrosoftTokenFailed')
} else if (e.userException.type === 'userCheckGameOwnershipFailed') {
description.value += t('launchBlocked.userCheckGameOwnershipFailed')
} else if (e.userException.type === 'userExchangeXboxTokenFailed') {
description.value += t('launchBlocked.userExchangeXboxTokenFailed')
} else if (e.userException.type === 'userLoginMinecraftByXboxFailed') {
description.value += t('launchBlocked.userLoginMinecraftByXboxFailed')
}
} else if (e.type === 'launchSpawnProcessFailed') {
title.value = t('launchBlocked.launchSpawnProcessFailed.title')
description.value = t('launchBlocked.launchSpawnProcessFailed.description')
Expand All @@ -130,7 +103,22 @@ function onException(e: LaunchExceptions) {
}
on('error', (e) => {
onException(e.exception)
if (isException(LaunchException, e)) {
onException(e.exception)
} else {
title.value = t('launchBlocked.launchGeneralException.title')
description.value = t('launchBlocked.launchGeneralException.description')
unexpected.value = true
if (typeof e.stack === 'string') {
extraText.value += e.stack
} else if (typeof e.message === 'string') {
extraText.value = e.message
} else if (typeof e.toString === 'function') {
extraText.value = e.toString()
} else {
extraText.value = ''
}
}
})
useExceptionHandler(LaunchException, (e) => {
Expand Down
11 changes: 7 additions & 4 deletions xmcl-keystone-ui/src/views/AppLaunchServerDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ const { isShown } = useDialog('launch-server', () => {
if (mods.length > 0) {
selectedMods.value = all.filter(m => mods.some(a => a.ino === m.ino))
} else {
selectedMods.value = all
selectedMods.value = getFitsMods()
}
}).finally(() => {
loadingSelectedMods.value = false
Expand Down Expand Up @@ -368,8 +368,8 @@ const selectedMods = shallowRef<ModFile[]>([])
const { installDependencies, installMinecraftJar } = useService(InstallServiceKey)
const { installToServerInstance, getServerInstanceMods } = useService(InstanceModsServiceKey)
function selectFit() {
const filtered = enabled.value.filter(v => {
function getFitsMods() {
return enabled.value.filter(v => {
const fabric = v.fabric
if (fabric) {
let env: 'client' | 'server' | '*' | undefined
Expand All @@ -384,7 +384,10 @@ function selectFit() {
}
return true
})
selectedMods.value = filtered
}
function selectFit() {
selectedMods.value = getFitsMods()
}
function selectAll() {
Expand Down
6 changes: 4 additions & 2 deletions xmcl-keystone-ui/src/views/ModItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ const props = defineProps<{
const emit = defineEmits(['click', 'checked', 'install'])
const { compatibility: compatibilities } = injection(kInstanceModsContext)
const compatibility = computed(() => props.item.installed[0] ? compatibilities.value[props.item.installed[0].modId] : [])
const compatibility = computed(() => props.item.installed[0] ? compatibilities.value[props.item.installed[0].modId] ?? [] : [])
const { uninstall, disable, enable } = useService(InstanceModsServiceKey)
const { path } = injection(kInstance)
const _getContextMenuItems = useModItemContextMenuItems(computed(() => props.item), () => {
if (props.item.installed) {
uninstall({ path: path.value, mods: props.item.installed.map(i => i.path) })
}
}, () => { }, () => {
if (props.item.installed.length > 0) {
if (props.item.installed && props.item.installed.length > 0) {
if (props.item.installed[0].enabled) {
disable({ path: path.value, mods: props.item.installed.map(i => i.path) })
} else {
Expand All @@ -75,4 +75,6 @@ const getContextMenuItems = () => {
if (items && items.length > 0) return items
return _getContextMenuItems()
}
const hasLabel = computed(() => !props.dense && props.item.installed && (props.item.installed?.[0]?.tags.length + compatibility.value.length) > 0)
</script>
2 changes: 1 addition & 1 deletion xmcl-runtime-api/src/services/LaunchService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface LaunchServiceEventMap {
'minecraft-stderr': { pid: number; stdout: string }
'launch-performance-pre': { id: string; name: string }
'launch-performance': { id: string; name: string; duration: number }
'error': LaunchException
'error': LaunchException | Error
}

export interface LaunchOptions {
Expand Down
6 changes: 3 additions & 3 deletions xmcl-runtime/instance/InstanceService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export class InstanceService extends StatefulService<InstanceState> implements I
await ensureDir(join(newPath, 'mods'))
// hard link all source to new path
const files = await readdir(modDirSrc)
await Promise.all(files.map(f => linkWithTimeoutOrCopy(join(modDirSrc, f), join(newPath, 'mods', f))))
await Promise.allSettled(files.map(f => linkWithTimeoutOrCopy(join(modDirSrc, f), join(newPath, 'mods', f))))
}
if (hasResourcepacks) {
const resourcepacksDirSrc = join(path, 'resourcepacks')
Expand All @@ -304,7 +304,7 @@ export class InstanceService extends StatefulService<InstanceState> implements I
// hard link all files
await ensureDir(join(newPath, 'resourcepacks'))
const files = await readdir(resourcepacksDirSrc)
await Promise.all(files.map(f => linkWithTimeoutOrCopy(join(resourcepacksDirSrc, f), join(newPath, 'resourcepacks', f))))
await Promise.allSettled(files.map(f => linkWithTimeoutOrCopy(join(resourcepacksDirSrc, f), join(newPath, 'resourcepacks', f))))
}
}
if (hasShaderpacks) {
Expand All @@ -314,7 +314,7 @@ export class InstanceService extends StatefulService<InstanceState> implements I
// hard link all files
await ensureDir(join(newPath, 'shaderpacks'))
const files = await readdir(shaderpacksDirSrc)
await Promise.all(files.map(f => linkWithTimeoutOrCopy(join(shaderpacksDirSrc, f), join(newPath, 'shaderpacks', f))))
await Promise.allSettled(files.map(f => linkWithTimeoutOrCopy(join(shaderpacksDirSrc, f), join(newPath, 'shaderpacks', f))))
}
}

Expand Down
4 changes: 2 additions & 2 deletions xmcl-runtime/service/pluginServicesHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ export const pluginServicesHandler = (services: ServiceConstructor[]): LauncherA
return { result: r }
} catch (e) {
app.emit('service-call-end', serviceName, serviceMethod, Date.now() - start, false)
logger.warn(`Error during service call ${serviceName}.${serviceMethod}:`)
const exception = getNormalizeException(e)
const exception = await getNormalizeException(e)

if (!exception) {
// only log the error if it is not a known exception
Expand All @@ -77,6 +76,7 @@ export const pluginServicesHandler = (services: ServiceConstructor[]): LauncherA
: new AnyError('ServiceUnknownError', typeof e === 'string' ? e : JSON.stringify(e), undefined),
{ payload, serviceMethod },
)
logger.warn(`Error during service call ${serviceName}.${serviceMethod}:`)
logger.error(err, serviceName)
}

Expand Down
1 change: 1 addition & 0 deletions xmcl-runtime/settings/pluginSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const pluginSettings: LauncherAppPlugin = async (app) => {
globalDisableElyByAuthlib: state.globalDisableElyByAuthlib,
enableDedicatedGPUOptimization: state.enableDedicatedGPUOptimization,
replaceNatives: state.replaceNatives,
globalEnv: state.globalEnv,
}), 1000)

app.registryDisposer(async () => {
Expand Down
2 changes: 1 addition & 1 deletion xmcl-runtime/telemetry/pluginTelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const pluginTelemetry: LauncherAppPlugin = async (app) => {

appInsight.setup(DEFAULT_APP_INSIGHT_KEY)
.setDistributedTracingMode(appInsight.DistributedTracingModes.AI_AND_W3C)
.setAutoCollectExceptions(true)
.setAutoCollectExceptions(false)
.setAutoCollectPerformance(false)
.setAutoCollectConsole(false)
.setAutoCollectHeartbeat(false)
Expand Down

0 comments on commit 8143a72

Please sign in to comment.