流程设计

战令系统流程设计

数据库记录

  • 使用redis记录玩家战令数据
  • 键名: hash:userbattlepass区号
  • key: 玩家账号
  • value: ver=版本,type=战令类型,season=赛季,activity=活跃值,bExtreme=是否解锁至尊,takePrizes=已领的奖励列表

战令类型

  • 目前只有pve,后面可扩充
enum BattlepassType
{
    Battlepass_Pve = 0, 
};

战令操作场景

  • 激活至尊或购买活跃时,客户端需要告知,默认为0
enum emBattlepassScene
{
    Scene_Main = 0,     // 主界面或其他
    Scene_RoguelikeGame,  // 爬塔对局
};

双端交互

战令数据请求

  • 客户端主动请求req;
  • 数据发生变化时,服务端主动通知rep;
ABROAD_BATTLEPASS_DATA_REQ=48750
struct ClientBattlepassDataReq : public PacketBase
{
    unsigned int battlepassType;  // BattlepassType
    ClientBattlepassDataReq() : PacketBase(ABROAD_BATTLEPASS_DATA_REQ, sizeof(ClientBattlepassDataReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassDataReq));
    }
};

ABROAD_BATTLEPASS_DATA_REP=48751
struct ClientBattlepassDataRep : public PacketBase
{
    static const unsigned int sc_max_prize_count = 400;

    enum enResult
    {
        ok = 0,
        fail,
    };

    struct TPrizeItem
    {
        unsigned short level;
        unsigned short id;
    };

    BYTE result;
    unsigned int battlepassType;  // BattlepassType
    unsigned int season;  // 赛季
    unsigned short level;  // 等级
    bool extreme;  // 是否解锁至尊
    unsigned int activity;  // 当前活跃值
    unsigned int upgradeNeedActivity;  // 到下一等级需要的活跃值
    unsigned int countDown;  // 赛季剩余时间,秒
    unsigned short count;  
    TPrizeItem takePrizes[sc_max_prize_count];  // 已领取的奖励

    ClientBattlepassDataRep() : PacketBase(ABROAD_BATTLEPASS_DATA_REP, sizeof(ClientBattlepassDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassDataRep));
    }

    friend bostream& operator<<(bostream& bos, const ClientBattlepassDataRep& t)
    {
        bos << t.result;
        bos << t.battlepassType;
        bos << t.season;
        bos << t.level;
        bos << t.extreme;
        bos << t.activity;
        bos << t.upgradeNeedActivity;
        bos << t.countDown;
        bos << t.count;
        for (unsigned char i = 0; i < t.count && i < sc_max_prize_count; ++i)
        {
            bos << t.takePrizes[i].level;
            bos << t.takePrizes[i].id;
        }
        return bos;
    }
};

领取奖励

ABROAD_BATTLEPASS_PRIZE_TAKE_REQ=48752
struct ClientBattlepassPrizeTakeReq : public PacketBase
{
    enum emType
    {
        take_one = 0,  // 领取单个奖励
        take_all,      // 一键领取
    };

    BYTE takeType;
    unsigned int battlepassType;  // BattlepassType
    unsigned short level;
    unsigned short id;
    ClientBattlepassPrizeTakeReq() : PacketBase(ABROAD_BATTLEPASS_PRIZE_TAKE_REQ, sizeof(ClientBattlepassPrizeTakeReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassPrizeTakeReq));
    }
};

ABROAD_BATTLEPASS_PRIZE_TAKE_REP=48753
struct ClientBattlepassPrizeTakeRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        fail,
        not_load_complete,        // 数据未加载完毕
        season_not_open,        // 赛季未开启
        param_not_match,        // 参数不匹配
        take_already,           // 已领取
        no_prize_take,          // 没有奖励可领取
        extreme_limit,          // 至尊未解锁
        add_goods_error,        // 奖励发放失败
    };

    BYTE result;
    BYTE takeType;
    unsigned int battlepassType;  // BattlepassType
    unsigned short level;
    unsigned short id;
    ClientBattlepassPrizeTakeRep() : PacketBase(ABROAD_BATTLEPASS_PRIZE_TAKE_REP, sizeof(ClientBattlepassPrizeTakeRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassPrizeTakeRep));
    }
};

解锁至尊

ABROAD_BATTLEPASS_EXTREME_UNLOCK_REQ=48754
struct ClientBattlepassExtremeUnlockReq : public PacketBase
{
    unsigned int battlepassType;  // BattlepassType
    unsigned int toLevel;   // 解锁到几级,单独解锁至尊填0即可
    unsigned int scene;  // emBattlepassScene
    ClientBattlepassExtremeUnlockReq() : PacketBase(ABROAD_BATTLEPASS_EXTREME_UNLOCK_REQ, sizeof(ClientBattlepassExtremeUnlockReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassExtremeUnlockReq));
    }
};

ABROAD_BATTLEPASS_EXTREME_UNLOCK_REP=48755
struct ClientBattlepassExtremeUnlockRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        fail,
        not_load_complete,        // 数据未加载完毕
        season_not_open,        // 赛季未开启
        config_error,           // 配置错误
        unlock_already,            // 已解锁
        yb_not_enough,          // 元宝不足
        consume_error,          // 扣元宝失败
    };

    BYTE result;
    unsigned int battlepassType;  // BattlepassType
    unsigned int toLevel;
    unsigned int scene;  // emBattlepassScene
    ClientBattlepassExtremeUnlockRep() : PacketBase(ABROAD_BATTLEPASS_EXTREME_UNLOCK_REP, sizeof(ClientBattlepassExtremeUnlockRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassExtremeUnlockRep));
    }
};

购买活跃

ABROAD_BATTLEPASS_ACTIVITY_BUY_REQ=48756
struct ClientBattlepassActivityBuyReq : public PacketBase
{
    unsigned int battlepassType;  // BattlepassType
    unsigned int nowActivity;
    unsigned int buyActivityValue; // 购买的活跃值
    unsigned int scene;  // emBattlepassScene

    friend bostream& operator<<(bostream& bos, const ClientBattlepassActivityBuyReq& t)
    {
        bos << t.battlepassType;
        bos << t.nowActivity;
        bos << t.buyActivityValue;
        bos << t.scene;
        return bos;
    }

    friend bistream& operator>>(bistream& bis, ClientBattlepassActivityBuyReq& t)
    {
        bis >> t.battlepassType;
        bis >> t.nowActivity;
        bis >> t.buyActivityValue;
        bis >> t.scene;
        return bis;
    }

    ClientBattlepassActivityBuyReq() : PacketBase(ABROAD_BATTLEPASS_ACTIVITY_BUY_REQ, sizeof(ClientBattlepassActivityBuyReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassActivityBuyReq));
    }
};

ABROAD_BATTLEPASS_ACTIVITY_BUY_REP=48757
struct ClientBattlepassActivityBuyRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        fail,
        not_load_complete,//数据未加载完毕
        config_error,//配置错误
        season_not_open,//赛季未开启
        can_not_buy,//不能购买
        yb_not_enough,//元宝不足
        consume_error,          // 扣元宝失败
        param_not_match,  
    };

    unsigned int result;
    unsigned int battlepassType;  // BattlepassType
    unsigned int scene;  // emBattlepassScene

    friend bostream& operator<<(bostream& bos, const ClientBattlepassActivityBuyRep& t)
    {
        bos << t.result;
        bos << t.battlepassType;
        bos << t.scene;
        return bos;
    }

    friend bistream& operator>>(bistream& bis, ClientBattlepassActivityBuyRep& t)
    {
        bis >> t.result;
        bis >> t.battlepassType;
        bis >> t.scene;
        return bis;
    }

    ClientBattlepassActivityBuyRep() : PacketBase(ABROAD_BATTLEPASS_ACTIVITY_BUY_REP, sizeof(ClientBattlepassActivityBuyRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientBattlepassActivityBuyRep));
    }
};

注意项

客户端解锁至尊

  • 某些场景的操作可能需要玩家达到战令至尊几级,客户端不满足时可能需要提示购买等操作;
  • 未解锁至尊时,如果未达到等级要求,客户端提示直接解锁到至尊几级,根据配置计算需要的元宝数目;
  • 未解锁至尊时,如果已达到等级要求,客户端提示解锁到至尊,根据配置计算需要的元宝数目;
  • 已解锁至尊时,但未达到等级要求,客户端提示购买活跃,根据配置计算需要的元宝数目;
  • 以上需要客户端根据已有的战令数据和配置进行判断并作出处理