宜黄红心5

错误码

从10000到10099

错误码 描述
10001 success
10002 数据反序化失败
10003 地区玩法错误
10004 未知事件
10005 没有该用户
10006 用户未登录
10007 用户验证失败
10008 用户重复登录
10009 已加入其他游戏
10010 已登陆其他服务器
10012 加入房间失败
10013 房间不存在
10014 房间已经满人
10015 用户已在房间中
10016 该用户没有在任何房间
10020 重复申请解散
10021 房间不在解散中
10022 获取距离失败
10023 退出房间失败
10024 房间不在准备中
10027 重复解散投票
10028 用户不在当前房间
10029 房间已开始游戏
10030 坐下失败,游戏币不足
10031 没有空房间
10032 重复准备
10033 用户已在其他设备登陆
10034 用户信息读取失败
10035 准备失败,游戏币不足
10036 创建VIP房间失败,游戏币不足
10037 VIP房间, 加入失败
10038 加入VIP房间失败, 密码错误
10039 非VIP房间
10040 无权包牌
10041 房间不在选择包牌中
10045 房间不在游戏中
10046 无权不出
10047 不出token错误
10048 必须出牌
10049 出牌token错误
10050 出牌不符合规则
10051 无权出牌
10052 你没有处于托管中
10053 数据库操作失败
10054 取消托管的次数已经用光
10055 你处于托管中

事件定义

从10000到10099 事件流向:

  • c->s 客户端发送到服务器端
  • s->c 服务器端发送到客户端
  • s->m 服务器端广播到客户端
事件编号 事件名称 事件流向 是否返回 描述
10001 登录 c->s true
10002 服务器返回 s->c 服务器返回,包括成功和异常
10003 心跳包 c->s true 服务器回空包
10004 房间列表 s->m 广播给大厅内但不在房间的玩家
10005 房间变化 s->m 广播给大厅内但不在房间的玩家
10006 加入房间 c->s true 快速开始-不用填房间号
10007 房间信息 s->c 加入房间推送或在房间内掉线回来推送
10008 准备 c->s 玩家准备及取消准备
10009 玩家变化 s->m 加入,离开,上线,掉线,准备,取消准备都广播房间内玩家
10010 游戏信息 s->c 开始游戏推送或游戏内掉线回来推送
10011 申请解散 c->s 如果房间未开始,当作退出房间处理
10012 提示玩家投票 s->m 广播给房间内玩家
10013 玩家投票 c->s 玩家是否同意解散
10014 广播解散结果 s->m 广播给房间内玩家
10015 请求LBS c->s
10016 回复LBS s->c
10017 请求退出房间 c->s true 服务器返回
10018 顶号 s->c 同个用户只能一个连接,新的顶替旧的
10019 请求历史积分 c->s
10020 回复历史积分 s->c
10021 近距离提示 m
10022 聊天 m 客户端和服务器广播同一个命令字/PB结构,服务器不做任何处理
10023 游戏信息 s->c 刷新游戏信息
10031 系统发牌 s->m 广播给房间内玩家,每个人信息不同
10032 提示打独 s->m 让玩家选择是否打独
10033 玩家是否打独 c->s 玩家是否打独,出错回包,成功不回
10034 广播是否打独 s->m 通知打独
10035 广播亮牌 s->m 通知找朋友牌
10036 提示出牌 s->m 通知玩家出牌
10037 玩家出牌 c->s 玩家出牌,出错时回包,成功不回
10038 广播出牌 s->m 广播给房间内玩家,玩家出牌
10039 广播清桌 s->m 广播给房间内玩家,通知清桌
10040 摊牌 s->m 广播给房间内玩家
10041 小局结算 s->m 广播给房间内玩家
10042 回放游戏信息
10055 回放
10056 广播用户进入托管模式 s->m
10057 取消托管模式 c->s true
10058 广播托管模式 s->m

协议PB结构

玩家结构

syntax = "proto3";
package event;
//玩家信息
message EventPlayerInfo {
 //用户ID
 int32   userId       = 1;
 //在线状态  true -- 在线   false -- 离线
 bool    onlineStatus = 2;
 //准备状态  true --准备 false --未准备
 bool    readyStatus  = 3;
    //游戏币数(精确到分)
 int64 coins = 4;
 //座位ID 0,1,2,3
 int32   seatId       = 5;
 //昵称
 string  nickName     = 6;
 //头像url
 string  headUrl      = 7;
 //用户IP
 string  ip          = 8;
 // 性别 0-没有设置,1--男 2--女
 int32   sex          = 9;
 //总积分
 int32   totalJiFen   = 10;
 //登录地址
 string  loginAddress = 11;
}

广播托管模式

// 取消托管成功
message EventCancelEntrustDone { // IResponse 10058
 // 取消托管用户座位号
 int32 seat = 1;
}

取消托管模式

// 取消托管
message EventCancelEntrust { // IRequest 10057
 
}

广播用户进入托管模式

// 广播用户进入托管
message EventInEntrust { // IResponse 10056
 // 进入托管用户的座位号
 int32 seat = 1;
 // 还有多少次可以取消托管
 int32 count = 2;
}

登录

syntax = "proto3";
package event;
message EventLogin {
    //用户登录标识
    string token     = 1;
    //客户端校验 md5(token + secret_key) 服务端和客户端约定secret_key
    string secretString    = 2;
    // 登录地址
    string loginAddress    = 3;
    // 登录经度
    string loginLng        = 4;
    // 登录纬度
    string loginLat        = 5;
}

服务器返回

syntax = "proto3";
package event;
message EventReturn{
    //事件ID
    int32     eventId         = 1;
    //返回码-错误编码
    int32     code            = 2;
    //描述
    string    message         = 3;
}

心跳包

syntax = "proto3";
package event;
//心跳包
message EventHeartBeat {
}

房间列表

syntax = "proto3";
package event;
import "room_info.proto";
//房间列表
message EventRoomList {
    // 房间列表
    repeated EventRoomInfo items = 1[packed = false];
 // 开始房间数
    int32 StartedRoomNum = 2;
}

房间变化

syntax = "proto3";
package event;
import "room_info.proto";
// 大厅内有房间内变化,广播所有大厅里不在房间内玩家
message EventUseRoomChange {
    //变化原因 (0-创建,1-更新资料,2-开始游戏,3-解散)
    int32  reason = 1;
    //变化后房间信息
    EventRoomInfo roomInfo = 2;
 // 开始房间数
    int32 StartedRoomNum = 3;
}

加入房间

快速开始-不用填房间号

syntax = "proto3";
package event;
message EventJoinRoom {
  //房间ID,不填房间号,就是系统选房间即快速开始
 int32   roomId         = 1;
}

房间信息

syntax = "proto3";
package event;
import "player_info.proto";
//房间信息
message EventRoomInfo {
 // 房间id
 int32 roomId = 1;
 // 房间状态,0-没开始,1-游戏中,2-小局结束,3-所有已结束,4-房间解散中,5-选择打独中
 int32 status = 2;
 //当前局数
 int32   curGameNum  = 3;
 // 总局数
 int32   totalGameNum    = 4;
 // 底分
 int32   baseScore    = 5;
 // 玩法描述
 string  playDes         = 6;
 // 玩家信息(以座位号为顺序)
 repeated EventPlayerInfo playerInfo = 7[packed = false];
 // 最低局数
    int32 minGameNum = 8;
}

准备

syntax = "proto3";
package event;
message EventAskReady {
 //true-准备 false--取消准备
 bool  isReady  = 1;
}

玩家变化

syntax = "proto3";
package event;
import "player_info.proto";
// 房间内有玩家变化,广播给房间内玩家
message EventUsePlayerChange {
    //变化原因, 0-加入 1-离开,2-准备 3-取消准备,4-上线 5-离线
    int32  reason = 1;
    //变化玩家座位号
    int32  seatId = 2;
    //变化玩家id
    int32  userId = 3;
    // 变化后,房间内所有玩家信息(以座位号为顺序)
    repeated EventPlayerInfo playerInfo = 4[packed = false];
}

游戏信息

syntax = "proto3";
package event;
import "use_out.proto";

message PBBombType {
 repeated int32 bts = 1[packed = false];
}

message PBGameInfo { // IResponse 10010
 // 是否打独
 bool isAlone = 1;
 // 找朋友亮牌
 int32 friendPai = 2;
 // 朋友关系是否出现
 bool friendShow = 3;
 // 按座位号记录每个玩家对应朋友关系,朋友关系出现才有效
 repeated int32 friendShip = 4[packed = false];
 // 对家用户id,朋友关系出现才有效
 int32 friendUserId = 5;
 // 叫牌者用户id
 int32 bankerUserId = 6;
 // 叫牌者座位id
 int32 bankerSeatId = 7;
 // 当前桌牌(按出牌顺序)
 repeated PBUseOut desktopPai = 8[packed = false];
 // 当前桌牌分
 int32 desktopScore = 9;
 // 当前手牌
 repeated int32 handPai = 10[packed = false];
 // 每个玩家抓分(座位号为下标)
 repeated int32 catchScore = 11[packed = false];
 // 每个玩家炸弹输赢分(座位号为下标)
 repeated int32 bombScore = 12[packed = false];
 // 能否出牌
 bool canOutPai = 13;
 // 是否必须出牌
 bool mustOutPai = 14;
 // 出牌token
 string outPaiToken = 15;
 // 当前出牌座位号
 int32 curOutPaiSeat = 16;
 // 是否选择打独中
 bool isChoiceAlone = 17;
 // 当前选择打独座位号
    int32 choiceSeatId    =18;
 // 每个玩家出完顺序(座位号为下标),0-没出完,1-头游,2-二游,3-三游,4-四游
 repeated int32 overOrder = 19[packed = false];
 // 每个玩家剩余张数(座位号为下标),小于等于5张才有效
 repeated int32 restNum = 20[packed = false];
 // 每个玩家炸弹赔率(座位号为下标)
 repeated int32 bombOdds = 21[packed = false];
 // 选择打独中时,还剩余多少秒考虑时间
 int32 remainAloneTime = 22;
 // 出牌时的剩余时间
 int32 remainOutTime = 23;
 // 是否处于托管中
 repeated bool isEntrust = 24[packed = false];
 // 还有几次取消托管的机会
 int32 cancelEntrustCount = 25;
 // 炸弹类型,按座位号
 repeated PBBombType bombTypes = 26[packed = false];
}

申请解散

syntax = "proto3";
package event;
// 申请解散
message EventAskDismassRoom {
}

提示玩家投票

syntax = "proto3";
package event;
//玩家的投票情况
message EventPlayerVote {
    int32 userId = 1;
    string nickName = 2;
    //投票结果 0--未投票 1--同意 2--拒绝
    int32 vote = 3;
}

// 提示玩家投票及广播解散意见,玩家如果没有投票,则提示投票,否则仅显示
message EventQueryDismassRoom {
 //申请的玩家ID
 int32 applyUserId = 1;
 //申请的玩家昵称
 string applyNickName = 2;
 //各个玩家投票情况
    repeated EventPlayerVote playerVote = 3[packed = false];
    //解散还剩的秒数 如:89
    int32 remainderTime = 5;
}

玩家投票

syntax = "proto3";
package event;
// 玩家上传是否同意解散
message EventReportDismassRoom {
 //true--同意  false--拒绝
 bool    isAgree    = 1;
}

广播解散结果

syntax = "proto3";
package event;
//解散房间的结果
message EventNoticeDismassRoom {
    //true -- 解散 false --不解散
    bool isAgree = 1;
    //解散原因, 0-玩家发起解散, 1-房间超过最低局数,有玩家退出, 2-房间达到最高局数
 // 3-有玩家游戏币为负数, 4-长时间没开始,自动解散
    int32 reason = 2;
    //解散文字说明
    string doc = 3;
 // 房间ID
    int32 roomId = 4;
}

请求LBS

syntax = "proto3";
package event;
//玩家间距离请求
message EventAskGeo {
}

回复LBS

syntax = "proto3";
package event;
message EventUseGeoItem {
    //起始用户ID
    int32 srcUid = 1;
    //结束用户ID
    int32 destUid = 2;
    //用户之间距离
    string distance = 3;
    //用户之间距离,数值表示,单位(米)
    int32 gap = 4;
}

//玩家间距离回包
message EventUseGeo {
    // 用户ID列表
    repeated int32 uids = 1[packed = false];
    // 结果列表
    repeated EventUseGeoItem Items = 2[packed = false];
}

请求退出房间

syntax = "proto3";
package event;
//用户请求退出房间
message EventAskExit {
}

顶号

syntax = "proto3";
package event;
//同个用户新登陆踢出旧登陆
message EventKickOut {
 //用户ID
 int32   userId          = 1;
}

请求历史积分

syntax = "proto3";
package event;
// 请求历史积分
message EventAskHistoryScore {
}

回复历史积分

syntax = "proto3";
package event;
message EventHistoryScoreItem {
 // 用户ID
 int32 userId = 1;
 // 下标-局数,值-积分
 repeated int32 scores = 2[packed = false];
}
// 历史积分回包
message EventUseHistoryScore {
 repeated EventHistoryScoreItem items = 1[packed = false];
}

近距离提示

syntax = "proto3";
package event;
//玩家间距离太近提示
message EventDistanceAlert {
    //提示内容
    string alertStr = 1;
}

刷新游戏信息

syntax = "proto3";

package event;

// 客户端刷新房间信息,不推送给其他人,
message EventRefreshRoom { // IResponse 10023
}

聊天

syntax = "proto3";
package event;
// 客户端和服务器广播同一个命令字,同一个PB结构
// 服务器纯广播,不做任何处理
message EventChat {
 // 聊天类型
 int32 Type = 1;
 // 聊天内容
 string Content = 2;
 // 聊天扩展
 string Extend = 3;
    // 聊天发起人id
    int32 authorId = 4;
}

系统发牌

syntax = "proto3";
package event;
message PBAssignPai {
 // 系统开始发的手牌
 repeated int32 pai  = 1[packed = false];
}

提示打独

syntax = "proto3";
package event;
message PBHintAlone {
 // 是否能选择打独
 bool canAlone =1;
 // 当前叫牌者座位号
 int32 seatId =2;
 // 当前叫牌者用户id
 int32 userId =3;
 // 剩余多少秒的考虑时间
 int32 countdown = 4;
}

玩家是否打独

syntax = "proto3";
package event;
message PBAskAlone {
 // 是否打独
 bool isAlone =1;
}

广播是否打独

syntax = "proto3";
package event;
import "assign_pai.proto";

message PBUseAlone { // IResponse 10034
    // 是否打独
 bool isAlone = 1;
 // 当前叫牌者座位号
 int32 seatId =2;
 // 当前叫牌者用户id
 int32 userId =3;
 // 所有玩家的手牌
 repeated PBAssignPai allPai = 4[packed = false];
}

广播亮牌

syntax = "proto3";
package event;
message PBUseFriend {
 // 庄家座位号
 int32 seatId =1;
 // 庄家用户id
 int32 userId =2;
 // 找朋友的牌
 int32 friendPai =3;
}

提示出牌

syntax = "proto3";
package event;
message PBHintOut {
 // 出牌token
 string token =1;
 // 当前出牌者座位号
 int32 seatId =2;
 // 是否必须出牌
 bool isForce = 3;
 // 倒计时
 int32 countdown = 4;
}

玩家出牌

syntax = "proto3";
package event;
message PBAskOut{
 // 出牌token,处理重复出牌
 string token=1;
 // 此次出的牌
 repeated int32 pai  = 2[packed = false];
 // 是否不出
 bool isSkip = 3;
}

广播出牌

扑克牌型掩码文档

syntax = "proto3";
package event;
message PBUseOut { // IResponse 10038
 // 出牌玩家座位号
 int32 seatId =1;
 // 出牌玩家用户id
 int32 userId =2;
 // 出的牌
 repeated int32 pai  = 3[packed = false];
 // 是否包括找朋友牌,出牌者不是叫牌者
 bool containFriendPai =4;
 // 包括此次出牌的桌面分
 int32 desktopScore =5;
 
 // 牌分类,1-单张,2-对子,3-3张,4-3带1,5-3带2, 6-顺子,7-连对,8-飞机
 // 10-4炸,11-5炸,12-6炸,13-7炸,14-8炸,15-纯色双王
 // 16-5炸(四红/四黑),17-6炸(四红/四黑),
 // 20-三王,21-四王,26--四炸(四红/四黑),
 // 27-一对红心5,28-四张红5,29--8张5,
 int32 paiClass = 6;
 // 牌掩码,例如单张3,3张3带2,见文档
 int32 paiMask = 7;
 // 出完位置,0-没出完,1-头游,2-二游,3-三游,4-四游
 int32 overOrder = 8;
 // 按座位号记录每个玩家此次炸弹或纯色双王的输赢分,赢分为正数,输分为负数
 repeated int32 bombScore = 9[packed = false];
 // 第几轮
 int32 roundIndex = 10;
 // 同一轮第几次
 int32 roundSerial = 11;
 // 按座位号记录每个玩家对应朋友关系,必须出现找朋友牌才有效
 repeated int32 friendShip = 12[packed = false];
 // 是否不出
 bool isSkip =13;
 // 炸弹或纯色双王的赔率
 int32 bombOdds =14;
 // 剩余张数,小于等于5张才有效
 int32 restNum =15;
 // 打出的朋友牌,containFriendPai=true时才有效
 int32 friendPai = 17;
}

广播清桌

syntax = "proto3";
package event;
message PBClearDesktop{
 // 大牌的玩家座位号
 int32 seatId =1;
 // 大牌的玩家用户id
 int32 userId =2;
 // 此次大牌玩家赚的桌面分
 int32 desktopScore =3;
 // 每个玩家抓桌面分(座位号为下标)
 repeated int32 catchScore = 4[packed = false];
 // 第几轮
 int32 roundIndex = 5;
}

摊牌

syntax = "proto3";
package event;
//用户的手牌
message PBTanPaiItem {
    //玩家ID
    int32 userId                        = 1;
    //玩家ID
    int32 seatId                        = 2;
    //手牌
    repeated int32 normalPai            = 3[packed = false];
}
//摊牌
message PBTanPai {
    repeated PBTanPaiItem items = 1[packed = false];
}

小局结算

syntax = "proto3";
package event;
message PBSmallMeta {
    //玩家ID
    int32 userId        = 1;        
    //玩家昵称
    string nickName     = 2;
    //当前总游戏币(精确到分)
    int64  totalCoins    = 4;
    //此局输赢分(牌局结束输赢+炸弹),赢分为正数,输分为负数
    int32  winScore    = 5;        
    //此局炸弹输赢分,赢分为正数,输分为负数
    int32 bombScore = 6;
    //出完顺序,0-没出完,1-头游,2-二游,3,三游,4-四游
    int32 overOrder = 7;
    //是否双围
    bool isDouble = 8;
    //是否打独
    bool isAlone = 9;
 //炸弹赔率
    int32 bombOdds = 10;
 //是否庄家(此局第一个出牌人)
    bool isBanker = 11;
 //队友座位号(找朋友模式才有效)
 int32 friendSeatId = 12;
 //0-没有原炸,2-大原炸
    int32 fryState = 13;
    //捡分
    int32 catchScore = 14;
    //牌局结束输赢分,赢分为正数,输分为负数
    int32 cardScore = 15;
    //输赢游戏币数(单位:分)
    int32 winGold = 16;
 //是否单边
    bool isSingle = 17;
}

message PBSmallSettlement {
    //房间号
    int32   id          = 1;
    //房间状态 0-未开始 1-小局结束 2-游戏中 3-已结束
    int32   status          = 2;
    //当前局数
    int32   now  = 3;
    //下局局数, 如果房间状态为:3, 这里为:
    int32   next     = 4;
    //总局数
    int32   total    = 5;
    //玩法名称
    string  name        = 6;
    //玩法描述
    string  doc         = 7;
    //时间
    string time = 8;
    //各玩家的情况,座位号为下标
    repeated PBSmallMeta players = 9[packed = false];
 //是否打独
 bool isAlone = 10;
 //为true表示数据(是否打独,是否双围,是否庄家,队友座位号,出完顺序)有效,否则无效
 bool dataValid = 11;
    //房间底分
    int32   baseScore     = 12;
 //结束原因, 0-玩家发起解散, 1-房间超过最低局数,有玩家退出, 2-房间达到最高局数
    // 3-有玩家游戏币为负数
    int32 overReason = 13;
    //结束文字说明
    string overDoc = 14;
}

回放游戏信息

syntax = "proto3";
package event;

// 回放游戏信息
message PBReplayGame { // IResponse 10042
 // 是否打独
 bool isAlone = 1;
 // 找朋友亮牌
 int32 friendPai = 2;
 // 叫牌者用户id
 int32 bankerUserId = 3;
 // 叫牌者座位id
 int32 bankerSeatId = 4;
 // 系统发的手牌,按座位号为下标
 repeated PBAssignPai handPai = 5[packed = false];
}

回放

syntax = "proto3";
package event;

message PBReplayCell {
 //对应的事件ID
    int32 eventId           = 1;
 //事件对应序列化后的proto内容
    bytes eventData     = 2;

}
//回放,客户端要求
message PBReplay { // IResponse 10055
    repeated PBReplayCell cells = 1[packed = false];
}