253 lines
11 KiB
Markdown
253 lines
11 KiB
Markdown
# 数据存储系统
|
||
|
||
<cite>
|
||
**本文档引用文件**
|
||
- [storage.md](file://doc/core/common/storage.md)
|
||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts)
|
||
- [config.json](file://assets/resources/config.json)
|
||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts)
|
||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts)
|
||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
|
||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts)
|
||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [本地数据持久化机制](#本地数据持久化机制)
|
||
2. [初始化与用户数据区分](#初始化与用户数据区分)
|
||
3. [基本操作方法](#基本操作方法)
|
||
4. [调试与发布模式差异](#调试与发布模式差异)
|
||
5. [数据安全策略](#数据安全策略)
|
||
6. [存储需求与应用示例](#存储需求与应用示例)
|
||
7. [异常处理与最佳实践](#异常处理与最佳实践)
|
||
8. [跨设备同步与本地缓存](#跨设备同步与本地缓存)
|
||
|
||
## 本地数据持久化机制
|
||
|
||
本游戏项目采用Oops Framework提供的本地存储模块,该模块封装了Cocos Creator引擎的`sys.localStorage`对象,实现了跨平台的本地数据存储功能。存储系统不仅支持基础的增删改查操作,还集成了数据加密和多用户数据区分功能,确保玩家数据的安全性和独立性。
|
||
|
||
系统通过`oops.storage`接口提供统一的数据访问方法,所有数据最终存储在设备本地,同时支持与云端数据同步的混合存储策略。本地存储主要用于保存玩家配置、语言设置、游戏进度等关键数据,确保即使在离线状态下也能正常访问游戏内容。
|
||
|
||
**Section sources**
|
||
- [storage.md](file://doc/core/common/storage.md#L1-L38)
|
||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L57)
|
||
|
||
## 初始化与用户数据区分
|
||
|
||
### 初始化本地存储加密
|
||
|
||
本地存储加密通过`oops.storage.init()`方法进行初始化,该方法需要传入加密密钥和初始化向量(IV)两个参数。在项目启动时,系统会从配置文件中读取加密参数并完成初始化。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant 游戏启动
|
||
participant Root组件
|
||
participant 存储系统
|
||
participant 配置文件
|
||
游戏启动->>Root组件 : onLoad()
|
||
Root组件->>配置文件 : 加载config.json
|
||
配置文件-->>Root组件 : 返回配置数据
|
||
Root组件->>存储系统 : oops.storage.init(key, vi)
|
||
存储系统-->>Root组件 : 初始化完成
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L57)
|
||
- [config.json](file://assets/resources/config.json#L1-L20)
|
||
|
||
### 区分用户数据
|
||
|
||
通过`oops.storage.setUser()`方法可以为不同用户设置唯一标识,从而实现多账号数据隔离。系统使用用户ID作为数据存储的命名空间,避免不同账号之间的数据覆盖问题。
|
||
|
||
当用户登录时,系统会调用此方法设置当前用户ID,后续的所有数据操作都将基于该用户ID进行。这对于支持多账号切换的游戏尤为重要,确保每个玩家的游戏进度和设置都能独立保存。
|
||
|
||
**Section sources**
|
||
- [storage.md](file://doc/core/common/storage.md#L10-L15)
|
||
|
||
## 基本操作方法
|
||
|
||
本地存储系统提供了一套完整的数据操作API,包括设置、获取、删除和清空等基本操作。
|
||
|
||
### 设置数据
|
||
|
||
使用`oops.storage.set(key, value)`方法可以将指定键值对保存到本地存储中。该方法接受两个参数:键名和值。值可以是字符串、数字、布尔值或对象等数据类型。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[开始] --> B["oops.storage.set(key, value)"]
|
||
B --> C{数据类型检查}
|
||
C --> |基本类型| D[直接存储]
|
||
C --> |对象类型| E[JSON序列化]
|
||
E --> F[加密处理]
|
||
F --> G[保存到localStorage]
|
||
G --> H[结束]
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [storage.md](file://doc/core/common/storage.md#L20-L22)
|
||
|
||
### 获取数据
|
||
|
||
通过`oops.storage.get(key)`方法可以从本地存储中读取指定键的数据。如果键不存在,则返回null。该方法会自动处理数据的解密和反序列化过程,向调用者返回原始数据类型。
|
||
|
||
### 删除数据
|
||
|
||
`oops.storage.remove(key)`方法用于删除指定键的数据。执行后,该键对应的数据将从本地存储中永久移除。
|
||
|
||
### 清空存储
|
||
|
||
`oops.storage.clear()`方法会清空当前用户的所有本地存储数据。这是一个危险操作,通常只在用户注销或重置游戏时使用。
|
||
|
||
**Section sources**
|
||
- [storage.md](file://doc/core/common/storage.md#L24-L38)
|
||
|
||
## 调试与发布模式差异
|
||
|
||
本地存储系统在调试模式和发布模式下表现出不同的行为特征,这是为了平衡开发效率和生产环境安全性的设计。
|
||
|
||
### 调试模式
|
||
|
||
在调试模式下,系统不会对存储数据进行加密,所有数据以明文形式保存。这一设计便于开发者调试时直接查看和修改存储内容,提高了开发效率。开发者可以通过浏览器的开发者工具直接查看`localStorage`中的数据内容。
|
||
|
||
### 发布模式
|
||
|
||
在发布模式下,系统会自动启用数据加密功能。所有写入本地存储的数据都会经过加密处理,读取时再进行解密。这种机制有效防止了玩家通过直接修改存储文件来作弊的行为,保护了游戏的公平性。
|
||
|
||
加密算法基于项目配置文件中定义的密钥和IV参数,确保了加密过程的一致性和安全性。
|
||
|
||
```mermaid
|
||
graph TB
|
||
A[数据操作] --> B{运行模式}
|
||
B --> |调试模式| C[明文存储]
|
||
B --> |发布模式| D[加密存储]
|
||
C --> E[便于调试]
|
||
D --> F[防止篡改]
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [storage.md](file://doc/core/common/storage.md#L10-L15)
|
||
- [Root.ts](file://extensions/oops-plugin-framework/assets/core/Root.ts#L57)
|
||
|
||
## 数据安全策略
|
||
|
||
### 加密机制
|
||
|
||
系统采用对称加密算法保护本地存储数据,加密密钥和IV参数定义在`assets/resources/config.json`配置文件中。这种集中管理的方式便于统一维护和更新加密参数。
|
||
|
||
项目依赖`crypto-es`库实现加密功能,这是一个轻量级的JavaScript加密库,支持多种加密算法。通过在`package.json`中声明依赖,确保了加密库的版本一致性。
|
||
|
||
### 防篡改机制
|
||
|
||
除了数据加密外,系统还通过用户ID区分机制防止数据篡改。每个用户的数据都有独立的存储空间,避免了通过修改用户ID来访问他人数据的可能性。
|
||
|
||
对于关键数据,系统建议采用双重保护策略:既在本地加密存储,又在云端备份。当检测到本地数据异常时,可以从云端恢复,确保玩家数据不丢失。
|
||
|
||
**Section sources**
|
||
- [config.json](file://assets/resources/config.json#L1-L20)
|
||
- [package.json](file://package.json#L1-L11)
|
||
|
||
## 存储需求与应用示例
|
||
|
||
### 碰撞分组配置存储
|
||
|
||
`BoxSet.ts`文件定义了游戏中的碰撞分组配置,这些配置数据可以通过本地存储系统进行持久化保存。玩家可以自定义碰撞规则,系统将这些设置保存到本地,确保每次启动游戏时都能恢复个性化配置。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class BoxSet {
|
||
+SKILL_TAG : number
|
||
+ATK_RANGE : number
|
||
+DEFAULT : number
|
||
+MONSTER : number
|
||
+HERO : number
|
||
+PLAYER : number
|
||
+BOSS : number
|
||
+BOX_WIDTH : number
|
||
+BOX_HEIGHT : number
|
||
}
|
||
class StorageManager {
|
||
+setCollisionConfig(config)
|
||
+getCollisionConfig()
|
||
+saveToLocalStorage()
|
||
+loadFromLocalStorage()
|
||
}
|
||
StorageManager --> BoxSet : "使用"
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L108)
|
||
- [storage.md](file://doc/core/common/storage.md#L20-L22)
|
||
|
||
### 游戏进度管理
|
||
|
||
系统通过`SingletonModuleComp.ts`管理游戏核心数据,包括玩家金币、英雄列表和出战阵容等。这些数据在游戏运行时存储在内存中,同时定期同步到本地存储。
|
||
|
||
当玩家完成游戏或退出应用时,系统会自动保存当前进度。下次启动游戏时,先从本地存储加载数据,再根据需要从云端同步最新状态,实现了本地与云端的数据一致性。
|
||
|
||
**Section sources**
|
||
- [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts#L1-L108)
|
||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L1-L41)
|
||
|
||
## 异常处理与最佳实践
|
||
|
||
### 数据序列化
|
||
|
||
在存储复杂数据类型时,需要先进行序列化处理。系统推荐使用`JSON.stringify()`将对象转换为字符串,然后再调用存储方法。读取数据时,使用`JSON.parse()`进行反序列化。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[原始数据] --> B[JSON.stringify]
|
||
B --> C[加密]
|
||
C --> D[存储]
|
||
D --> E[读取]
|
||
E --> F[解密]
|
||
F --> G[JSON.parse]
|
||
G --> H[恢复数据]
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L139)
|
||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L119-L159)
|
||
|
||
### 异常处理
|
||
|
||
在进行数据操作时,必须考虑各种异常情况,如存储空间不足、数据损坏、加密失败等。系统建议采用try-catch结构包裹存储操作,并提供相应的错误处理机制。
|
||
|
||
对于关键数据的保存操作,建议实现事务性处理:先写入临时位置,验证成功后再替换原数据,确保数据完整性。
|
||
|
||
**Section sources**
|
||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L139)
|
||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L81-L121)
|
||
|
||
## 跨设备同步与本地缓存
|
||
|
||
### 云端同步机制
|
||
|
||
系统实现了本地存储与微信云开发的集成,通过`WxCloudApi.ts`提供的接口实现数据云端同步。在微信客户端环境下,游戏启动时会自动从云端加载最新数据;在非微信环境下,则使用本地调试数据。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant 客户端
|
||
participant 云端
|
||
participant 本地存储
|
||
客户端->>云端 : login()
|
||
云端-->>客户端 : 用户数据
|
||
客户端->>本地存储 : 保存云端数据
|
||
本地存储-->>客户端 : 确认
|
||
客户端->>云端 : save(gameData)
|
||
云端-->>客户端 : 保存结果
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [WxCloudApi.ts](file://assets/script/game/wx_clound_client_api/WxCloudApi.ts#L0-L93)
|
||
- [index.js](file://build-templates/wechatgame/cloud_functions/cocos_cloud/index.js#L0-L53)
|
||
|
||
### 本地缓存协调
|
||
|
||
系统采用"本地优先,云端同步"的策略。日常游戏过程中主要使用本地存储,定期或在关键节点将数据同步到云端。这样既保证了游戏性能,又实现了数据备份。
|
||
|
||
当玩家在不同设备上登录同一账号时,系统会优先使用云端最新数据,然后与本地数据进行合并,确保游戏进度的一致性。对于冲突数据,采用"最后写入获胜"的策略。
|
||
|
||
**Section sources**
|
||
- [Initialize.ts](file://assets/script/game/initialize/Initialize.ts#L105-L139)
|
||
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L81-L121) |