流程设计与交互

翻牌流程设计与交互

服务端处理方式

  • 使用lua脚本进行流程处理,新增luckycard.lua,修改entrance.lua、helper.lua
  • 配置分离,单独使用一份配置

翻牌活动相关配置

  • 名称: luckycard
  • 模块id: 8
  • 配置需要保证同时只能进行一期翻牌活动,不可以有多期同时进行(即时间段不可以有重合)

redis数据记录

  • hash键名: hash:luckycard_areaid_actid (areaid:区号 actid:期数id)
  • 内容:
    • key: 玩家账号
    • value: 玩家数据
      {
      totalCnt:当前活动周期内累计的抽取次数,累计不重置,
      guaranteeCnt:当前活动周期内累计的抽取次数,根据保底可能被重置
      refreshTm:下一次免费刷新的时间
      payDate:付费刷新的日期
      payCnt:付费刷新的日期内,付费的次数
      resetTm:刷新牌组的时间
      leftCards:未翻牌的牌idx列表
      getCards:未翻牌的牌列表[idx=牌idx,pos=牌位置]}
      switch:翻面状态
      }

活动内容交互

客户端请求

  • 协议号
    CLIENT_ACTIVITY_LUA_REQ=22803
  • 协议内容
    struct ClientActivityLuaReq : public PacketBase
    {
      unsigned int module_type; // 模块类型(不同活动)
      unsigned int opid; // 模块操作id
      unsigned int datalen;
      char data[sc_max_activity_data_len];
    };
    

    服务端回复

  • 协议号
    CLIENT_ACTIVITY_LUA_REP=22804
  • 协议内容
    struct ClientActivityLuaRep : public PacketBase
    {
      unsigned int module_type; // 模块类型(不同活动)
      unsigned int opid; // 模块操作id
      unsigned int datalen;
      char data[sc_max_activity_data_len];
    };
    

请求的opid

-- 请求的opid
local EmOpID = {
    luckycard_get_acklist           = 0,            -- 获取ack列表
    luckycard_get_config            = 1,            -- 获取当前活动配置
    luckycard_get_data              = 2,            -- 获取翻牌信息
    luckycard_reset_cards           = 3,            -- 刷新卡牌
    luckycard_take_card             = 4,            -- 翻牌
    luckycard_card_switch           = 5,            -- 牌翻面
}

处理结果枚举

  • 服务端回复客户端请求的处理结果,客户端只在success表示处理成功并处理数据,其他结果可以进行相应的提示
-- 请求回复的结果
local EnumResult = {
    success = 0,                    -- 成功
    module_close = 1,               -- 模块未开启
    param_error = 2,                -- 参数错误
    click_too_fast = 3,             -- 操作太频繁
    data_error = 4,                 -- 数据错误(resid没有需要的数据)
    activity_no_open = 5,           -- 活动未开启

    redis_error = 6,                -- redis操作失败
    redis_no_data = 7,              -- redis无数据
    logic_error = 8,                -- 逻辑错误

    consume_goods_error = 9,        -- 代币消耗失败
    add_goods_failed = 10,           -- 添加物品失败

    refresh_free_not_meet = 11,     -- 免费刷新条件不满足
    refresh_pay_day_limit = 12,     -- 达到每天付费刷新上限

    make_card_error = 13,           -- 生成牌库失败
    take_card_pos_error = 14,       -- 翻牌位置错误
    take_card_pos_already = 15,     -- 该位置的牌已翻
    take_card_over = 16,            -- 牌已翻完
    card_switch_notshow = 17,       -- 不是展示状态
    card_switch_notdo = 18,         -- 牌还没有翻面
}

翻牌类型

-- 翻牌类型
local TakeCardType = {
    take_one = 0,      -- 翻一张
    all_in = 1,        -- 翻所有
}

牌库免费刷新状态

-- 牌库免费刷新状态
local FreeRefreshState = {
    free_no = 0,          -- 不能免费刷新
    free_reset = 1,       -- 已翻所有牌,可免费刷新一次
    free_period = 2,      -- 周期免费刷新
}

牌库刷新类型

-- 牌库刷新类型
local CardRefreshType = {
    refresh_free = 0,          -- 免费刷新
    refresh_pay = 1,           -- 付费刷新
}

牌的翻面状态

-- 翻面状态
local CardSwitchState = {
    switch_no = 0,              -- 还没有牌
    switch_show = 1,            -- 展示状态
    switch_hide = 2,            -- 翻面状态
}

获取活动列表

请求内容参数

module_type=8
opid=0

处理流程

  1. 获取有效配置;
  2. 获取免费刷新状态;

回复内容

module_type=8
opid=0
data={
    result: EnumResult(success/activity_no_open),
    freeRefreshSate: 免费刷新状态FreeRefreshState
    actlist:{
        [id]={
            id=第几期 string,
            actkey=活动key string,
            actnamekey=名称key string,
            name=模块名 string,
            consumelist=代币道具id列表 string
        }
    }
}

说明

  • 只回复在有效时间内的活动配置,目前是只有一个在有效时间内
  • 可根据freeRefreshSate进行红点提示设置

获取当前活动配置

请求内容

module_type=8
opid=1
data={
id=第几期 string,
}

处理流程

  1. 获取有效配置并回复;
  2. 牌库奖励显示由客户端配置读取

回复内容

module_type=8
opid=1
data={
    result:EnumResult(success/activity_no_open),
    config={
        id=第几期,
        actkey=活动key,
        name=模块名,
        show=是否显示,
        beginTime=开始时间,
        endTime=结束时间,
        countDown=倒计时,
        useList=[ 代币道具使用列表 ],
        refreshUseGoodsId=刷新牌组需要消耗的代币,
        refreshUseGoodsCount=刷新牌组需要消耗的代币数目,
    }
}

获取翻牌数据

请求内容

module_type=8
opid=2
data={
id=第几期 string
}

处理流程

  1. 获取当前有效配置,无则返错;
  2. 查询玩家翻牌数据(redis),查询失败则返错;
  3. 计算翻牌状态数据,回复客户端

回复内容

module_type=8
opid=2
data={
    result:EnumResult(success/activity_no_open/redis_error/data_error),
    freeRefreshSate:免费刷新状态,
    showFreePeriod:是否显示周期刷新提示,0/1,
    freeRefreshCountDown:周期免费刷新的倒计时,在showFreePeriod=1时有效,
    hasCard: 是否有牌可以翻,0/1,
    cardGoodsId: 翻牌消耗的代币id, 在hasCard=1时有效,
    nextCardPrice: 翻下一张牌需要消耗代币数目,在hasCard=1时有效,
    allInPrice:allin需要消耗代币数目,在hasCard=1时有效,
    switchState:翻面状态CardSwitchState,在hasCard=1时有效,
    mustGetCount:再抽取必得几号库的牌,0表示无效
    mustGetPool:必得几号库的id,mustGetCount=0=时无效
    leftCards: [未翻开的牌idx列表]
    getCards:[ 已翻开的牌
        {
            idx = 牌的唯一序号,
            pos = 牌的位置,取值[1, 总牌数]
        }
        ...
    ]
}

说明

  • 客户端查看桌面上的所有牌,通过leftCards和getCards的idx和本地配置获取显示
  • 有牌时,客户端根据翻面状态显示牌是展示还是背面;
  • 必得的提示根据mustGetCount、mustGetPool和本地配置显示,下同

刷新牌库

请求内容

module_type=8
opid=3
data={
id=第几期,
}

处理流程

  1. 获取当前有效配置,无则返错;
  2. 查询玩家翻牌数据(redis),查询失败则返错;
  3. 根据刷新类型判断是否可以刷新,付费刷新需要消耗代币;
  4. 更新玩家翻牌数据并回复;

回复内容

module_type=8
opid=3
data={    result:EnumResult(success/activity_no_open/redis_error/data_error/refresh_pay_day_limit/refresh_free_not_meet/logic_error/make_card_error/consume_goods_error),
freeRefreshSate:免费刷新状态,
showFreePeriod:是否显示周期刷新提示,0/1,
freeRefreshCountDown:周期免费刷新的倒计时,在showFreePeriod=1时有效,
cardGoodsId: 翻牌消耗的代币id,
nextCardPrice: 翻下一张牌需要消耗代币数目,
allInPrice:allin需要消耗代币数目,
showCards:[抽取出的牌idx列表],
mustGetCount:再抽取必得几号库的牌,0表示无效
mustGetPool:必得几号库的id,mustGetCount=0=时无效,
refreshType: 本次刷新的类型CardRefreshType,
switchState:翻面状态CardSwitchState
}

说明

  • 免费刷新时,服务端优先选择free_reset,没有则选择free_period;
  • 当前周期内首次刷新或者周期免费刷新,更新下一次免费刷新的时间;
  • 刷新成功后,如果客户端桌面上有牌显示,需要先清除;
  • 客户端先根据showCards和本地配置,将牌显示在桌面上;

翻牌

请求内容

module_type=8
opid=4
data={
    id=第几期,
    takeType=翻牌类型takeType
    cardPos=翻牌位置,取值[1, 总牌数],takeType=TakeCardType.all_in时填0 ,
}

处理流程

  1. 获取当前有效配置,无则返错;
  2. 查询玩家翻牌数据(redis),查询失败则返错;
  3. 判断翻牌条件;
  4. 消耗代币;
  5. 发放牌的奖品并回复;
  6. 更新玩家翻牌数据;

回复内容

module_type=8
opid=4
data={    result:EnumResult(success/activity_no_open/redis_error/data_error/take_card_pos_error/take_card_pos_already/logic_error/consume_goods_error/add_goods_failed/take_card_over/card_switch_notdo),
freeRefreshSate:免费刷新状态,
showFreePeriod:是否显示周期刷新提示,0/1,
freeRefreshCountDown:周期免费刷新的倒计时,在showFreePeriod=1时有效,
hasCard: 是否有牌可以翻,0/1,
cardGoodsId: 翻牌消耗的代币id, 在hasCard=1时有效,
nextCardPrice: 翻下一张牌需要消耗代币数目,在hasCard=1时有效,
allInPrice:allin需要消耗代币数目,在hasCard=1时有效,
mustGetCount:再抽取必得几号库的牌,0表示无效
mustGetPool:必得几号库的id,mustGetCount=0=时无效
takeType:翻牌类型takeType
takeCards:[翻开的牌idx的列表
        {
            idx = 牌的唯一序号,
            pos = 牌的位置,取值[1, 总牌数]
        }
        ...
],
leftCards: [未翻开的牌idx列表],
getCards:[ 已翻开的牌
        {
            idx = 牌的唯一序号,
            pos = 牌的位置,取值[1, 总牌数]
        }
        ...
    ]
}

说明

  • 客户端根据takeCards和本地配置进行翻牌显示;
  • 客户端根据takeCards和本地配置进行奖品显示;
  • 客户端查看桌面上的所有牌,通过leftCards和getCards的idx和本地配置获取显示

翻面

请求内容

module_type=8
opid=5
data={
id=第几期 
}

处理流程

  1. 获取当前有效配置,无则返错;
  2. 查询玩家翻牌数据(redis),查询失败则返错;
  3. 判断是否可以翻面,可以则记录数据并回复;

回复内容

module_type=8
opid=5
data={
    result:EnumResult(success/activity_no_open/redis_error/data_error/card_switch_notshow),
    freeRefreshSate:免费刷新状态,
    showFreePeriod:是否显示周期刷新提示,0/1,
    freeRefreshCountDown:周期免费刷新的倒计时,在showFreePeriod=1时有效,
    hasCard: 是否有牌可以翻,0/1,
    cardGoodsId: 翻牌消耗的代币id, 在hasCard=1时有效,
    nextCardPrice: 翻下一张牌需要消耗代币数目,在hasCard=1时有效,
    allInPrice:allin需要消耗代币数目,在hasCard=1时有效,
    switchState:翻面状态CardSwitchState,在hasCard=1时有效,
    mustGetCount:再抽取必得几号库的牌,0表示无效
    mustGetPool:必得几号库的id,mustGetCount=0=时无效
    leftCards: [未翻开的牌idx列表]
    getCards:[ 已翻开的牌
        {
            idx = 牌的唯一序号,
            pos = 牌的位置,取值[1, 总牌数]
        }
        ...
    ]
}

说明

  • 客户端查看桌面上的所有牌,通过leftCards和getCards的idx和本地配置获取显示
  • 有牌时,客户端根据翻面状态显示牌是展示还是背面;
  • 必得的提示根据mustGetCount、mustGetPool和本地配置显示,下同