# 数据存储系统 **本文档引用文件** - [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) ## 目录 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)