博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
角色数据存储方法
阅读量:5823 次
发布时间:2019-06-18

本文共 2372 字,大约阅读时间需要 7 分钟。

角色数据存储方法

服务端需要做的一件重要的事情就是保存角色(Role)的数据,以便让他下次登陆时可以还原状态。


初始化数据

在角色首次进入场景时,初始化数据。这一个过程是由客户端发起的,流程大致是:

客户端发起请求 -> 服务端请求从数据库中获取数据 -> 获取数据后初始化Role -> 通知客户端进入场景

尽管这一个过程还做了其他许多的逻辑判断,但其核心内容就是数据的获取,这是我们要关注的地方,其代码流程是:

Scene::RoleEnterSceneAsyn    RMIRoleClient::RoleInitAsyn        RMIRoleObject::__RoleInit            RMIRoleInitBackObjectImpl::RoleInitRet

在成功获取数据后,就可以创建Role了。我们平时写代码的地方通常是在:

  • RMIRoleObject::RoleInit,从数据库中获取数据

  • RoleOtherInitParam::SerializeRoleOtherInitParam::Unserialize,将数据序列化和反序列化

存储结构为何需要Reset方法?

我们注意到,大多数的存储结构(其命名如SomeParam)都有一个Reset方法。那为什么不使用构造函数列表初始化的方法初始化各个成员呢?这是因为我们使用了一个宏GET_BINARY_DATA来从数据库中初始化二进制类型的数据。而这个宏是约定使用Reset方法来初始化结构体的:

 

#define GET_BINARY_DATA(DATAADAPTER, TABLE_FIELD, PARAM)                                \{                                                                                       \    PARAM.Reset();                                                                      \    if (DATAADAPTER.m_data_area[TABLE_FIELD].length > sizeof(PARAM) * 2)                \    {                                                                                   \        DATAADAPTER.Free();                                                             \        return -1;                                                                      \    }                                                                                   \    HexToBin(DATAADAPTER.m_data_area[TABLE_FIELD].vcharp, DATAADAPTER.m_data_area[TABLE_FIELD].length, (char*)&PARAM);  \}

 

在Reset方法中忘记初始化成员将造成严重的错误。这些成员只会被默认初始化一次。

RoleOtherInitParam的用处是什么?

大多数系统数据都打包在RoleOtherInitParam,我们照着里面的代码写一般不会出错,但要理解它的意义。RoleOtherInitParam作用是:

  • 当要创建Role时,从数据库中拿数据初始化RoleOtherInitParam,用以初始化Role的各个系统

  • 当要存储Role数据时,把各个系统的数据拷贝给RoleOtherInitParam,用以存储至数据库

因为要通过RMI传输数据,所以RoleOtherInitParam提供了序列化的方法。

存储数据

游戏中大概这几种情况会存储角色数据:

  • 每隔若干秒(大概几分钟)

  • 切换场景时

  • 登出时

其代码流程是:

RMIRoleClient::RoleSaveAsyn    RMIRoleObject::__RoleSave        ...            RMIRoleSaveBackObjectImplRole::RoleSaveRet

只存储修改数据

有一些老一点的系统,比如背包系统,采用的是这样的存储方式:每一个物品都是一条数据库记录,每一个物品都有几个用来记录它的状态(structcommon::CHANGE_STATE)的变量。只有状态发生改变的物品才会存储。

这样的系统需要正确设置状态,编程难度较大。现在已经很少使用这样的方式了,因此暂不做介绍。

存储全部数据

采用这种方式存储的系统每当角色存储时,都把自己的所有数据拷贝出来,刷新到数据库中。其代码流程大致是:

Role::Save    Role::GetRoleOtherInitParam            SomeSystem::GetInitParam

采用这种方法的优点是只需要一个简单的接口就可以完成数据的存储的准备工作。

存储数据流程图

数据初始化的流程就刚好相反。

转载于:https://www.cnblogs.com/jonwei/articles/9589914.html

你可能感兴趣的文章
MySQL出现Access denied for user ‘root’@’localhost’ (using password:YES)
查看>>
通过Roslyn构建自己的C#脚本(更新版)(转)
查看>>
红黑树
查看>>
UIImagePickerController拍照与摄像
查看>>
python调用windows api
查看>>
第四章 mybatis批量insert
查看>>
Java并发框架——什么是AQS框架
查看>>
【数据库】
查看>>
Win配置Apache+mod_wsgi+django环境+域名
查看>>
linux清除文件内容
查看>>
WindowManager.LayoutParams 详解
查看>>
find的命令的使用和文件名的后缀
查看>>
Android的Aidl安装方法
查看>>
Linux中rc的含义
查看>>
曾鸣:区块链的春天还没有到来| 阿里内部干货
查看>>
如何通过Dataworks禁止MaxCompute 子账号跨Project访问
查看>>
js之无缝滚动
查看>>
Django 多表联合查询
查看>>
logging模块学习:basicConfig配置文件
查看>>
Golang 使用 Beego 与 Mgo 开发的示例程序
查看>>