Browse Source

加强存档校验,系统设置新增游戏加速

2.0
许孟阳 3 weeks ago
parent
commit
1c1f3df89b
  1. 31
      src/config/i18n/zh/index.ts
  2. 1
      src/config/i18n/zh/setting.ts
  3. 6
      src/store/action.ts
  4. 3
      src/store/mutation.ts
  5. 7
      src/store/state.ts
  6. 58
      src/tool/archive.ts
  7. 77
      src/views/archive.vue
  8. 1
      src/views/backpack/equip-menu/fusion/equip.vue
  9. 2
      src/views/backpack/equip-menu/fusion/fusion.vue
  10. 3
      src/views/backpack/equip-menu/reforge.vue
  11. 5
      src/views/backpack/equip-menu/strengthen.vue
  12. 7
      src/views/save-game.vue
  13. 13
      src/views/setting.vue
  14. 7
      src/views/version/update-log.vue

31
src/config/i18n/zh/index.ts

@ -92,8 +92,9 @@ export default class Zh { @@ -92,8 +92,9 @@ export default class Zh {
desc: [
'融合说明',
'消耗同名太古装备可进行装备融合',
'未融合的太古作为材料可以添加或重置一星融合属性',
'一星或二星太古做材料可以给同星且融合属性类型相同的太古升星',
'一星太古可消耗任意材料重置融合属性类型',
'一星以上太古可消耗同星切融合属性类型相同的材料升星,最多升为三星',
'融合属性品质为一星:神话,二星:远古,三星:太古',
],
confirm: ['融合后作为材料的装备将会消失,确认要融合吗?', '确定', '算了'],
empty: '无融合属性',
@ -174,17 +175,21 @@ export default class Zh { @@ -174,17 +175,21 @@ export default class Zh {
addPoints = '左键加+1,右键+10';
subtractPoints = '左键-1,右键-10';
saveGame = ['保存游戏(Ctrl+S)', '每5分钟会自动保存游戏一次', '游戏进度已经保存了。'];
archive = ['存档管理(A)', '导入存档前请将存档内容粘贴到输入框内'];
copyArchive = ['复制存档', '已经复制存档了,建议保存到备忘录', '复制存档失败', '复制旧存档'];
pasteArchive = ['粘贴存档', '粘贴存档内容到输入框成功', '粘贴失败'];
cleanArchive = ['删除存档'];
uploadArchive = '上传存档';
downArchive = '下载存档';
importArchive = ['导入', '导入存档成功,继续游戏吧!', '导入存档失败', '存档版本已过期,无法导入!'];
experiential = ['导入体验存档成功,体验时间${0}分钟。', '体验存档无法保存!', '体验时间已过,自动读取本地存档。'];
music = ['播放或禁音背景音乐(M)'];
archive = {
empty: '未读取到存档!',
error: '存档坏了!',
load: '读取存档成功',
menu: ['存档管理(A)', '导入存档前请将存档内容粘贴到输入框内'],
copy: ['复制存档', '已经复制存档了,建议保存到备忘录', '复制存档失败', '复制旧存档'],
paste: ['粘贴存档', '粘贴存档内容到输入框成功', '粘贴失败'],
clean: ['删除存档'],
upload: '上传存档',
down: '下载存档',
import: ['导入', '导入存档成功,继续游戏吧!', '导入存档失败', '存档版本已过期,无法导入!'],
experiential: ['导入体验存档成功,体验时间${0}分钟。', '体验存档无法保存!', '体验时间已过,自动读取本地存档。'],
save: ['保存游戏(Ctrl+S)', '每5分钟会自动保存游戏一次', '游戏进度已经保存了。', '保存游戏失败!'],
check: ['存档已更新,保存游戏10分钟内无法回档!'],
};
illustrated = ['装备图鉴(I)'];

1
src/config/i18n/zh/setting.ts

@ -2,3 +2,4 @@ export const title = '系统设置(ESC)'; @@ -2,3 +2,4 @@ export const title = '系统设置(ESC)';
export const action = ['保存设置', '取消'];
export const music = ['背景音乐', '完全关闭', '最小音量', '正常音量'];
export const battle = ['战斗日志', '显示', '隐藏'];
export const speed = ['游戏加速', '正常', '倍'];

6
src/store/action.ts

@ -70,8 +70,9 @@ export const saveGame = ({ state, commit }) => { @@ -70,8 +70,9 @@ export const saveGame = ({ state, commit }) => {
if (state.experiential) {
commit('set_sys_info', { msg: t('experiential.1'), type: 'warning' });
} else {
saveArchive(state);
commit('set_sys_info', { msg: t('saveGame.2'), type: 'win' });
saveArchive(state).then((msg) => {
commit('set_sys_info', msg);
});
}
};
@ -90,6 +91,7 @@ const loadArchive = (commit, data) => { @@ -90,6 +91,7 @@ const loadArchive = (commit, data) => {
} else if (data == 'undfind') {
commit('set_sys_info', { msg: t('loadError'), type: 'warning' });
} else {
commit('set_archive_flag', data.flag);
commit('set_experiential', data.experiential);
commit('set_player_equips', data.equips);
commit('set_player_layer', data.layer || 1);

3
src/store/mutation.ts

@ -127,3 +127,6 @@ export const add_player_curhp = (state, hp) => { @@ -127,3 +127,6 @@ export const add_player_curhp = (state, hp) => {
export const set_experiential = (state, data) => {
state.experiential = data || false;
};
export const set_archive_flag = (state, data) => {
data && (state.archiveFlag = data);
};

7
src/store/state.ts

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
import { i18n, Player, Points, BaseAttribute } from '@/config';
import { uuid } from '@/tool';
const { t } = i18n;
@ -7,7 +8,13 @@ export default { @@ -7,7 +8,13 @@ export default {
{ type: 'win', msg: t('welcome.0') },
{ type: 'win', msg: t('welcome.1') },
],
archiveFlag: {
id: uuid(),
seq: 0,
time: 0,
},
battleLog: 1, //是否显示战斗日志
speed: 1, //游戏加速
mobile: window.innerWidth < 768,
curMenu: null,
equipTip: {

58
src/tool/archive.ts

@ -1,8 +1,10 @@ @@ -1,8 +1,10 @@
import { Equip, Player, Points } from '@/config';
import { getFromStore, insertToStore, store_name_archive } from './IndexedDB';
import { uuid } from './random';
import { createt } from '@/config/i18n';
export const archive_version = '1.0';
const archive_version_strengthen = '1.0_flag';
const at = createt('archive.');
export class GameArchive {
version: String;
@ -14,41 +16,51 @@ export class GameArchive { @@ -14,41 +16,51 @@ export class GameArchive {
autoSell: string[];
shop: any[];
points: Points;
flag;
constructor(player: Player, grid: any[], autoSell: any[], shop: any[], points: Points) {
constructor(state) {
this.version = archive_version;
const player = state.playerAttribute;
this.equips = [player.weapon, player.armor, player.ring, player.neck, player.jewelry, player.pants, player.shoes, player.bracers];
this.lv = player.lv;
this.layer = player.layer;
this.coins = player.coins;
this.grid = grid;
this.autoSell = autoSell;
this.shop = shop;
this.points = points;
this.grid = state.grid;
this.autoSell = state.autoSell;
this.shop = state.shop;
this.points = state.points;
this.flag = state.archiveFlag;
}
}
export const saveArchive = (state) => {
const archive = new GameArchive(state.playerAttribute, state.grid, state.autoSell, state.shop, state.points);
getFromStore(store_name_archive, archive_version_strengthen).then((flag: any) => {
const time = new Date().getTime();
if (!flag || !flag.time || flag.time + 10 * 60 * 1000 < time) {
flag = { version: archive_version_strengthen, time: time };
}
const equips = new Array();
Array.prototype.push.apply(equips, archive.equips);
Array.prototype.push.apply(equips, archive.grid);
equips.forEach((equip) => {
if (!equip) return;
if (equip.strengthenLv > 0 && !equip.id) {
equip.id = uuid();
export const checkArchive = (flag) => {
return new Promise((resolve, reject) => {
getArchive().then((rsp: any) => {
const flago = rsp && rsp.flag;
const time = new Date().getTime();
if (flago && flago.id == flag.id && flag.seq < flago.seq && flago.time + 10 * 60 * 1000 > time) {
resolve(false);
} else {
resolve(true);
}
if (equip.id) {
flag[equip.id] = equip.strengthenLv;
});
});
};
export const saveArchive = (state) => {
return new Promise((resolve, reject) => {
checkArchive(state.archiveFlag).then((rsp) => {
if (rsp) {
state.archiveFlag.time = new Date().getTime();
state.archiveFlag.seq++;
const archive = new GameArchive(state);
insertToStore(store_name_archive, archive).then((rsp) => {
resolve({ msg: at(rsp ? 'save.2' : 'save.3'), type: 'win' });
});
} else {
resolve({ msg: at('check.0'), type: 'warning' });
}
});
insertToStore(store_name_archive, archive);
insertToStore(store_name_archive, flag);
});
};

77
src/views/archive.vue

@ -1,21 +1,21 @@ @@ -1,21 +1,21 @@
<template>
<Tooltip :infos="[t('archive.0')]" width="12rem">
<Tooltip :infos="[at('menu.0')]" width="12rem">
<img class="menu-img" :src="menu_icons.exportGame" @click="showMenu">
</Tooltip>
<Dialog :title="t('archive.0')" v-model="showArchive" top="4rem" left='8%' @close="state.curMenu = null">
<Dialog :title="at('menu.0')" v-model="showArchive" top="4rem" left='8%' @close="state.curMenu = null">
<div class="archive">
<span class="tip">* {{ t('archive.1') }}</span>
<span class="tip">* {{ at('menu.1') }}</span>
<textarea class="textarea" v-model="archive"></textarea>
</div>
<div class="footer">
<button class="button" @click="copyArchive(archive)">{{ t('copyArchive.0') }}</button>
<button class="button" @click="pasteArchive">{{ t('pasteArchive.0') }}</button>
<button class="button" @click="importArchive">{{ t('importArchive.0') }}</button>
<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>
</div>
<div class="footer">
<button class="button" @click="uploadArchive">{{ t('uploadArchive') }}</button>
<button class="button" @click="downArchive">{{ t('downArchive') }}</button>
<button class="button" @click="uploadArchive">{{ at('upload') }}</button>
<button class="button" @click="downArchive">{{ at('down') }}</button>
</div>
</Dialog>
@ -27,10 +27,12 @@ import { computed, onMounted, ref, onBeforeUnmount } from "vue"; @@ -27,10 +27,12 @@ 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 } from "@/tool";
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";
const { t } = useI18n();
// const { t } = useI18n();
const at = createt('archive.');
const { state, commit, dispatch } = useStore();
const showArchive = computed(() => {
return state.curMenu == 'archive';
@ -62,10 +64,10 @@ const showMenu = () => { @@ -62,10 +64,10 @@ const showMenu = () => {
const copyArchive = (archive) => {
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(archive).then(() => {
commit('set_sys_info', { msg: t('copyArchive.1'), type: 'win' })
commit('set_sys_info', { msg: at('copy.1'), type: 'win' })
showMenu();
}).catch(() => {
commit('set_sys_info', { msg: t('copyArchive.2'), type: 'waring' })
commit('set_sys_info', { msg: at('copy.2'), type: 'waring' })
});
} else {
const textField = document.createElement("textarea");
@ -74,7 +76,7 @@ const copyArchive = (archive) => { @@ -74,7 +76,7 @@ const copyArchive = (archive) => {
textField.select();
document.execCommand("copy");
textField.remove();
commit('set_sys_info', { msg: t('copyArchive.1'), type: 'win' })
commit('set_sys_info', { msg: at('copy.1'), type: 'win' })
showMenu();
}
}
@ -112,10 +114,10 @@ const pasteArchive = () => { @@ -112,10 +114,10 @@ const pasteArchive = () => {
if (result.state === 'granted') {
navigator.clipboard.readText().then(text => {
archive.value = text;
commit('set_sys_info', { msg: t('pasteArchive.1'), type: 'win' })
commit('set_sys_info', { msg: at('paste.1'), type: 'win' })
});
} else {
commit('set_sys_info', { msg: t('pasteArchive.2'), type: 'waring' })
commit('set_sys_info', { msg: at('paste.2'), type: 'waring' })
}
});
}
@ -124,29 +126,40 @@ const importArchive = async () => { @@ -124,29 +126,40 @@ const importArchive = async () => {
try {
const data = JSON.parse(AES_CBC_DECRYPT(archive.value, key));
if (!data || data == 'undfind') {
commit('set_sys_info', { msg: t('loadEmpty'), type: 'warning' });
commit('set_sys_info', { msg: at('empty'), type: 'warning' });
}
if (data.version != archive_version) {
commit('set_sys_info', { msg: t('importArchive.3'), type: 'warning' });
commit('set_sys_info', { msg: at('import.3'), type: 'warning' });
return;
}
await checkImportArchive(data);
await dispatch('loadGame', data);
if (state.experiential) {
commit('set_sys_info', { msg: replace(t('experiential.0'), [data.experientialTime]), type: 'win' });
const time = data.experientialTime || 10;
clearTimeout(timeOut);
timeOut = setTimeout(() => {
commit('set_sys_info', { msg: replace(t('experiential.2'), [data.experientialTime]), type: 'warning' });
dispatch('loadGame');
}, time * 60 * 100);
} else {
saveArchive(state);
}
showMenu();
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);
} catch (error) {
console.log(error);
commit('set_sys_info', { msg: t('loadError'), type: 'warning' });
commit('set_sys_info', { msg: at('error'), type: 'warning' });
}
}

1
src/views/backpack/equip-menu/fusion/equip.vue

@ -40,6 +40,7 @@ onMounted(() => { }); @@ -40,6 +40,7 @@ onMounted(() => { });
<style lang="scss" scoped>
.fusion-equip {
display: flex;
margin-bottom: 1rem;
}
.entry {

2
src/views/backpack/equip-menu/fusion/fusion.vue

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
<div class="coins">
{{ t('coins.0') }}:{{ userCoins }}
</div>
<Tooltip :infos="[ft('desc.1'), ft('desc.2'), ft('desc.3')]" width="8rem">
<Tooltip :infos="[ft('desc.1'), ft('desc.2'), ft('desc.3'), ft('desc.4')]" width="8rem">
<div class="descript">- {{ ft('desc.0') }} -</div>
</Tooltip>
<Equip :equip="equip" />

3
src/views/backpack/equip-menu/reforge.vue

@ -130,7 +130,7 @@ const reforge = () => { @@ -130,7 +130,7 @@ const reforge = () => {
tempEntry.value = extraEntry;
reforgeing.value = true;
check();
auto.value && setTimeout(reforge, 200);
auto.value && setTimeout(reforge, 200 / state.speed);
}
const saveOld = () => {
@ -213,5 +213,4 @@ onMounted(() => { }); @@ -213,5 +213,4 @@ onMounted(() => { });
align-items: center;
justify-content: center;
}
</style>

5
src/views/backpack/equip-menu/strengthen.vue

@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
<div class="btn-group" v-if='!auto'>
<p>{{ t('stren.0') }}<span :class="{ 'red': useCoins < needCoins }">{{ needCoins }}</span></p>
<button class="button" @click="strengthen(false)">{{ t('stren.1') }}+{{ parseInt(equip.strengthenLv) + 1
}}</button>
}}</button>
</div>
<div class="btn-group" v-if='!auto'>
<p>{{ t('stren.0') }}<span :class="{ 'red': useCoins < needCoins }">{{ needCoins }}</span></p>
@ -110,7 +110,7 @@ const strengthen = (test?) => { @@ -110,7 +110,7 @@ const strengthen = (test?) => {
}
commit("add_player_coins", -1 * needCoins.value);
auto.value && setTimeout(strengthen, 200);
auto.value && setTimeout(strengthen, 200 / state.speed);
};
const startAuto = () => {
auto.value = true;
@ -158,5 +158,4 @@ onMounted(() => { }); @@ -158,5 +158,4 @@ onMounted(() => { });
color: red;
}
}
</style>

7
src/views/save-game.vue

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
<template>
<Tooltip :infos="[t('saveGame.0'), t('saveGame.1')]" width="12rem">
<Tooltip :infos="[at('save.0'), at('save.1')]" width="12rem">
<img class="menu-img" :src="menu_icons.saveGame" @click="saveGame">
</Tooltip>
</template>
@ -7,12 +7,11 @@ @@ -7,12 +7,11 @@
<script lang="ts" setup>
import { useStore } from "vuex";
import { onBeforeUnmount, onMounted, ref } from "vue";
import { useI18n } from "vue3-i18n";
import { Tooltip } from "@/components"
import { menu_icons } from "@/config";
import { Base64 } from "js-base64";
import { createt } from "@/config/i18n";
const { t } = useI18n();
const at = createt('archive.');
const { state, commit, dispatch } = useStore();
let interval = 0;

13
src/views/setting.vue

@ -21,6 +21,15 @@ @@ -21,6 +21,15 @@
<input type="radio" :value="0" v-model="settings.battle"> {{ t('battle.2') }}
</div>
</div>
<div class="item">
<div class="label">{{ t('speed.0') }}</div>
<div class="options">
<input type="radio" :value="1" v-model="settings.speed"> {{ t('speed.1') }}
<input type="radio" :value="10" v-model="settings.speed"> 10{{ t('speed.2') }}
<input type="radio" :value="50" v-model="settings.speed"> 50{{ t('speed.2') }}
<input type="radio" :value="100" v-model="settings.speed"> 100{{ t('speed.2') }}
</div>
</div>
</div>
<div class="footer">
<button class="button" @click="saveSettings">{{ t('action.0') }}</button>
@ -46,7 +55,8 @@ const show = computed(() => { @@ -46,7 +55,8 @@ const show = computed(() => {
const settings = ref({
type: 'setting',
music: 0.01,
battle: 1
battle: 1,
speed: 1,
})
const saveSettings = () => {
@ -58,6 +68,7 @@ const saveSettings = () => { @@ -58,6 +68,7 @@ const saveSettings = () => {
const set = () => {
dispatch('set_music_volume', settings.value.music);
state.battleLog = settings.value.battle;
state.speed = settings.value.speed || 1;
}
const readSetting = () => {

7
src/views/version/update-log.vue

@ -38,6 +38,13 @@ const hisVersions = [ @@ -38,6 +38,13 @@ const hisVersions = [
]
const updateLogs: any = [{
date: '2025-05-27', version: '1.0',
adjust: [
'新增太古装备融合功能',
'完善存档校验',
'系统设置新增游戏加速',
],
}, {
date: '2025-05-26', version: '1.0',
adjust: [
'新增神话武器:银河裂',

Loading…
Cancel
Save