一个全随机的刷装备小游戏
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
6.8 KiB

2 months ago
<template>
<Tooltip :infos="[at('menu.0')]" width="12rem">
2 months ago
<img class="menu-img" :src="menu_icons.exportGame" @click="showMenu">
</Tooltip>
<Dialog :title="at('menu.0')" v-model="showArchive" top="4rem" left='8%' @close="state.curMenu = null">
2 months ago
<div class="archive">
<span class="tip">* {{ at('menu.1') }}</span>
2 months ago
<textarea class="textarea" v-model="archive"></textarea>
</div>
<div class="footer">
<button class="button" @click="copyArchive(archive)">{{ at('copy.0') }}</button>
<button class="button" @click="pasteArchive">{{ at('paste.0') }}</button>
<button class="button" @click="importArchive">{{ at('import.0') }}</button>
2 months ago
</div>
<div class="footer">
<button class="button" @click="uploadArchive">{{ at('upload') }}</button>
<button class="button" @click="downArchive">{{ at('down') }}</button>
</div>
2 months ago
</Dialog>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { computed, onMounted, ref, onBeforeUnmount } from "vue";
import { useI18n } from "vue3-i18n";
import { Tooltip, Dialog } from "@/components"
import { menu_icons } from "@/config";
import { getArchive, AES_CBC_ENCRYPT, AES_CBC_DECRYPT, checkImportArchive, saveArchive, replace, archive_version, MD5, checkArchive } from "@/tool";
import * as API from "@/api";
import { createt } from "@/config/i18n";
2 months ago
// const { t } = useI18n();
const at = createt('archive.');
2 months ago
const { state, commit, dispatch } = useStore();
const showArchive = computed(() => {
return state.curMenu == 'archive';
});
const archive = ref('');
const key = 'KUf4hM5rThssysJhcRFCfxLR8Imihjl0eMsyhh1M7Wk';
let timeOut = 0;
const strengthenLv = computed(() => {
const player = state.playerAttribute;
const equips = [player.weapon, player.armor, player.neck, player.ring, player.jewelry, player.pants, player.shoes, player.bracers];
let lv = 0;
equips.forEach(equip => {
equip && (lv += equip.strengthenLv)
})
return lv;
});
2 months ago
const showMenu = () => {
if (showArchive.value) {
state.curMenu = null;
} else {
state.curMenu = 'archive';
getArchive().then((rsp: any) => {
archive.value = AES_CBC_ENCRYPT(JSON.stringify(rsp), key);
});
2 months ago
}
}
const copyArchive = (archive) => {
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(archive).then(() => {
commit('set_sys_info', { msg: at('copy.1'), type: 'win' })
showMenu();
}).catch(() => {
commit('set_sys_info', { msg: at('copy.2'), type: 'waring' })
});
} else {
const textField = document.createElement("textarea");
textField.innerText = archive;
document.body.appendChild(textField);
textField.select();
document.execCommand("copy");
textField.remove();
commit('set_sys_info', { msg: at('copy.1'), type: 'win' })
showMenu();
}
2 months ago
}
const uploadArchive = () => {
API.getUser().then(user => {
if (user) {
const palyer = state.playerAttribute;
const data = { version: archive_version, lv: palyer.lv, coins: palyer.coins, strengthenLv: strengthenLv.value, layer: palyer.layer, archive: archive.value }
API.uploadArchive(data).then(rsp => rsp && showMenu());
} else {
state.showLogin = true;
}
});
}
const downArchive = () => {
API.getUser().then(user => {
if (user) {
API.downArchive({ version: archive_version }).then((rsp: any) => {
if (rsp) {
archive.value = rsp;
importArchive();
}
});
} else {
state.showLogin = true;
}
});
}
2 months ago
const pasteArchive = () => {
const name: any = 'clipboard-read';
navigator.permissions.query({ name: name }).then(result => {
if (result.state === 'granted') {
navigator.clipboard.readText().then(text => {
archive.value = text;
commit('set_sys_info', { msg: at('paste.1'), type: 'win' })
});
} else {
commit('set_sys_info', { msg: at('paste.2'), type: 'waring' })
}
2 months ago
});
}
const importArchive = async () => {
2 months ago
try {
const data = JSON.parse(AES_CBC_DECRYPT(archive.value, key));
2 months ago
if (!data || data == 'undfind') {
commit('set_sys_info', { msg: at('empty'), type: 'warning' });
2 months ago
}
if (data.version != archive_version) {
commit('set_sys_info', { msg: at('import.3'), type: 'warning' });
return;
}
const flag = data.flag || state.archiveFlag;
console.log(flag);
checkArchive(flag).then(async rsp => {
if (!rsp) {
commit('set_sys_info', { msg: at('check.0'), type: 'warning' });
return;
} else {
await dispatch('loadGame', data);
if (state.experiential) {
commit('set_sys_info', { msg: replace(at('experiential.0'), [data.experientialTime]), type: 'win' });
const time = data.experientialTime || 10;
clearTimeout(timeOut);
timeOut = setTimeout(() => {
commit('set_sys_info', { msg: replace(at('experiential.2'), [data.experientialTime]), type: 'warning' });
dispatch('loadGame');
}, time * 60 * 100);
} else {
saveArchive(state);
}
showMenu();
}
})
// await checkImportArchive(data);
2 months ago
} catch (error) {
console.log(error);
commit('set_sys_info', { msg: at('error'), type: 'warning' });
2 months ago
}
}
const keydown = (e) => {
if (e.keyCode == 65 && !e.ctrlKey) {
showMenu();
}
}
onMounted(() => {
document.addEventListener('keydown', keydown);
2 months ago
});
onBeforeUnmount(() => {
document.removeEventListener('keydown', keydown);
clearTimeout(timeOut);
2 months ago
})
onMounted(() => { });
</script>
<style lang="scss" scoped>
.archive {
padding: 0.7rem;
display: flex;
flex-direction: column;
.tip {
color: white;
font-size: 0.8rem;
margin: 0.25rem 0;
}
}
.textarea {
width: 25rem;
2 months ago
height: 15rem;
user-select: text;
background: rgba($color: #ffffff, $alpha: 0.8);
}
.footer {
border-top: 1px solid #ccc;
padding: 0.4rem;
display: flex;
align-items: center;
justify-content: center;
}
2 months ago
@media only screen and (max-width: 768px) {
.archive {
padding: 0.3rem;
.tip {
color: white;
font-size: 0.8rem;
margin: 0.25rem 0;
}
}
.textarea {
width: 22rem;
height: 20rem;
}
}
2 months ago
</style>