Files
ogame-vue-ts/src/utils/migration.ts
谦君 752cade67c refactor: 优化主界面布局与通知系统
重构App.vue,首页独立无侧边栏,其他页面采用统一侧边栏布局。新增右下角固定通知区,集成返回顶部、队列通知、外交通知和敌方警报。移除新手引导组件,替换为弱引导提示系统。支持星球重命名弹窗。优化NPC成长与行为定时器逻辑,提升性能和可维护性。删除issue模板及相关文档描述。
2025-12-19 12:01:45 +08:00

190 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Planet, DebrisField, NPC } from '@/types/game'
import { decryptData, encryptData } from './crypto'
import pkg from '../../package.json'
/**
* 数据迁移工具
* 用于从旧版本数据结构迁移到新版本
*/
/**
* 执行数据迁移
* 将旧版本的 universePlanets 和 debrisFields 从 gameStore 迁移到 universeStore
*/
export const migrateGameData = (): void => {
try {
const storageKey = pkg.name
const universeStorageKey = `${pkg.name}-universe`
// 读取旧的加密存档
const oldEncryptedData = localStorage.getItem(storageKey)
if (!oldEncryptedData) return
// 尝试解密(如果是加密格式)
let oldData: any
try {
oldData = decryptData(oldEncryptedData)
} catch {
// 解密失败,可能是新格式(未加密),直接解析
try {
oldData = JSON.parse(oldEncryptedData)
} catch {
return // 无法解析,放弃迁移
}
}
// 标记是否有数据需要保存
let needsSave = false
// 修复NPC数据确保所有必需字段都存在
if (oldData.npcs && Array.isArray(oldData.npcs)) {
const now = Date.now()
const playerId = oldData.player?.id
oldData.npcs.forEach((npc: NPC) => {
// 确保NPC有必需的时间字段并设置随机冷却避免同时行动
if (npc.lastSpyTime === undefined || npc.lastSpyTime === 0) {
// 0-4分钟的随机延迟
const randomSpyOffset = Math.random() * 240 * 1000
npc.lastSpyTime = now - randomSpyOffset
needsSave = true
}
if (npc.lastAttackTime === undefined || npc.lastAttackTime === 0) {
// 0-8分钟的随机延迟
const randomAttackOffset = Math.random() * 480 * 1000
npc.lastAttackTime = now - randomAttackOffset
needsSave = true
}
// 确保NPC有必需的数组字段
if (!npc.fleetMissions) {
npc.fleetMissions = []
needsSave = true
}
if (!npc.playerSpyReports) {
npc.playerSpyReports = {}
needsSave = true
}
if (!npc.relations) {
npc.relations = {}
needsSave = true
}
if (!npc.allies) {
npc.allies = []
needsSave = true
}
if (!npc.enemies) {
npc.enemies = []
needsSave = true
}
// 如果NPC与玩家没有建立关系自动建立中立关系
if (playerId && !npc.relations[playerId]) {
npc.relations[playerId] = {
fromId: npc.id,
toId: playerId,
reputation: 0,
status: 'neutral' as const,
lastUpdated: now,
history: []
}
needsSave = true
}
})
}
// 初始化玩家积分(如果不存在)
if (oldData.player && oldData.player.points === undefined) {
// 积分会在游戏启动时通过 initGame 计算这里设置为0
oldData.player.points = 0
needsSave = true
}
// 迁移 player.diplomaticRelations 到 npc.relations
// 旧版本使用 player.diplomaticRelations[npcId] 存储玩家对NPC的关系
// 新版本统一使用 npc.relations[playerId] 存储NPC对玩家的关系
if (oldData.player?.diplomaticRelations && oldData.npcs && Array.isArray(oldData.npcs)) {
const playerId = oldData.player.id
const playerRelations = oldData.player.diplomaticRelations as Record<string, any>
Object.entries(playerRelations).forEach(([npcId, relation]) => {
const npc = oldData.npcs.find((n: NPC) => n.id === npcId)
if (npc) {
if (!npc.relations) {
npc.relations = {}
}
// 如果NPC对玩家的关系不存在使用玩家对NPC的关系数据
if (!npc.relations[playerId]) {
npc.relations[playerId] = {
...relation,
fromId: npcId,
toId: playerId
}
needsSave = true
} else {
// 如果两边都有数据使用声望值更极端的那个偏离0更远的
const existingReputation = npc.relations[playerId].reputation || 0
const playerReputation = relation.reputation || 0
if (Math.abs(playerReputation) > Math.abs(existingReputation)) {
npc.relations[playerId].reputation = playerReputation
npc.relations[playerId].status = relation.status
needsSave = true
}
}
}
})
// 删除旧的 diplomaticRelations 字段
delete oldData.player.diplomaticRelations
needsSave = true
console.log('[Migration] Migrated player.diplomaticRelations to npc.relations')
}
// 检查是否需要迁移地图数据
const hasOldMapData = oldData.universePlanets || oldData.debrisFields
if (hasOldMapData) {
// 准备 universeStore 数据
const universeData: {
planets: Record<string, Planet>
debrisFields: Record<string, DebrisField>
} = {
planets: {},
debrisFields: {}
}
// 迁移星球数据(排除玩家星球)
if (oldData.universePlanets) {
const oldPlanets = oldData.universePlanets as Record<string, Planet>
const playerPlanets = oldData.player?.planets || []
const playerPlanetIds = new Set(playerPlanets.map((p: Planet) => p.id))
Object.entries(oldPlanets).forEach(([key, planet]) => {
// 只迁移非玩家星球
if (!playerPlanetIds.has(planet.id)) {
universeData.planets[key] = planet
}
})
delete oldData.universePlanets
needsSave = true
}
// 迁移残骸场数据
if (oldData.debrisFields) {
universeData.debrisFields = oldData.debrisFields
delete oldData.debrisFields
needsSave = true
}
// 保存universeStore数据
localStorage.setItem(universeStorageKey, encryptData(universeData))
}
// 如果有任何数据被修改保存gameStore数据
if (needsSave) {
localStorage.setItem(storageKey, encryptData(oldData))
console.log('[Migration] Game data migrated successfully')
}
} catch (error) {
console.error('[Migration] Failed to migrate game data:', error)
}
}