import { useDebounceFn } from '@vueuse/core' import { useTokenValidation } from '#layers/composables/useTokenValidation' import { csrGoStoveLogin } from '#layers/utils/stoveUtil' export const useCheckGameStart = () => { const runtimeConfig = useRuntimeConfig() const gameDataStore = useGameDataStore() const modalStore = useModalStore() const { handleTokenValidation } = useTokenValidation() const { tm, locale } = useI18n() const { gameId } = storeToRefs(gameDataStore) const stoveCs = runtimeConfig.public.stoveCs const isProcessing = ref(false) // 연속 클릭 방지 const isShowCheckLauncher = ref(false) // 런처 실행 로딩 표시 const isShowDownloadLauncher = ref(false) // 런처 다운로드 표시 const customerServiceUrl = `${stoveCs}/${gameId.value}` let launcherTimeoutId: ReturnType | null = null // 에러 처리 const errorHandler = (errorCode: number) => { switch (errorCode) { case -100: // Window OS에서만 실행 가능 modalStore.handleOpenAlert({ contentText: tm('Alert_Client_Window'), }) break case 601: // PC 클라이언트 미설치 break case 40101: // 로그인 정보 확인 중 오류가 발생했습니다. 재로그인 후 다시 이용해 주세요. modalStore.handleOpenConfirm({ contentText: tm('Alert_40101'), confirmButtonText: tm('Text_StoveLogin'), modalName: 'modal-login', confirmButtonEvent: () => { csrGoStoveLogin() }, }) break case 40103: // 로그인 정보가 만료되었습니다. 재로그인 후 다시 이용해 주세요. modalStore.handleOpenConfirm({ contentText: tm('Alert_40103'), confirmButtonText: tm('Text_StoveLogin'), modalName: 'modal-login', confirmButtonEvent: () => { csrGoStoveLogin() }, }) break case 602: case 504: case 70051: case 500000: case 701: case 70052: default: // 일시적으로 오류가 발생했습니다. 잠시 후 다시 이용해 주세요. 동일한 현상이 계속 발생할 경우 고객센터로 문의해 주세요. modalStore.handleOpenConfirm({ contentText: tm('Alert_Error'), confirmButtonText: tm('Text_Customer'), confirmButtonEvent: () => { window.open(customerServiceUrl, '_blank') }, }) break } } // 런처 실행 로딩 시작 UI 처리 const startLoadingForLauncher = () => { if (import.meta.client) { // 이전 타이머 정리 if (launcherTimeoutId) { clearTimeout(launcherTimeoutId) launcherTimeoutId = null } isShowCheckLauncher.value = true isShowDownloadLauncher.value = false launcherTimeoutId = setTimeout(() => { if (isShowCheckLauncher.value) { isShowDownloadLauncher.value = true } launcherTimeoutId = null }, 5000) } } // 런처 실행 로딩 종료 UI 처리 const stopLoadingForLauncher = () => { if (import.meta.client) { // 타이머 정리 if (launcherTimeoutId) { clearTimeout(launcherTimeoutId) launcherTimeoutId = null } isShowCheckLauncher.value = false isShowDownloadLauncher.value = false } } // OS 체크 함수 추가 const checkWindowsOS = (): boolean => { // 서버 사이드 렌더링 중에는 navigator 객체가 없으므로, 항상 false를 반환하여 통과시킵니다. // 실제 OS 체크는 클라이언트 사이드에서만 의미가 있습니다. if (typeof navigator === 'undefined') { return false } return /windows/i.test(navigator.userAgent) } // 런처 호출 const runLauncher = async () => { if (!import.meta.client) return const accessTokenSub = csrGetAccessToken() const stoveGameId = gameId.value || '' const nationCookie = useCookie('NNTO').value const localeCode = locale.value.toUpperCase() || 'KO' window.stoveJsService = window.stoveJsService || {} // 토큰 유효성 체크 const validateTokenResult = await handleTokenValidation( accessTokenSub || '' ) // 토큰 유효성 체크 실패 시 if (validateTokenResult === false) { isProcessing.value = false return } // 런처 실행 로딩 시작 startLoadingForLauncher() window.stoveJsService.launcher .run({ gameId: stoveGameId, nation: nationCookie, lang: localeCode, isSkipMaintenance: true, }) .then(() => { // 런처 실행 성공 시 처리 stopLoadingForLauncher() }) .catch((error: any) => { // 런처 실행 실패시 처리 if (error.code !== 601) { stopLoadingForLauncher() } errorHandler(error.code) }) .finally(() => { isProcessing.value = false }) } // 디바운스 설정 const debounceHandler = useDebounceFn(runLauncher, 500) // 런처 상태 검사 const validateLauncher = () => { if (isProcessing.value) return const isWindowsOS = checkWindowsOS() if (!isWindowsOS) { errorHandler(-100) return } isProcessing.value = true debounceHandler() } // 런처 다운로드 함수 const downloadLauncher = () => { const stoveClientDownloadUrl = runtimeConfig.public.stoveClientDownloadUrl location.href = stoveClientDownloadUrl isProcessing.value = false } return { isProcessing, // 연속 클릭 방지 isShowCheckLauncher, // 런처 실행 로딩 표시 isShowDownloadLauncher, // 런처 다운로드 표시 validateLauncher, // 런처 검사 함수 downloadLauncher, // 런처 실행 함수 } }