流程设计

师徒系统流程设计

服务部署

  • 师徒数据处理时,大多操作需要判断双方是否在线并进行双方数据处理,最好是个单点服务,且该系统属于社交,故将该系统测处理部署在FriendServer服务上;
  • 师徒系统需要的数据从其他服务(主要是DBS)同步过来;

与好友系统的关系

  • 师徒关系与好友关系独立,即两个玩家是师徒关系,不一定是好友关系;
  • 添加师徒关系是需要判断黑名单,添加黑名单需要判断是否是师徒关系;

离线数据处理

  • 在进行申请、处理申请、解除关系、出师操作时,可能存在对方离线的情况,此时需要拉取离线玩家的数据进行处理;
  • 如果多个人对同一个离线玩家进行操作时,离线玩家的数据读取和保存可能存在时差导致不一致;
  • 对同一个玩家进行操作时,将这些操作先放置到该被操作玩家的等待处理队列中,该处理队列会被一一执行(测试注意多人请求时是否有较大的延迟);

师徒关系申请&处理

师徒关系申请

  • 不可在黑名单中;
  • 满足申请与被申请的基本条件(配置);
  • 不可重复申请同一个玩家;
  • 不可频繁申请(服务端配置申请发出时间间隔);
  • 在解除关系惩罚时间内,不可发出申请;
  • 申请发出成功后,被申请人的师徒数据添加一天申请记录,被申请人在线则提示;

处理师徒申请

  • 不可在黑名单中;
  • 满足申请与被申请的基本条件(配置);
  • 在解除关系惩罚时间内,不可处理申请;
  • 同意申请处理失败,不删除申请记录;
  • 同意申请处理成功,双方建立师徒关系,被申请人在线则提示;
  • 拒绝申请,删除申请记录,被申请人在线则提示;

身份确认与切换

身份定义

enum emMentorIdentity
{
    mentor_identity_init = 0,                 // 初始身份
    mentor_identity_not_open = 1,             // 身份未开放 系统未开启,等级小于拜师的最小等级
    mentor_identity_stu = 2,                  // 徒弟
    mentor_identity_teacher = 3,              // 师父
};

身份确认与切换

  • 根据配置及玩家数据,初始化玩家的身份;
  • 当玩家的数据发生变化时,判断师父身份是否有变化,如果有变化,则重置身份,并对数据进行清理;
  • 身份只可以由0到4增序变化,不可降序变化(除非配置变动,最好不要,会导致玩家和与该玩家关联的玩家数据异常)

徒弟出师

  • 徒弟满足条件后(配置),自动出师,发送徒弟和师父的奖励邮件;
  • 出师后,身份切换到师父,但不一定能收徒(配置);

师徒之间数据同步

  • 双方在线,一方登录或有数据变化时,会将自己的数据通知到与自己有师徒关联的玩家;
  • 注意:如果一方不在线,就可能会存在两边数据显示不一致的情况,后续有好非方案再处理;

异常关系处理

  • 双方在同步数据时,会检查双方的师徒关联是否相对应,如果不对应,则进行异常关系处理:出师处理、解除关系、删除关系等

师徒推荐

游戏方计算推荐值

  • 根据现有数据,计算出师徒的推荐值,记录到一个有序列表中;
  • 不满足拜师或收徒条件、关闭拜师或收徒,则不进行推荐

推荐方处理

  • 数据记录在redis中
  • 师父推荐集合的键名 sorted_set:mentor_recommend_stu_区号 (区号: 内网39 公测38 正式30)
  • 徒弟推荐集合的键名 sorted_set:mentor_recommend_teacher_区号 (区号: 内网39 公测38 正式30)
  • 推荐标签的获取 redis键名:hash:user_mentor_区号(区号: 内网39 公测38 正式30) key:账号, value: json字符串,解析出来后的tag(数字)就是推荐标签,没有则默认为7
  • 从对应的推荐集合中随机几个玩家,获取玩家的昵称、头像、等级、标签,将数据推送给客户端

注意

  • 推荐值不具有实时性,特别是对离线玩家

双端交互

关联关系

// 师徒关系
enum emMentorLinkType
{
    mentor_link_unknow = 0,                 // 未知关系
    mentor_link_teacher_applyer = 1,        // 申请成为你的师父
    mentor_link_stu_applyer = 2,            // 申请成为你的徒弟
    mentor_link_teacher = 3,                // 你的在任师父
    mentor_link_stu = 4,                    // 你的在任徒弟
    mentor_link_stu_graduate = 5,           // 你的出师徒弟
    mentor_link_teacher_graduate = 6,       // 你的出师老师
};

协议处理结果

enum emMentorSysCode
{
    memtorsys_code_ok = 0,                                       // 成功
    memtorsys_code_fail = 1,                                     // 未知错误
    memtorsys_code_no_config = 2,                                // 没有配置
    memtorsys_code_level_not_match = 3,                          // 我的等级不满足
    memtorsys_code_level_not_match2 = 4,                         // 目标等级不满足
    memtorsys_code_official_level_not_match = 5,                 // 我的官阶不满足
    memtorsys_code_official_level_not_match2 = 6,                // 目标官阶不满足
    memtorsys_code_arena_division_not_match = 7,                 // 我的排位赛段位不满足
    memtorsys_code_arena_division_not_match2 = 8,                // 目标排位赛段位不满足
    memtorsys_code_send_time_limit = 9,                          // 我申请发送频繁
    memtorsys_code_send_time_limit2 = 10,                         // 目标申请发送频繁,即目标不能接受和同意申请
    memtorsys_code_apply_list_count_limit = 11,                   // 目标的申请列表达到上限
    memtorsys_code_stu_pos_lock = 12,                             // 我的徒弟席位不足
    memtorsys_code_stu_pos_lock2 = 13,                            // 目标的徒弟席位不足
    memtorsys_code_stu_pos_limit = 14,                            // 我的徒弟席位达到上限
    memtorsys_code_stu_pos_limit2 = 15,                           // 目标的徒弟席位达到上限
    memtorsys_code_in_applyer_black = 16,                        // 目标在我的黑名单中
    memtorsys_code_in_applyed_black = 17,                        // 我在目标的黑名单中
    memtorsys_code_in_break_punish_time = 18,                    // 我在解除关系惩罚时间内
    memtorsys_code_in_break_punish_time2 = 19,                   // 目标在解除关系惩罚时间内,即目标不能接受和同意申请
    memtorsys_code_link_time_limit = 20,                         // 建立关系的时间限制
    memtorsys_code_had_teacher = 21,                             // 我有老师了
    memtorsys_code_had_teacher2 = 22,                            // 目标有老师了
    memtorsys_code_not_link = 23,                                // 没有建立师徒关系
    memtorsys_code_identity_initing = 24,                        // 身份初始化中
    memtorsys_code_graduate = 25,                                // 已出师
    memtorsys_code_isvisitor = 26,                               // 游客不可操作
    memtorsys_code_link_build = 27,                              // 已建立师徒关系
    memtorsys_code_already_in_applylist = 28,                    // 在申请列表中了
    memtorsys_code_not_in_applylist = 29,                        // 不在申请列表中
    memtorsys_code_setting_close = 30,                           // 我设置关闭了拜师或收徒
    memtorsys_code_setting_close2 = 31,                          // 目标设置关闭了拜师或收徒
    memtorsys_code_identity_err = 32,                            // 我当前身份不适合
    memtorsys_code_identity_err2 = 33,                           // 目标当前身份不适合
    memtorsys_code_data_not_load = 34,                           // 师徒数据还没加载
    memtorsys_code_data_not_load2 = 35,                          // 目标师徒数据还没加载
    memtorsys_code_not_init_data = 36,                           // 目标师徒数据未初始化

};

数据长度定义

  • sc_max_nickname_len=40

基础数据获取

ABROAD_MENTOR_DATA_REQ = 48790,
struct ClientMentorBaseDataReq : public PacketBase
{
    ClientMentorBaseDataReq() : PacketBase(ABROAD_MENTOR_DATA_REQ, sizeof(ClientMentorBaseDataReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorBaseDataReq));
    }
};

ABROAD_MENTOR_DATA_REP = 48791,
struct ClientMentorBaseDataRep : public PacketBase
{
    static const unsigned int sc_max_pos_count = 10;
    static const unsigned int sc_max_define_tag_len = 256;

    unsigned int result;
    unsigned int curIdentity;                    // 当前身份 emMentorIdentity
    unsigned int exp;                            // 师徒经验或名师值
    unsigned int todayExp;                        // 师徒经验或名师值当天增加值
    bool bMeetCon;                                // 是否满足拜师或收徒的基础条件
    bool bHadLink;                                // 是否有老师或徒弟
    bool bOpen;                                    // 是否开启拜师或收徒
    unsigned int tag;                            // 拜师或收徒的标签
    char defineTag[sc_max_define_tag_len];        // 自定义标签
    unsigned int params[4];                     // 预留字段
    unsigned int count;                            // 解锁的徒弟席位数目
    unsigned int stuPos[sc_max_pos_count];        // 解锁的徒弟席位

    unsigned int GetLen() { return sizeof(ClientMentorBaseDataRep) - sizeof(stuPos) + count * sizeof(unsigned int); }

    ClientMentorBaseDataRep() : PacketBase(ABROAD_MENTOR_DATA_REP, sizeof(ClientMentorBaseDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorBaseDataRep));
    }
};

获取关联玩家列表

  • 根据请求类型分为师父、徒弟、出师、申请者
ABROAD_MENTOR_LINK_USER_REQ = 48792,
struct ClientMentorLinkUserDataReq : public PacketBase
{
    enum emReqType
    {
        req_my_students = 1, // 获取我的徒弟数据
        req_my_teacher = 2,  // 获取我的师父数据
        req_my_graduate_stu = 3, // 获取我的出师的徒弟
        rey_my_applyer = 4,  // 获取申请者列表
        req_my_graduate_teacher = 5,    // 获取我的出师的师父
    };

    unsigned int reqType;  // emReqType

    ClientMentorLinkUserDataReq() : PacketBase(ABROAD_MENTOR_LINK_USER_REQ, sizeof(ClientMentorLinkUserDataReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorLinkUserDataReq));
    }
};

struct LinkUserData
{
    unsigned int level;                        // 等级
    unsigned int officialLevel;             // 官阶 【2.5.4.2】
    unsigned int linkType;                    // 与我的关系
    unsigned int linkTime;                    // 关联时间
    unsigned int exp;                        // 师门经验或名师值
    unsigned int head;                        // 头像
    unsigned int mentorTag;                 // 师徒标签 【2.5.4.2】
    unsigned int param[2];                    // 预留参数
    unsigned long long uuid;                // uuid
    char nickName[sc_max_nickname_len];        // 昵称
    char noteName[sc_max_nickname_len];        // 备注 【2.5.4.2】

    friend bostream& operator<<(bostream& bos, const LinkUserData& t)
    {
            bos << t.level << t.officialLevel << t.linkType << t.linkTime << t.exp << t.head << t.mentorTag << t.param[0] << t.param[1]
            << t.uuid << t.nickName << t.noteName;
        return bos;
    }
};

ABROAD_MENTOR_LINK_USER_REP = 48793,
struct ClientMentorLinkUserDataRep : public PacketBase
{
    static const unsigned int sc_max_user_count = 50;

    unsigned int result;
    unsigned int reqType;
    unsigned int sendFlag;  // 发送标记,用于数据量较大  分包数目*100+第几个分包  【2.5.4.2】
    unsigned int count;
    LinkUserData linkUsers[sc_max_user_count];

    ClientMentorLinkUserDataRep() : PacketBase(ABROAD_MENTOR_LINK_USER_REP, sizeof(ClientMentorLinkUserDataRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorLinkUserDataRep));
    }

    friend bostream& operator<<(bostream& bos, const ClientMentorLinkUserDataRep& t)
    {
        bos << t.result << t.reqType << t.sendFlag << t.count;
        for (unsigned int i = 0; i < t.count && i < sc_max_user_count; i++)
        {
            bos << t.linkUsers[i];
        }
        return bos;
    }
};

申请发出

ABROAD_MENTOR_APPLY_REQ = 48794,
struct ClientMentorApplyReq : public PacketBase
{
    enum emApplyTo
    {
        apply_to_my_stu = 0,        // 收徒
        apply_to_my_teacher = 1,    // 拜师
    };

    unsigned int applyTo;  // emApplyTo
    char targetNick[sc_max_nickname_len];

    ClientMentorApplyReq() : PacketBase(ABROAD_MENTOR_APPLY_REQ, sizeof(ClientMentorApplyReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorApplyReq));
    }
};

ABROAD_MENTOR_APPLY_REP = 48795,
struct ClientMentorApplyRep : public PacketBase
{
    unsigned int result;
    unsigned int applyTo;
    char targetNick[sc_max_nickname_len];

    ClientMentorApplyRep() : PacketBase(ABROAD_MENTOR_APPLY_REP, sizeof(ClientMentorApplyRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorApplyRep));
    }
};

申请接收通知

ABROAD_MENTOR_APPLY_RECEIVE_NTF = 48804
struct ClientMentorApplyReveiveNtf : public PacketBase
{
    unsigned int applyTo;  // ClientMentorApplyReq::emApplyTo
    // 目标信息
    unsigned int level;  // 等级
    unsigned int officialLevel;  // 官阶
    unsigned int curDivision;  // 当前排位赛段位
    unsigned int historyDivision;  // 历史最高排位赛段位
    unsigned int mentorTag; // 师徒标签
    unsigned int head;  // 头像
    unsigned long long targetUUID;  // uuid
    char targetNick[sc_max_nickname_len]; // 昵称

    ClientMentorApplyReveiveNtf() : PacketBase(ABROAD_MENTOR_APPLY_RECEIVE_NTF, sizeof(ClientMentorApplyReveiveNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorApplyReveiveNtf));
    }
};

申请处理

ABROAD_MENTOR_APPLY_DEAL_REQ = 48796,
struct ClientMentorApplyDealReq : public PacketBase
{
    bool bAgree;
    char targetNick[sc_max_nickname_len];

    ClientMentorApplyDealReq() : PacketBase(ABROAD_MENTOR_APPLY_DEAL_REQ, sizeof(ClientMentorApplyDealReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorApplyDealReq));
    }
};


ABROAD_MENTOR_APPLY_DEAL_REP = 48797,
struct ClientMentorApplyDealRep : public PacketBase
{
    unsigned int result;
    bool bAgree;
    char targetNick[sc_max_nickname_len];

    ClientMentorApplyDealRep() : PacketBase(ABROAD_MENTOR_APPLY_DEAL_REP, sizeof(ClientMentorApplyDealRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorApplyDealRep));
    }
};

申请处理结果通知

ABROAD_MENTOR_APPLY_RESULT_NTF = 48805,
struct ClientMentorApplyResultNtf : public PacketBase
{
    bool bPass;  // 申请通过
    unsigned int applyTo;  // ClientMentorApplyReq::emApplyTo
    char targetNick[sc_max_nickname_len];

    ClientMentorApplyResultNtf() : PacketBase(ABROAD_MENTOR_APPLY_RESULT_NTF, sizeof(ClientMentorApplyResultNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorApplyResultNtf));
    }
};

上下线通知

ABROAD_MENTOR_ONLINE_NTF = 48808
struct ClientMentorLinkUserOnlineNtf : public PacketBase
{
    bool isOnline;
    bool isYourStu;  // 是不是你的徒弟,不是则是你的师父

    ClientMentorLinkUserOnlineNtf() : PacketBase(ABROAD_MENTOR_ONLINE_NTF, sizeof(ClientMentorLinkUserOnlineNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorLinkUserOnlineNtf));
    }
};

解除关系

ABROAD_MENTOR_BREAK_REQ = 48798,
struct ClientMentorBreakReq : public PacketBase
{
    char targetNick[sc_max_nickname_len];

    ClientMentorBreakReq() : PacketBase(ABROAD_MENTOR_BREAK_REQ, sizeof(ClientMentorBreakReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorBreakReq));
    }
};

ABROAD_MENTOR_BREAK_REP = 48799,
struct ClientMentorBreakRep : public PacketBase
{
    unsigned int result;
    unsigned int punishTm; // 惩罚的时间
    char targetNick[sc_max_nickname_len];

    ClientMentorBreakRep() : PacketBase(ABROAD_MENTOR_BREAK_REP, sizeof(ClientMentorBreakRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorBreakRep));
    }
};

解除关系通知

ABROAD_MENTOR_BREAK_NTF = 48806
struct ClientMentorBreakNtf : public PacketBase
{
    bool isMyStu;      // targetNick是我的徒弟,否则是师傅
    char targetNick[sc_max_nickname_len];

    ClientMentorBreakNtf() : PacketBase(ABROAD_MENTOR_BREAK_NTF, sizeof(ClientMentorBreakNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorBreakNtf));
    }
};

出师通知

ABROAD_MENTOR_GRADUATE_NTF = 48807
struct ClientMentorGraduateNtf : public PacketBase
{
    bool isMy;      // 是不是我自己出师的通知,是:targetNick是我的师傅   否:targetNick是我的出师徒弟
    char targetNick[sc_max_nickname_len];

    ClientMentorGraduateNtf() : PacketBase(ABROAD_MENTOR_GRADUATE_NTF, sizeof(ClientMentorGraduateNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorGraduateNtf));
    }
};

发布与设置

ABROAD_MENTOR_SETTING_REQ = 48800,
struct ClientMentorSettingReq : public PacketBase
{
    enum emType
    {
        set_for_student = 1,
        set_for_teacher = 2,
    };

    unsigned int setType;
    unsigned int tag;   // 标签 bit位记录
    bool bOpen;         // 是否开启拜师或收徒
    char defineTag[ClientMentorBaseDataRep::sc_max_define_tag_len];  // 自定义标签

    ClientMentorSettingReq() : PacketBase(ABROAD_MENTOR_SETTING_REQ, sizeof(ClientMentorSettingReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorSettingReq));
    }
};

ABROAD_MENTOR_SETTING_REP = 48801
struct ClientMentorSettingRep : public PacketBase
{
    unsigned int result;
    unsigned int setType;

    ClientMentorSettingRep() : PacketBase(ABROAD_MENTOR_SETTING_REP, sizeof(ClientMentorSettingRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorSettingRep));
    }
};

添加黑名单处理

  • 原协议,内容不变,添加一个错误码op_fail_is_mentor_link

    CFRIEND_OPERATORFRIEND_REP=20606
    struct CFriendOperatorRep : public PacketBase
    {
      enum emresult
      {
          op_success = 1,
          op_waiting_dbsrep_baseinfo,     //等待dbs返回信息
          op_fail,
          op_fail_maxcount,                //已经最大数目了
          op_fail_paramerror,                //参数错误,太长
          op_fail_delnotexist,            //不存在
          op_fail_frienduser_notonline,    //你添加的好友不在线
          op_fail_exist_thisfriend,        //他已经是你的好友了
    
          op_fail_todbs_reqbaseinfofriend_fail0,  //发起向dbs的请求操作失败
          op_fail_dbs_getuserinfo,        //昵称不存在,其实是在dbs上的所有失败
    
          op_fail_del_notfind,            //没有发现
          op_movefail_notneed,            //不需要
    
          op_fill_user_refuseadd,         //对方的好友设置禁止今天好友
    
          op_ok_waiting_yourfriend_agree, //等待对方同意你的申请
          op_fail_maxcount_other,            //对方已经最大数目了
          op_fail_you_isvisitor,            //你是游客不给添加
          op_fail_other_isvisitor,        //对方是游客
          op_fail_exist_inrequest,        //你在对方的好友申请里面
          op_fail_exist_tgt_inrequest,    //对方在你的好友申请里面
          op_fail_exist_inblack,            //你在对方的黑名单里面
          op_fail_exist_tgt_inblack,        //对方在你的黑名单里面
          op_fail_setting_level_limit,
          op_fail_setting_division_limit,
          op_fail_setting_token_empty,
          op_fail_setting_token_error,
          op_fail_setting_token_error_max,
          op_fail_is_mentor_link,    // 是师徒关系 【新增】
      };
      CFriendOperatorReq::em_optype            type;
      emresult                                result;
      unsigned char                            groupid;         
      char                                    friendname[sc_max_nickname_len];
      FSCFriendsGroupsInfoNtf::TFriendItem    newFriendinfo;        //添加的时候才使用,别的时候是不发送的
      CFriendOperatorRep() : PacketBase(CFRIEND_OPERATORFRIEND_REP, sizeof(CFriendOperatorRep)){}
    };
    

关联玩家数据变化通知

struct LinkUserData
{
    unsigned int level;  // 等级
    unsigned int linkType;  // 与我的关系
    unsigned int exp;  // 师门经验或名师值
    unsigned int head;  // 头像
    unsigned int param[2]; // 预留参数
    char nickName[sc_max_nickname_len]; // 昵称

    friend bostream& operator<<(bostream& bos, const LinkUserData& t)
    {
        bos << t.level << t.linkType << t.exp << t.head << t.param[0] << t.param[1] << t.nickName;
        return bos;
    }
};

ABROAD_MENTOR_LINKUSER_INFO_UPDATE = 48813,
struct ClientMentorLinkUserInfoUpdate : public PacketBase
{
    LinkUserData linkUser;

    ClientMentorLinkUserInfoUpdate() : PacketBase(ABROAD_MENTOR_LINKUSER_INFO_UPDATE, sizeof(ClientMentorLinkUserInfoUpdate))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorLinkUserInfoUpdate));
    }
};

经验(师门经验)变化通知

ABROAD_MENTOR_EXP_UPDATE = 48814,
struct ClientMentorExpUpdate : public PacketBase
{
    unsigned int identity;   // 我的身份
    unsigned int exp;        // 总经验值(师门经验,名师值通过名师宝册获取)
    unsigned int dayExp;     // 当天添加额经验值

    ClientMentorExpUpdate() : PacketBase(ABROAD_MENTOR_EXP_UPDATE, sizeof(ClientMentorExpUpdate))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorExpUpdate));
    }
};

对局经验加成通知

  • 原协议
MSG_EXP_ADD_DETAIL=21680
struct MsgExpAddDetail : public PacketBase
{
    static const unsigned char s_c_max_addtype = 20;

    enum
    {
        add_ddys        = 0,    // 多多益善加成
        add_time        = 1,    // 时间加成
        add_skin        = 2,    // skin加成
        add_vip            = 3,    // vip加成
        add_perfect        = 4,    // 完胜加成
        add_generalstar = 5,    // 武将星级加成
        add_guild        = 6,    // 公会加成
        add_marry        = 7,    // 结婚加成
        add_nj            = 8,    // 内奸加成    
        add_hgkh        = 9,    // 回归狂欢
        add_recruit        = 10,    // 战友加成
        add_team        = 11,    // 开黑加成
        add_mentor      = 12,    // 师徒加成 【新增】
        add_timewelfare = 13,    // 限时加成 【新增】
    };

    struct tagAddItems
    {
        BYTE type;
        unsigned short add;
    };

    struct tagPlayerExpAdd
    {
        unsigned char seatid;
        unsigned char addcnt;
        tagAddItems items[s_c_max_addtype];
    };

    unsigned int playercnt;
    tagPlayerExpAdd playerExpAdd[MAX_TABLE_SEAT];

    friend bostream& operator<<(bostream& bos, const MsgExpAddDetail& t)
    {
        bos << t.playercnt;
        for(unsigned int i = 0; i < t.playercnt; ++i)
        {
            bos << t.playerExpAdd[i].seatid;
            bos << t.playerExpAdd[i].addcnt;
            for(unsigned char j = 0 ; j < t.playerExpAdd[i].addcnt; ++j )
            {
                bos << t.playerExpAdd[i].items[j].type;
                bos << t.playerExpAdd[i].items[j].add;
            }
        }
        return bos;
    }


    MsgExpAddDetail() : PacketBase(MSG_EXP_ADD_DETAIL, sizeof(MsgExpAddDetail))
    {
        PRO_ZERO_MEMORY(this, sizeof(MsgExpAddDetail));
    }
};

一键拒绝所有申请者

  • 【2.5.4.2】
ABROAD_MENTOR_DISAGREE_ALL_REQ = 48802,
struct ClientMentorDisagreeAllReq : public PacketBase
{
    ClientMentorDisagreeAllReq() : PacketBase(ABROAD_MENTOR_DISAGREE_ALL_REQ, sizeof(ClientMentorDisagreeAllReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorDisagreeAllReq));
    }
};

ABROAD_MENTOR_DISAGREE_ALL_REP = 48803,
struct ClientMentorDisagreeAllRep : public PacketBase
{
    unsigned int result;

    ClientMentorDisagreeAllRep() : PacketBase(ABROAD_MENTOR_DISAGREE_ALL_REP, sizeof(ClientMentorDisagreeAllRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorDisagreeAllRep));
    }
};

添加备注

  • 【2.5.4.2】
ABROAD_MENTOR_SET_NOTENAME_REQ = 48817,
struct ClientMentorSetNodeNameReq : public PacketBase
{
    unsigned long long uuid;
    char nickName[sc_max_nickname_len];
    char noteName[sc_max_nickname_len];  // 备注

    ClientMentorSetNodeNameReq() : PacketBase(ABROAD_MENTOR_SET_NOTENAME_REQ, sizeof(ClientMentorSetNodeNameReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorSetNodeNameReq));
    }
};

ABROAD_MENTOR_SET_NOTENAME_REP = 48818,
struct ClientMentorSetNodeNameRep : public PacketBase
{
    unsigned int result;
    unsigned long long uuid;
    char nickName[sc_max_nickname_len];
    char noteName[sc_max_nickname_len];  // 备注

    ClientMentorSetNodeNameRep() : PacketBase(ABROAD_MENTOR_SET_NOTENAME_REP, sizeof(ClientMentorSetNodeNameRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientMentorSetNodeNameRep));
    }
};