双端交互

语音接入双端交互

获取语音配置

交互协议

CLIENT_QUERY_CHAT_CAHNNEL_CONFIG_REQ = 25258,    //查询聊天频道相关配置
CLIENT_QUERY_CHAT_CAHNNEL_CONFIG_REP = 25259,

//主动请求暂时没用;服务器会主动下发
struct ClientQueryChatChannelConfigReq : public PacketBase
{
    ClientQueryChatChannelConfigReq() :PacketBase(CLIENT_QUERY_CHAT_CAHNNEL_CONFIG_REQ, sizeof(ClientQueryChatChannelConfigReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientQueryChatChannelConfigReq));
    }
    BYTE model;
    BYTE section;
};

struct ClientQueryChatChannelConfigRep : public PacketBase
{
    ClientQueryChatChannelConfigRep() :PacketBase(CLIENT_QUERY_CHAT_CAHNNEL_CONFIG_REP, sizeof(ClientQueryChatChannelConfigRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientQueryChatChannelConfigRep));
    }
    BYTE model;
    BYTE section;

    bool voiceChat;    // 实时语音功能是否开启
    bool teamChannel;  // 组队时是否进入组队频道
    bool tableChannel; // 建房时是否进入房间频道
    BYTE gameChannel;    // 进入牌局之后是否转换频道 1:全局;2:组队;0:不变

    BYTE reserved[8];  // 预留字段
};

说明

  • 目前语音配置由服务端通知客户端,不需要客户端主动请求;
  • 玩家进入某个模式,且该模式开启了实时语音,则通知客户端;
  • 客户端可根据配置进行语音按钮的显示等;

开启与关闭语音频道

交互协议

// 开启语音频道
CLIENT_OPEN_CHANNEL_REQ = 25260,
CLIENT_OPEN_CHANNEL_REP = 25261,
struct ClientOpenChannelReq : public PacketBase
{
    ClientOpenChannelReq() :PacketBase(CLIENT_OPEN_CHANNEL_REQ, sizeof(ClientOpenChannelReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientOpenChannelReq));
    }
    char device_id[sc_max_device_len];
};

struct ClientOpenChannelRep : public PacketBase
{
    ClientOpenChannelRep() :PacketBase(CLIENT_OPEN_CHANNEL_REP, sizeof(ClientOpenChannelRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientOpenChannelRep));
    }
    enum
    {
        success = 0,
        failed = 1,
    };
    BYTE result;
};

// 关闭语音频道
CLIENT_CLOSE_CHANNEL_REQ = 25262,
CLIENT_CLOSE_CHANNEL_REP = 25263,
struct ClientCloseChannelReq : public PacketBase
{
    ClientCloseChannelReq() :PacketBase(CLIENT_CLOSE_CHANNEL_REQ, sizeof(ClientCloseChannelReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientCloseChannelReq));
    }
    char device_id[sc_max_device_len];
};

struct ClientCloseChannelRep : public PacketBase
{
    ClientCloseChannelRep() :PacketBase(CLIENT_CLOSE_CHANNEL_REP, sizeof(ClientCloseChannelRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientCloseChannelRep));
    }
    enum
    {
        success = 0,
        failed = 1,
    };
    BYTE result;
};

说明

  • 为避免同设备多开,限制同一个设备只能供一个账号进行语音聊天,服务端会记录一份正在使用语音频道的设备数据(redis: 键为voice_cache:区号:设备id,值为账号);
  • 玩家进入语音频道前应该先检测设备限制;
  • 客户端主动退出语音频道,或被踢下线后自动退出语音频道;

语音频道开通申请与通知

交互协议

SS_CLIENT_ENTER_CHAT_CHANNEL_NTF = 25256,    //服务通知客户端加入某个频道
struct SsClientEnterChatChannelNtf : public PacketBase
{
    SsClientEnterChatChannelNtf() : PacketBase(SS_CLIENT_ENTER_CHAT_CHANNEL_NTF, sizeof(SsClientEnterChatChannelNtf))
    {
        PRO_ZERO_MEMORY(this, sizeof(SsClientEnterChatChannelNtf));
    }

    enum emChannelType
    {
        CT_None = 0,
        CT_Team = 1, //组队频道
        CT_Table = 2, //建桌频道(游戏内全局频道)
        CT_Camp = 3, //阵营频道
        CT_GameGlobal = 4, //游戏内全局频道
    };

    friend bostream& operator<<(bostream& bos, const SsClientEnterChatChannelNtf& t)
    {
        bos << t.channel_type << t.status << t.chanel_id;
        return bos;
    }
    static const unsigned int sc_max_channel_id_len = 64;

    BYTE channel_type;
    BYTE status; //0:未开启;1:已开启
    char chanel_id[sc_max_channel_id_len];
};

CLIENT_APPLY_CHAT_CAHNNEL = 25257,    //申请开通聊天频道
struct ClientApplyChatChannel : public PacketBase
{
    ClientApplyChatChannel() :PacketBase(CLIENT_APPLY_CHAT_CAHNNEL, sizeof(ClientApplyChatChannel))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientApplyChatChannel));
    }
    BYTE channel_type; //SsClientEnterChatChannelNtf::emChannelType;
};

语音屏蔽操作

交互协议

// 语音屏蔽请求
ABROAD_CLIENT_SHIELD_CHAT_VOICE_REQ = 48433, 
struct ClientShieldChatVoiceReq : public PacketBase
{
    enum
    {
        shield_enable = 0, // 屏蔽
        shield_cancle,    // 取消屏蔽
    }; 

    BYTE channelType; //SsClientEnterChatChannelNtf::emChannelType;
    BYTE shieldType;
    unsigned int shiledUserId;

    ClientShieldChatVoiceReq() :PacketBase(ABROAD_CLIENT_SHIELD_CHAT_VOICE_REQ, sizeof(ClientShieldChatVoiceReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientShieldChatVoiceReq));
    }
};

//语音屏蔽回复
ABROAD_CLIENT_SHIELD_CHAT_VOICE_REP = 48434,
struct ClientShieldChatVoiceRep : public PacketBase
{
    enum emResult
    {
        ok = 0,
        failed,
        team_not_exist,
        user_not_find,
    };


    unsigned int result;
    BYTE channelType; //SsClientEnterChatChannelNtf::emChannelType;
    BYTE shieldType;
    unsigned int shiledUserId;

    ClientShieldChatVoiceRep() :PacketBase(ABROAD_CLIENT_SHIELD_CHAT_VOICE_REP, sizeof(ClientShieldChatVoiceRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientShieldChatVoiceRep));
    }
};

语音屏蔽信息获取

交互协议

// 获取语音屏蔽信息
ABROAD_CLIENT_VOICE_SHIELD_INFO_REQ = 48440, 
struct ClientShieldVoiceInfoReq : public PacketBase
{
    BYTE channelType; //SsClientEnterChatChannelNtf::emChannelType;

    ClientShieldVoiceInfoReq() :PacketBase(ABROAD_CLIENT_VOICE_SHIELD_INFO_REQ, sizeof(ClientShieldVoiceInfoReq))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientShieldVoiceInfoReq));
    }
};

// 获取语音屏蔽信息回复
ABROAD_CLIENT_VOICE_SHIELD_INFO_REP = 48435,
struct ClientShieldVoiceInfoRep : public PacketBase
{
    unsigned int count;
    unsigned int shiledUserId[MAX_TABLE_PLAYER];

    ClientShieldVoiceInfoRep() :PacketBase(ABROAD_CLIENT_VOICE_SHIELD_INFO_REP, sizeof(ClientShieldVoiceInfoRep))
    {
        PRO_ZERO_MEMORY(this, sizeof(ClientShieldVoiceInfoRep));
    }
};

说明

  • 在玩家收到语音频道号通知的同时,也会收到ABROAD_CLIENT_VOICE_SHIELD_INFO_REP