游戏服务器之存档读档

该博客探讨了游戏服务器的存档读档机制,包括存档方式、场景服务器和db服务器的处理流程,以及档案的压缩解压。存档采用随机定时策略,关键角色属性未压缩直接存储,其他数据使用zlib压缩后再存入数据库。解档过程在场景服务器和db服务器协同完成。
摘要由CSDN通过智能技术生成

设计上:

(1)存档方式

定时器在一定范围的分钟内随机存档一次,为了避免集中式存档

第一次需要全部存档一次,因为需要存档版本字段

分标签实时存档设置了标签的数据,减少每次存档数据

(2)压缩处理

档案消息中的角色二进制数据是经过zlib算法压缩处理的,减少每次存档数据

被压缩数据也以压缩形式的二进制存入数据库mysql,在读档案到场景服务器中才会解档

(3)角色属性数据

关键性角色属性数据没有进行压缩处理,以明文方式写入数据库,可直接查询


1、存档方式

在场景服务器:

定时器在一定范围的分钟内随机存档一次。

第一次需要全部存档一次,因为需要存档版本字段。

分标签实时存档设置了标签的数据。

场景服务器循环 
if (_write_record_timer(main_logic_thread::currentTime))
{
//随机时间存档
save(MSG::DB::WRITEBACK_TIMETICK);
first_save = true;
}
else
{
if(!first_save)
{
save(MSG::DB::FIRST_SAVE);//第一次全部内容存档
first_save = true;
}
else
{
operation_save(); //实时标签存档
}
}


2、场景服务器档案处理

(1)存档


 序列化一个用户的所有存档数据

struct SerializeRoleData
{
    SerializeRoleData()
    {
        size = 0;
    }
    RoleData roledata;//角色属性
    uint32 size;
    char data[0];//其他数据
};


全部内容存档

bool scene_player::save(MSG::DB::WriteBack_Type type)
{
    update_roledata(type);


    BUFFER_CMD(MSG::DB::stWriteplayerRoleDataRecordCmd,send,UNZIP_BINARY_SIZE);
    send->writeback_type = type;
    send->charid = id;


    SerializeRoleData *sall = (SerializeRoleData*)(&send->data);
    constructInPlace(sall);
    sall->size = 0;


    5 种类型的存档
    bcopy(&roledata, &sall->roledata, sizeof(sall->roledata));
    other_serialize((char*)(&(send->data.data[0])), send->data.size);
    money_serialize((char*)(&(send->data.data[0])), send->data.size);
    task_serialize((char*)(&(send->data.data[0])), send->data.size);
    item_serialize((char*)(&(send->data.data[0])), send->data.size);


    dbClient->sendmsg(send, sizeof(MSG::DB::stWriteplayerRoleDataRecordCmd) + send->data.size);
    ///清除存档标签
    clear_save_tag();
    //g_log->debug("角色二进制存档数据:%u", send->data.size);


    return true;
}



标签内容存档
void scene_player::operation_save()
{
    if(0 != this->save_tag )
    {
        if((this->save_tag & (1<<SAVE_ROLE_DATA)))  ///有roledata更新的情况
        {
            update_roledata(MSG::DB::WRITEBACK_OPERATION);


            BUFFER_CMD(MSG::DB::stWriteplayerRoleDataRecordCmd,send,UNZIP_BINARY_SIZE);
            send->writeback_type = MSG::DB::WRITEBACK_OPERATION;
            send->charid = id;
            send->save_tag = this->save_tag;


            SerializeRoleData *sall = (SerializeRoleData*)(&send->data);
            constructInPlace(sall);
            sall->size = 0;
            bcopy(&roledata, &sall->roledata, sizeof(sall->roledata));//角色属性存档


            if(this->save_tag & (1<<SAVE_ITEM))//道具存档
            {
                item_serialize((char*)&sall->data, sall->size);
            }
            if(this->save_tag & (1<<SAVE_TASK))//任务存档
            {
                task_serialize((char*)&sall->data, sall->size);
            }
            if(this->save_tag & (1<<SAVE_MONEY))//金钱存档
            {
                money_serialize((char*)&sall->data, sall->size);
            }
            if(this->save_tag & (1<<SAVE_OTHER))//其他存档
            {
                other_serialize((char*)&sall->data, sall->size);
            }
            dbClient->sendmsg(send, sizeof(MSG::DB::stWriteplayerRoleDataRecordCmd) + send->data.size);
        }
        else //没有roledata
        {
            BUFFER_CMD(MSG::DB::stNewSaveBinaryCmd,send,UNZIP_BINARY_SIZE);
            send->charid = id;
            send->save_tag = this->save_tag;
            if(this->save_tag & (1<<SAVE_ITEM)) 二进制压缩道具数据
            {
                item_serialize((char*)&send->data, send->size);
            }
            if(this->save_tag & (1<<SAVE_TASK)) ///二进制压缩任务数据
            {
                task_serialize((char*)&send->data, send->size);
            }
            if(this->save_tag & (1<<SAVE_MONEY)) 金钱(不进行zlib压缩)存档
            {
                money_serialize((char*)&send->data, send->size);
            }
            if(this->save_tag & (1<<SAVE_OTHER)) 其它二进制存档
            {
                other_serialize((char*)&send->data, send->size);
            }
            dbClient->sendmsg(send, sizeof(MSG::DB::stNewSaveBinaryCmd) + send->size);
        }  
        clear_save_tag();///清除存档标签
    }
}




道具存档
bool scene_player::item_serialize(char *pdata, uint32 & cursor)
{
    char* data = pdata;
    char temp[UNZIP_BINARY_SIZE];//存档缓冲区
    bzero(temp,sizeof(temp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值