前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >protobuf 序列化到文件及反序列化

protobuf 序列化到文件及反序列化

作者头像
changan
发布2020-11-04 15:03:43
1.8K0
发布2020-11-04 15:03:43
举报

项目应用

游戏中,将对局的数据保留下来,用于对局回顾及debug等用途,由于协议采用PB,故以二进制的pb格式写入文件,在使用该对局内容的时候,按照格式反序列化出来用于播放对局、压测数据构造等。

涉及的部分: pvp服务器,产生对局数据,然后通过路由发送到recordsvr,一个专门写文件的服务器,写完文件后,使用时对文件解析。

文件的格式: head-data-head-data….

相关的协议如下:

代码语言:javascript
复制
message RecordReq
{
    optional uint64 game_id = 1;
    optional string record_name = 2;
    optional bool finish = 3;
    optional RecordPkg Pkg = 4;
}

message RecordPkg
{
    optional uint32 time_offfect = 1;
    optional uint32 cmd = 2;
    optional bytes fragment_data = 3;
}

message RecordHead
{
    required fixed32 cmd = 1;  
    required fixed32 len = 2;
    required fixed32 time_offect = 3;
}

pvp对局服务器,产生数据

代码语言:javascript
复制
void CPvPGame::SendRecord(uint16_t uiCmd, const Message* msg, bool bFinish/* = false*/)
{
    unsigned int uiNow = CSingletonPvPDateTime::instance()->GetSec();
    uint32_t uiTimeOffset = uiNow - m_battleInfo.battle_base.battle_start_time;

    RecordReq msgReq;
    RecordPkg* pPkg = msgReq.mutable_pkg();
    if (NULL == pPkg)
    {
        return;
    }
    msgReq.set_game_id(GetGameId());
    msgReq.set_record_name(GetRecordName());
    msgReq.set_finish(bFinish);
    pPkg->set_time_offfect(uiTimeOffset);
    pPkg->set_cmd(uiCmd);


    if (GAME_RECORD_START == uiCmd || GAME_RECORD_END == uiCmd)
    {
        GameDataInfo gameData;
        FillGameInfo(&gameData);
        //修正starttime
        gameData.mutable_game_init_info()->set_start_time(m_uiStartTime);
        gameData.SerializeToString(pPkg->mutable_fragment_data());
    }
    else if (NULL != msg)
    {
        msg->SerializeToString(pPkg->mutable_fragment_data());
    }
    else
    {
        return;
    }

    int iRet = 0;
    iRet = CSingletonPvPProcessor::instance()->
        SendMsgToAllServerByIdc(GetOwer(), RecordSvrCmd::RECORD_REQ, msgReq, SERVER_FAMILY_RECORDSVR);

录像服务器,专门写文件

代码语言:javascript
复制
std::stringstream sstrNameTmp;
sstrNameTmp << szRecordDir << "/tmp_" << msgReq.game_id() << "_tmp";

RecordHead rHead;
rHead.set_cmd(msgReq.pkg().cmd());
rHead.set_len(msgReq.pkg().fragment_data().size());
rHead.set_time_offect(msgReq.pkg().time_offfect());

//std::fstream output(sstrNameTmp.str().c_str(), std::ios::out | std::ios::binary | std::ios::app);
std::fstream& output = OpenFile(sstrNameTmp.str().c_str());

std::string strout;
rHead.SerializeToString(&strout);
output << strout;
if (msgReq.pkg().has_fragment_data())
{
    output << msgReq.pkg().fragment_data();
}

//output.close();

LOG_DEBUG(0, 0, "write record|%lu|%s", msgReq.game_id(), sstrNameTmp.str().c_str());
LOG_DEBUG(0, 0, "write record|%lu|%d|%s", msgReq.game_id(), rHead.ByteSize(), rHead.ShortDebugString().c_str());

if (msgReq.finish())
{
    CloseFile(sstrNameTmp.str().c_str());
    rename(sstrNameTmp.str().c_str(), strLogName.c_str());
    LOG_DEBUG(0, 0, "rename|%lu|%s|%s", msgReq.game_id(), sstrNameTmp.str().c_str(), strLogName.c_str());
}

解析对局数据,用于回放或性能测试

代码语言:javascript
复制
  bool Robot::ReadData()
  {
m_IsInitGameDataInfo = true;
      char* writebuff=RunTime::GetInst()->getwritebuff();
      long filelength=RunTime::GetInst()->getfilelength();
      DEBUG("enter ReadData");
      DEBUG("writebuff len:%d,length:%ld",(int)strlen(writebuff),filelength);

/*
message RecordHead
{
	required fixed32 cmd = 1;  //cmd 为0的时候,包体为GameDataInfo结构
	required fixed32 len = 2;
	required fixed32 time_offect = 3;
}
*/
// 先 算一个包头
RecordHead recHead;
recHead.set_cmd(869);			// GAME_RECORD_START
recHead.set_len(1024);			//  fixed32  any 32 bit
recHead.set_time_offect(1024);	// fixed32; any 32 bit
std::string strout;
recHead.SerializeToString(&strout);
int HeadSize = strout.size();

recHead.ParseFromArray(writebuff, HeadSize );
DEBUG("RecordHead: %s", recHead.ShortDebugString().c_str());

m_gameDataInfo.ParseFromArray(writebuff + HeadSize, recHead.len());
DEBUG("m_gameDataInfo: %s", m_gameDataInfo.ShortDebugString().c_str());
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目应用
  • pvp对局服务器,产生数据
  • 录像服务器,专门写文件
  • 解析对局数据,用于回放或性能测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档