#ifndef CMD_SPARROW_HEAD_FILE #define CMD_SPARROW_HEAD_FILE #include #pragma pack(1) ////////////////////////////////////////////////////////////////////////// //公共宏定义 #define KIND_ID 305 //游戏 I D //组件属性 #define SAN_ZHANG 3 //换牌数--换三张 #define GAME_PLAYER 4 //游戏人数 #define GAME_PLAY_Three 3 #define VERSION_SERVER PROCESS_VERSION(6,0,3) //程序版本 #define VERSION_CLIENT PROCESS_VERSION(6,0,3) //程序版本 #define GAME_NAME TEXT("诸暨麻将") //游戏名字 #define GAME_GENRE (GAME_GENRE_SCORE|GAME_GENRE_MATCH|GAME_GENRE_GOLD) //游戏类型 //游戏状态 #define GS_MJ_FREE GAME_STATUS_FREE //空闲状态 #define GS_MJ_PLAY (GAME_STATUS_PLAY+1) //游戏状态 //常量定义 #define MAX_WEAVE 4 //最大组合 #define MAX_INDEX 34 //最大索引 34 //#define MAX_INDEX 34 //推倒胡最大索引 27 #define MAX_COUNT 14 //最大数目 #define MAX_REPERTORY_ZJ 136 //黄石晃晃136张牌 #define MAX_REPERTORY_ZJ_Two 100 //2人麻将 不带万字 最大张数 /*#define MAX_REPERTORY_ZJ 136 //推倒胡*/ #define MAX_TING 20 //最大听牌数 #define MAX_CHANGE_SCORE 20 //最大积分变动次数 //扑克定义 #define MAX_RIGHT_COUNT 1 //最大权位DWORD个数 #define GAME_TIMEOUT 10 //玩家出牌超时时间 ////////////////////////////////////////////////////////////////////////// //组合子项 struct CMD_WeaveItem { INT cbWeaveKind; //组合类型 BYTE cbCenterCard; //中心扑克 BYTE cbPublicCard; //公开标志 WORD wProvideUser; //供应用户 BYTE cbMargicOffset[4]; //如果有财神参与组合,财神的位置 1-4 ,该位置存储实际是那张财神的index }; ////////////////////////////////////////////////////////////////////////// //服务器命令结构 #define SUB_S_GAME_START 100 //游戏开始 #define SUB_S_OUT_CARD 101 //出牌命令 #define SUB_S_SEND_CARD 102 //发送扑克 #define SUB_S_TING_CARD 103 //听牌单独协议 #define SUB_S_OPERATE_NOTIFY 104 //操作提示 #define SUB_S_OPERATE_RESULT 105 //操作命令 #define SUB_S_GAME_END 106 //游戏结束 #define SUB_S_TRUSTEE 107 //用户托管 #define SUB_S_CHI_HU 108 //胡牌 #define SUB_S_XUELIU_END 109 //血流单局游戏结束协议 #define SUB_S_GANG_SCORE 110 // #define SUB_S_NOTICE_BAO 120 //通知包台 #define SUB_S_BAO_CHOICE 121 //包台广播 #define SUB_S_BAO_RESULT 122 //包结果 #define SUB_S_CAI_RESULT 123 //财神结果 #define SUB_S_DING_CAI_RESULT 124 //定财神返回结果 #define SUB_S_NOTIFY_QIANGGH 125 // 通知抢杠胡S->C #define SUB_S_PANGGUAN 200 //旁观者登陆游戏 #define LEN_PRIVATE_TABLE_ID 7 #define LEN_NICKNAME 32 #define LEN_HEAD_URL 256 #define LEN_RECORD 512 enum MahJongType { hshh = 30, //诸暨麻将 hzhh, //红中晃晃 fchh, //发财晃晃 count = 50, //总数 }; struct CMD_S_GameConfig { WORD wSubGameID; // 30 翻财神 31 包麻将 int wDiScore; //底分 WORD wFanFei; //房费(0房间创建者,1打牌者平摊) WORD wIpLimit; //IP限制(0限制,1不限制); WORD wPlayCountRule; //一次玩的局数(8局?16局?) WORD RoomId; //房间ID WORD IsOwner; //是否房主 WORD wHadPlayCount; //当前局数 TCHAR sPrivateTableID[LEN_PRIVATE_TABLE_ID]; BYTE bDuoLai; //包麻将 使用此变量,作为是否计算 大牌分数 WORD wFengDing; //封顶分数 BYTE tmp1; //备用字段 //0,4人 | 1,,3人 |2,2人 int tmp2; //备 bool ToString(TCHAR* pBuffer, int iLen) { if (sizeof(CMD_S_GameConfig) * 16 > iLen) return false; #ifdef _UNICODE _snwprintf(pBuffer, iLen, TEXT("游戏配置->游戏类型:%d,游戏低分:%d,房费扣出方式:%d,IP地址限制:%d,玩的局数:%d,是否为房主:%d,当前局数:%d,房间号码:%d") , wSubGameID, wDiScore, wFanFei, wIpLimit, wPlayCountRule, IsOwner, wHadPlayCount, sPrivateTableID); #else _snwprintf(pBuffer, iLen, TEXT("游戏配置->游戏类型:%d,游戏低分:%d,房费扣出方式:%d,IP地址限制:%d,玩的局数:%d,是否为房主:%d,当前局数:%d,房间号码:%d") , wSubGameID, wDiScore, wFanFei, wIpLimit, wPlayCountRule, IsOwner, wHadPlayCount, sPrivateTableID); #endif //mylog::ToSet(pBuffer, iLen); return true; } }; //游戏状态 struct CMD_S_StatusFree { CMD_S_GameConfig gameConfig; //游戏基本配置 INT lUserTmpScore[GAME_PLAYER]; //临时积分。在私有桌子中不使用自身的积分或金币,使用临时积分。 BYTE leftTime; //未开始设置 255 WORD wchairId; //发起人座位号 BYTE options[GAME_PLAYER]; // 0 未决定 1 tongy 2jj BYTE UserStat; //玩家当前状态 }; //旁观者断线重连 struct CMD_S_PangGuan { CMD_S_GameConfig gameConfig; INT lUserTmpScore[GAME_PLAYER]; //临时积分。本轮玩家的积分 //游戏变量 BYTE GameStatus; //0等待开始,1游戏中 BYTE cbTotalCardCount; //游戏总牌数 BYTE cbLeftCardCount; //单局游戏剩余牌数 WORD wBankerUser; //本局游戏庄家 BYTE lSiZi[4]; //色子1,2,皮子,癞子 DWORD dwOwnerID; //房主ID //WORD bWanLaiZi[GAME_PLAYER]; //每个打出玩家癞子数 //当前状态 WORD wCurrentUser; //当前用户 BYTE bPutCardData[GAME_PLAYER]; //最后一张牌打出的人和牌值 BYTE totalOptTime; //总操作时间10秒 BYTE leftOptTime; //还剩多少时间0 BYTE cbDiscardCount[GAME_PLAYER]; //丢弃数目 BYTE cbDiscardCard[GAME_PLAYER][40]; //丢弃记录 BYTE cbCardCount[GAME_PLAYER]; //每个玩家扑克数目 //组合扑克 BYTE cbWeaveCount[GAME_PLAYER]; //组合数目 CMD_WeaveItem WeaveItemArray[GAME_PLAYER][MAX_WEAVE]; //组合扑克 }; //游戏状态,断线重连 struct CMD_S_StatusPlay { CMD_S_GameConfig gameConfig; INT lUserTmpScore[GAME_PLAYER]; //临时积分。本轮玩家的积分 BYTE leftTime; //255未开始 WORD wchairId; //解散申请人 BYTE options[GAME_PLAYER]; //在坐玩家 解散状态 0 未决定 1 tongy 2jj //游戏变量 BYTE cbTotalCardCount; //游戏总牌数 BYTE cbLeftCardCount; //单局游戏剩余牌数 WORD wBankerUser; //本局游戏庄家 BYTE lSiZi[4]; //色子1,2,皮子,癞子 DWORD dwOwnerID; //房主ID //包家ID 6位 包家台数6位 每5位一个玩家台数 //WORD bWanLaiZi[GAME_PLAYER]; //每个玩家打出癞子数(低四位是癞子,中四位是红中杠的个数,高四位就是发财杠的个数) //当前状态 WORD wCurrentUser; //当前用户 BYTE bPutCardData[GAME_PLAYER]; //最后一张牌打出的人和牌值 BYTE totalOptTime; //总操作时间10秒 BYTE leftOptTime; //还剩多少时间0 BYTE cbDiscardCount[GAME_PLAYER]; //丢弃数目 BYTE cbDiscardCard[GAME_PLAYER][40]; //丢弃记录 BYTE cbCardCount[GAME_PLAYER]; //每个玩家扑克数目 //组合扑克 BYTE cbWeaveCount[GAME_PLAYER]; //组合数目 CMD_WeaveItem WeaveItemArray[GAME_PLAYER][MAX_WEAVE]; //组合扑克 BYTE cbCardData[MAX_COUNT]; //当前玩家手牌 //断线玩家数据就是当前牌权玩家 INT cbActionMask; //操作掩码 WORD gangCards[6]; //当有杠的时候这里面有牌 bool ToString(TCHAR* pBuffer, int iLen) { if (sizeof(CMD_S_StatusPlay) * 16 > iLen) return false; CString outCards; for (int i = 0; i < 4; i++) { CString tmp; tmp.Format(_T(" 玩家%d手牌 |\r\n"),i); outCards += tmp; for (int j = 0; i < cbDiscardCount[i];j++) { CString strTmp; strTmp.Format(_T("0x%x "), cbDiscardCard[i][j]); outCards += strTmp; } outCards += _T(" |\r\n"); } OutputDebugString(outCards); TCHAR tempcard[1024 * 2] = { 0 }; #ifdef _UNICODE _snwprintf(tempcard, iLen, TEXT("断线重连命令->重连用户:%d,最后的出牌:[%d][%d][%d][%d],玩家手牌数量:[%d][%d][%d][%d],玩家牌值:[%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d],包家[%d],台数[%d] 打出的牌=%s ") , wCurrentUser, bPutCardData[0], bPutCardData[1], bPutCardData[3], bPutCardData[3], cbCardCount[0], cbCardCount[1], cbCardCount[2], cbCardCount[3], cbCardData[0], cbCardData[1], cbCardData[2], cbCardData[3] , cbCardData[4], cbCardData[5], cbCardData[6], cbCardData[7], cbCardData[8], cbCardData[9], cbCardData[10], cbCardData[11], cbCardData[12], cbCardData[13], (dwOwnerID & 0x3f), ((dwOwnerID >> 6) & 0x3f), outCards.GetBuffer() ); #else _snwprintf(tempcard, iLen, TEXT("断线重连命令->重连用户:%d,最后的出牌:[%d][%d][%d][%d],玩家手牌数量:[%d][%d][%d][%d],玩家牌值:[%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d][%d],包家[%d],台数[%d]") , wCurrentUser, bPutCardData[0], bPutCardData[1], bPutCardData[3], bPutCardData[3], cbCardCount[0], cbCardCount[1], cbCardCount[2], cbCardCount[3], cbCardData[0], cbCardData[1], cbCardData[2], cbCardData[3] , cbCardData[4], cbCardData[5], cbCardData[6], cbCardData[7], cbCardData[8], cbCardData[9], cbCardData[10], cbCardData[11], cbCardData[12], cbCardData[13] (dwOwnerID & 0x3f), ((dwOwnerID >> 6) & 0x3f) ); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; //游戏开始 struct CMD_S_GameStart { WORD wBankerUser; //庄家用户, WORD wCurrentUser; //就是当前用户 INT cbUserAction; //用户动作(0:没操作,0x08:碰牌,0x10:杠,0x80:自摸等) WORD ActionCard[6]; //动作所对应的牌 BYTE cbCardData[MAX_COUNT*GAME_PLAYER]; //扑克列表 BYTE cbSiceLaiZi[4]; //色子1,2,皮子,癞子 BYTE cbLeftCardCount; //剩余牌 BYTE cbTotalCardCount; //总麻将数 BYTE cbOptTime; //操作时间(秒) BYTE cbCurrPlay; //当前局数 BYTE cbSliceCheckBankUser[2]; bool ToString(TCHAR* pBuffer, int iLen) { if (sizeof(CMD_S_GameStart) * 16 > iLen) return false; TCHAR tempcard[2000]; //TCHAR tempActionCard[2000]; ZeroMemory(tempcard, 2000 * sizeof(TCHAR)); //ZeroMemory(tempActionCard, 2000 * sizeof(TCHAR)); for (BYTE i = MAX_COUNT*wCurrentUser; i < MAX_COUNT*(wCurrentUser + 1); i++) { SwitchToStringCard(cbCardData[i], tempcard, 2000); } tempcard[1999] = 0; //tempActionCard[1999] = 0; #ifdef _UNICODE _snwprintf(pBuffer, iLen, TEXT("游戏开始->庄家用户:%d,当前用户:%d,用户动作:0x%x,扑克列表:%s,[色子:%d,色子:%d],[色子:%d,色子:%d],皮子:0x%x,癞子:0x%x,剩余牌数:%d,总麻将数:%d,操作时间:%d,当前局数:%d,操作牌:0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x") , wBankerUser, wCurrentUser, cbUserAction, tempcard, cbSiceLaiZi[0], cbSiceLaiZi[1], cbSliceCheckBankUser[0], cbSliceCheckBankUser[1], cbSiceLaiZi[2], cbSiceLaiZi[3], cbLeftCardCount, cbTotalCardCount, cbOptTime, cbCurrPlay, ActionCard[0], ActionCard[1], ActionCard[2], ActionCard[3], ActionCard[4], ActionCard[5]); #else _snwprintf(pBuffer, iLen, TEXT("游游戏开始->庄家用户:%d,当前用户:%d,用户动作:0x%x,扑克列表:%s,[色子:%d,色子:%d],[色子:%d,色子:%d],皮子:0x%x,癞子:0x%x,剩余牌数:%d,总麻将数:%d,操作时间:%d,当前局数:%d,操作牌:0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x") , wBankerUser, wCurrentUser, cbUserAction, tempcard, cbSiceLaiZi[0], cbSiceLaiZi[1],cbSliceCheckBankUser[0],cbSliceCheckBankUser[1], cbSiceLaiZi[2], cbSiceLaiZi[3], cbLeftCardCount, cbTotalCardCount, cbOptTime, cbCurrPlay, ActionCard[0], ActionCard[1], ActionCard[2], ActionCard[3], ActionCard[4], ActionCard[5]); #endif //mylog::ToSet(pBuffer, iLen); return true; } bool SwitchToStringCard(BYTE bData, TCHAR pBuffer[], int iLen) { if (wcslen(pBuffer) > 1980 + iLen) { return false; } BYTE iHuaSe = (bData & 0xF0) >> 4; BYTE bValue = (bData & 0x0F); TCHAR szTemp[8]; ZeroMemory(szTemp, 8*sizeof(TCHAR)); switch (iHuaSe) { case 0: { switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一万~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二万~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三万~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四万~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五万~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六万~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七万~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八万~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九万~")); break; } default: break; } break; } case 1: switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一条~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二条~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三条~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四条~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五条~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六条~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七条~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八条~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九条~")); break; } default: break; } break; case 2: switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一筒~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二筒~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三筒~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四筒~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五筒~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六筒~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七筒~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八筒~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九筒~")); break; } default: break; } break; case 3: switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("东风~")); break; } case 2: { StringCchCat(szTemp, 16, _T("南风~")); break; } case 3: { StringCchCat(szTemp, 16, _T("西风~")); break; } case 4: { StringCchCat(szTemp, 16, _T("北风~")); break; } case 5: { StringCchCat(szTemp, 16, _T("红中~")); break; } case 6: { StringCchCat(szTemp, 16, _T("发财~")); break; } case 7: { StringCchCat(szTemp, 16, _T("白板~")); break; } default: break; } break; default: break; } StringCchCat(pBuffer, iLen, szTemp); return true; } }; //出牌命令 struct CMD_S_OutCard { WORD wOutCardUser; //出牌用户,座位号 BYTE bOptType; //操作类型(0,表示普通出牌,1,表示癞子杠) BYTE cbOutCardData; //出牌扑克 bool ToString(TCHAR* pBuffer, int iLen) { if (sizeof(CMD_S_OutCard) * 16 > iLen) return false; #ifdef _UNICODE _snwprintf(pBuffer, iLen, TEXT("出牌命令->出牌用户:%d,操作类型(0表示普通出牌,1表示癞子杠):0x%x,出牌数据:0x%x") , wOutCardUser, bOptType, cbOutCardData); #else _snwprintf(pBuffer, iLen, TEXT("出牌命令->出牌用户:%d,操作类型(0表示普通出牌,1表示癞子杠):0x%x,出牌数据:0x%x") , wOutCardUser, bOptType, cbOutCardData); #endif //mylog::ToSet(pBuffer, iLen); return true; } /*bool SwitchToStringCard(BYTE bData, TCHAR pBuffer[], int iLen) { if (wcslen(pBuffer) > 1980 + iLen) { return false; } BYTE iHuaSe = (bData & 0xF0) >> 4; BYTE bValue = (bData & 0x0F); TCHAR szTemp[8]; ZeroMemory(szTemp, 8 * sizeof(TCHAR)); switch (iHuaSe) { case 0: { switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一万~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二万~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三万~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四万~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五万~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六万~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七万~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八万~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九万~")); break; } default: break; } break; } case 1: switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一条~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二条~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三条~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四条~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五条~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六条~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七条~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八条~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九条~")); break; } default: break; } break; case 2: switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一筒~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二筒~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三筒~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四筒~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五筒~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六筒~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七筒~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八筒~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九筒~")); break; } default: break; } break; default: break; } StringCchCat(pBuffer, iLen, szTemp); return true; }*/ }; //听牌数据单独协议 struct CMD_S_TingCard { BYTE bPaiQuan; //1表示 当前不是自己的牌权,但是已经听了 BYTE bOutCardCout; //可以打出的牌就听牌的个数 BYTE bOutCardData[MAX_COUNT]; //具体打哪几张牌 BYTE bTingCardCount[MAX_COUNT]; //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 WORD bTingCardData[MAX_COUNT][MAX_TING];//具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 bool ToString(TCHAR* pBuffer, int iLen) { //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; TCHAR tempcard[255*255] = { 0 }; ZeroMemory(tempcard, 255*255 * sizeof(TCHAR)); CString strTmp; CString strAllTmp; if (bOutCardCout != 255) { for (int i = 0; i < bOutCardCout; i++) { strTmp.Format(TEXT("打出 0x%02x 胡牌个数%d "), bOutCardData[i], bTingCardCount[i]); for (int j = 0; j < bTingCardCount[i]; j++) { CString tmp; int cbCard; int cbFan; int cbNum; cbCard = bTingCardData[i][j] & 0x003F; cbFan = (bTingCardData[i][j] & 0x07C0) >> 6; cbNum = (bTingCardData[i][j] & 0xE000) >> 13; tmp.Format(_T("\r\n数据=%08x 牌值=%02x 台数=%d 剩余数量=%d ****"), bTingCardData[i][j], cbCard, cbFan, cbNum); strTmp += tmp; } strAllTmp += strTmp; strAllTmp += TEXT("-------"); } } else { strAllTmp = _T("bOutCardCout =255"); } #ifdef _UNICODE _snwprintf(tempcard, 255 * 255, TEXT("听牌协议->%s"), strAllTmp.GetBuffer()); #else _snprintf(tempcard, 255*255, TEXT("听牌协议->%s"), strAllTmp.GetBuffer()); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; //发送扑克 struct CMD_S_SendCard { BYTE cbCardData; //发牌扑克数据 INT cbActionMask; //动作掩码(0:没操作,0x08:碰牌,0x10:杠,0x80:自摸) WORD cbActionCard[6]; //操作扑克(杠的时候才有数据,多杠时,补杠,暗杠才有数据) WORD wCurrentUser; //当前用户 BYTE bTail; //末尾发牌(0:正常发牌,1:末尾) BYTE bLeftCardCount; //剩余牌数 bool ToString(TCHAR* pBuffer, int iLen) { if (sizeof(CMD_S_SendCard) * 8 > iLen) return false; TCHAR tempcard[2550]; TCHAR sbOutCardData[2550] = { 0 }; ZeroMemory(tempcard, 2550 * sizeof(TCHAR)); ZeroMemory(sbOutCardData, 2550 * sizeof(TCHAR)); #ifdef _UNICODE _snwprintf(pBuffer, iLen, TEXT("派发麻将->麻将数据:0x%x,动作掩码(0没操作 8碰牌 16杠 128自摸):0x%x,当前用户:%d,操作牌值:[0x%x][0x%x][0x%x] 剩余牌数%d") , cbCardData, cbActionMask, wCurrentUser, cbActionCard[0], cbActionCard[1], cbActionCard[2], bLeftCardCount); #else _snwprintf(pBuffer, iLen, TEXT("派发麻将->麻将数据:0x%x,动作掩码(0没操作 8碰牌 16杠 128自摸):0x%x,当前用户:%d,操作牌值:[0x%x][0x%x][0x%x] 剩余牌数%d") , cbCardData, cbActionMask, wCurrentUser, cbActionCard[0], cbActionCard[1], cbActionCard[2],bLeftCardCount); #endif //mylog::ToSet(pBuffer, iLen); return true; } bool SwitchToStringCard(BYTE bData, TCHAR pBuffer[], int iLen) { if (wcslen(pBuffer) > 1980 + iLen) { return false; } BYTE iHuaSe = (bData & 0xF0) >> 4; BYTE bValue = (bData & 0x0F); TCHAR szTemp[8]; ZeroMemory(szTemp, 8 * sizeof(TCHAR)); switch (iHuaSe) { case 0: { switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一万~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二万~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三万~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四万~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五万~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六万~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七万~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八万~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九万~")); break; } default: break; } break; } case 1: switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一条~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二条~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三条~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四条~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五条~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六条~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七条~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八条~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九条~")); break; } default: break; } break; case 2: switch (bValue) { case 1: { StringCchCat(szTemp, 16, _T("一筒~")); break; } case 2: { StringCchCat(szTemp, 16, _T("二筒~")); break; } case 3: { StringCchCat(szTemp, 16, _T("三筒~")); break; } case 4: { StringCchCat(szTemp, 16, _T("四筒~")); break; } case 5: { StringCchCat(szTemp, 16, _T("五筒~")); break; } case 6: { StringCchCat(szTemp, 16, _T("六筒~")); break; } case 7: { StringCchCat(szTemp, 16, _T("七筒~")); break; } case 8: { StringCchCat(szTemp, 16, _T("八筒~")); break; } case 9: { StringCchCat(szTemp, 16, _T("九筒~")); break; } default: break; } break; default: break; } StringCchCat(pBuffer, iLen, szTemp); return true; } }; //操作提示 struct CMD_S_OperateNotify { WORD wResumeUser; //还原用户 INT cbActionMask; //动作掩码() BYTE cbActionCard; //动作扑克 bool ToString(TCHAR* pBuffer, int iLen) { //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; TCHAR tempcard[255] = { 0 }; ZeroMemory(tempcard, 255 * sizeof(TCHAR)); #ifdef _UNICODE _snwprintf(tempcard, 255, TEXT("操作提示->还原用户:%d,动作掩码:0x%x,动作扑克:0x%x"), wResumeUser, cbActionMask, cbActionCard); #else _snprintf(tempcard, 255, TEXT("操作提示->还原用户:%d,动作掩码:0x%x,动作扑克:0x%x") , wResumeUser, cbActionMask, cbActionCard); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; //操作命令 struct CMD_S_OperateResult { WORD wOperateUser; //操作用户 WORD wProvideUser; //供应用户 INT cbOperateCode; //操作代码 BYTE cbOperateCard; //操作扑克 BYTE cbCaiShenCard[4]; //存财神牌 INT cbActionMask; //动作 WORD cbActionCard[6]; //动作牌值 bool ToString(TCHAR* pBuffer, int iLen) { //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; TCHAR tempcard[1024*2] = { 0 }; ZeroMemory(tempcard, 1024 * 2 * sizeof(TCHAR)); #ifdef _UNICODE _snwprintf(tempcard, iLen / sizeof(TCHAR), TEXT("操作命令->操作用户:%d,供应用户:%d,操作代码:0x%x,操作扑克:0x%x,动作掩码:0x%x,动作牌值:[%d][%d][%d][%d][%d][%d]") , wOperateUser, wProvideUser, cbOperateCode, cbOperateCard, cbActionMask, cbActionCard[0], cbActionCard[1], cbActionCard[2], cbActionCard[3], cbActionCard[4], cbActionCard[5]); #else _snwprintf(tempcard, iLen / sizeof(TCHAR), TEXT("操作命令->操作用户:%d,供应用户:%d,操作代码:0x%x,操作扑克:0x%x,动作掩码:0x%x,动作牌值:[%d][%d][%d][%d][%d][%d]") , wOperateUser, wProvideUser, cbOperateCode, cbOperateCard, cbActionMask, cbActionCard[0], cbActionCard[1], cbActionCard[2], cbActionCard[3], cbActionCard[4], cbActionCard[5]); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; //血流game结束 struct CMD_S_XueLiuEnd { BYTE bFinish;//是否结束本轮。0表示否,1表示是 BYTE cbCardData[GAME_PLAYER][MAX_COUNT]; //玩家手牌 BYTE checkHuazhu[GAME_PLAYER]; //默认0 1查叫 2花猪 int checkCoin[GAME_PLAYER]; // 查花猪 或查叫的积分变化值 int DangJu[GAME_PLAYER]; //单局积分 int leftCoin[GAME_PLAYER]; //玩家积分 BYTE winScoreNum; //积分变化次数 BYTE winScoreType[MAX_CHANGE_SCORE]; //类型 BYTE winScoreRate[MAX_CHANGE_SCORE]; //倍数 int winScore[MAX_CHANGE_SCORE]; //分数 BYTE winProvider[MAX_CHANGE_SCORE]; //关连玩家 0表示3家 1下家 2对家 3上家 BYTE winFanType[MAX_CHANGE_SCORE]; //番型 }; //游戏结束 struct CMD_S_GameEnd { BYTE bOptType; //操作类型(1胡牌结束,2黄庄,3解散)1 WORD bWanJiaId; //玩家座位号 3 WORD wDianpao; //点炮玩家 5 BYTE HuPaiCard; //胡的牌 6 BYTE cbCardData[GAME_PLAYER][MAX_COUNT]; //玩家手牌值 62 INT cbWanJiaScore[GAME_PLAYER]; //玩家目前所拥有积分 78 BYTE bZimo[GAME_PLAYER]; //每位玩家胡牌次数 82 BYTE bFinish; //是否结束本轮。0表示否,1表示是 83 DWORD dwOwnerID; //房主ID 87 BYTE bLeftCardCount; //剩余牌数 88 BYTE bLeftCardDada[109]; //剩余牌值 142 为了应对 3人 2人麻将 修改数组 3人96 2人109 BYTE playGameNum; //打到第几局了 143 INT lGameScoreDetail[16 * GAME_PLAYER]; //195流水详情 204 bool ToString(TCHAR* pBuffer, int iLen) { //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; TCHAR tempcard[1024 * 2] = { 0 }; ZeroMemory(tempcard, 1024 * 2 * sizeof(TCHAR)); // CString strUserShouPai; // for (int i = 0; i < GAME_PLAYER;i++) // { // CString strUserPai; // for (int j = 0; j < MAX_COUNT;j++) // { // if (cbCardData[i][j]==0) // { // continue; // } // CString strTmp; // strTmp.Format(_T("%02x,"), cbCardData[i][j]); // strUserPai.Append(strTmp); // } // strUserPai.Append(_T("---|---")); // strUserShouPai.Append(strUserPai); // } // CString strLeftCard; // for (int i = 0; i < sizeof(bLeftCardDada); i++) // { // CString tmp; // tmp.Format(_T("%02x,"), bLeftCardDada[i]); // strLeftCard.Append(tmp); // } // strLeftCard.Append(_T("\r\n")); #ifdef _UNICODE _snwprintf(tempcard, iLen / sizeof(TCHAR), TEXT("游戏结束->玩家剩余分数:%d,%d,%d,%d"), cbWanJiaScore[0], cbWanJiaScore[1], cbWanJiaScore[2], cbWanJiaScore[3] ); #else _snwprintf(tempcard, iLen / sizeof(TCHAR), TEXT("游戏结束->玩家剩余分数:%d,%d,%d,%d"), cbWanJiaScore[0], cbWanJiaScore[1], cbWanJiaScore[2], cbWanJiaScore[3]); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); //OutputDebugString(tempcard); return true; } }; //用户准备 struct CMD_S_Reading { BYTE bReading; WORD wChairID; }; //用户托管 struct CMD_S_Trustee { bool bTrustee; //是否托管 WORD wChairID; //托管用户 }; // struct CMD_S_ChiHu { WORD wChiHuUser; //胡牌玩家 WORD wProviderUser; //放炮人,自己为自摸 BYTE cbChiHuCard; //胡牌数据 int ChrOperator; //胡牌操作码 }; //积分变动 struct CMD_S_GangScore { WORD wChairId; //用户 int cbOperateCode; //操作代码 int lGangScore[GAME_PLAYER]; //单局 积分变动情况 int cbWanJiaScore[GAME_PLAYER]; //玩家目前所拥有积分 bool ToString(TCHAR* pBuffer, int iLen) { TCHAR tempcard[1024 * 2] = { 0 }; ZeroMemory(tempcard, 1024 * 2 * sizeof(TCHAR)); if (wChairId<0 || wChairId >GAME_PLAYER) { _snwprintf(tempcard, iLen / sizeof(TCHAR), TEXT("积分变动->用户id:%d,错误"),wChairId); StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); //OutputDebugString(tempcard); return true; } //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; _snwprintf(tempcard, iLen / sizeof(TCHAR), TEXT("积分变动->用户id:%d,变动原因=0x%x 各玩家计分变动 %d,%d,%d,%d 各玩家目前积分 %d,%d,%d,%d"), wChairId, cbOperateCode, lGangScore[0], lGangScore[1], lGangScore[2], lGangScore[3], cbWanJiaScore[0], cbWanJiaScore[1], cbWanJiaScore[2], cbWanJiaScore[3]); //OutputDebugString(tempcard); StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; struct CMD_S_DIGNQUE { BYTE cbDingQue[GAME_PLAYER]; }; struct CMD_S_HuanSanZhang { BYTE cbSice; BYTE cbCard1[GAME_PLAYER]; BYTE cbCard2[GAME_PLAYER]; BYTE cbCard3[GAME_PLAYER]; WORD wChairID[GAME_PLAYER]; INT cbUserAction; //用户动作(0:没操作,0x08:碰牌,0x10:杠,0x80:自摸等) BYTE ActionCard[3]; //动作所对应的牌 }; ////////////////////////////////////////////////////////////////////////// //S //通知包台 struct CMD_S_BAO_NOTICE { WORD m_wChairID; //选包玩家 BYTE minBao; //可选最小包台数 }; //玩家包台广播 struct CMD_S_BAO_CHOICE { WORD m_wChairID; //包玩家 BYTE baochoice; //包台 255 表示不包 }; //包结果 struct CMD_S_BAO_RESULT { WORD m_wChairID; //包家 BYTE baoTai; //台数 BYTE cbMagicCount; //需要选择财神个数 0 1 2 int actionMask; //无财时 直接可以庄家出牌 需要发送庄家有的操作 仅庄家可见 WORD gangCard[6]; bool ToString(TCHAR* pBuffer, int iLen) { //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; TCHAR tempcard[255] = { 0 }; ZeroMemory(tempcard, 255 * sizeof(TCHAR)); #ifdef _UNICODE _snwprintf(tempcard, 255, TEXT("包台结果->包家ID:%d,包家台数enum:%d 财神个数=%d 操作掩码=0x%x"), m_wChairID, baoTai, cbMagicCount, actionMask); #else _snprintf(tempcard, 255, TEXT("包台结果->包家ID:%d,包家台数enum:%d 财神个数=%d 操作掩码=0x%x"), m_wChairID, baoTai, cbMagicCount, actionMask); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; //财神结果 struct CMD_S_Magic_RESULT { BYTE cbMagicFirst; //财神1 BYTE cbMagicSenced; //财神2 0 表示该财神不需要 int actionMask; //庄家出牌 需要发送庄家有的操作 仅庄家可见 WORD gangCard[6]; bool ToString(TCHAR* pBuffer, int iLen) { //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; TCHAR tempcard[255] = { 0 }; ZeroMemory(tempcard, 255 * sizeof(TCHAR)); #ifdef _UNICODE _snwprintf(tempcard, 255, TEXT("包台结果(设置财神)->财神1=0x%x 财神2=0x%x操作掩码=0x%x"), cbMagicFirst, cbMagicSenced, actionMask); #else _snprintf(tempcard, 255, TEXT("包台结果(设置财神)->财神1=0x%x 财神2=0x%x操作掩码=0x%x"), cbMagicFirst, cbMagicSenced, actionMask); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; // struct CMD_S_DING_CAI_RESULT { byte cbResult; //定财神返回结果 1 有财 2无财神 0 取消 byte cbIsWCHu; BYTE caiCards[MAX_COUNT];////可以被定为财神的牌 最高位用于标示是否可以独选 bool ToString(TCHAR* pBuffer, int iLen) { CString str; for (INT i = 0; i < MAX_COUNT; i++){ if (caiCards[i] == 0) { break; } CString tmp; tmp.Format(_T("%d "), caiCards[i]); str += tmp; } #ifdef _UNICODE _snwprintf(pBuffer, iLen, TEXT("游戏通知->返回结果 %d %d %s ") , cbResult, cbIsWCHu, str); #else _snprintf(pBuffer, iLen, TEXT("游戏通知->返回结果 %d %d %s ") , cbResult, cbIsWCHu, str); #endif return true; } }; ////////////////////////////////////////////////////////////////////////// //游戏回放回放 struct GameRecordPacket { WORD wChairID; WORD wMainCmdID; WORD wSubCmdID; TCHAR wPacket[LEN_RECORD]; WORD wPacketSize; WORD wSize; }; struct ChairRecord { WORD wChairId; //椅子号 UINT32 dwUserId; //用户id TCHAR userName[LEN_NICKNAME];//用户名 TCHAR headUrl[LEN_HEAD_URL]; //头像 }; struct CMD_GR_ReplayRecordResp { UINT32 m_UUID; //回放唯一ID UINT32 m_tableID; //公开桌子号 UINT32 m_startTime; //游戏开始时间 UINT32 m_endTime; //游戏结束时间 UINT32 m_UserId; //用户ID CMD_S_GameConfig m_gameconfig; //游戏基本配置 ChairRecord m_chairList[GAME_PLAYER]; //游戏椅子玩家信息 UINT16 m_recordCount; //回放数据记录数 GameRecordPacket pData[200]; //回放记录列表(尾拖数据) }; ////////////////////////////////////////////////////////////////////////// //客户端命令结构 #define SUB_C_OUT_CARD 1 //出牌命令 #define SUB_C_OPERATE_CARD 3 //操作扑克 #define SUB_C_TRUSTEE 4 //用户托管 #define SUB_C_SELECT_BAO 5 //选择包台 #define SUB_C_REPLAY 6 //回放 #define SUB_C_SELECT_CAI 7 //选择财神 #define SUB_C_DING_CAI 8 //定财神 //出牌命令 struct CMD_C_OutCard { BYTE cbCardData; //扑克数据 }; //操作命令 struct CMD_C_OperateCard { INT cbOperateCode; //操作代码 BYTE cbOperateCard; //操作扑克 BYTE cbCaiShenCard[4]; //存财神牌 bool ToString(TCHAR* pBuffer, int iLen) { //if(sizeof(CMD_S_OperateNotify) * 8 > iLen) return false; TCHAR tempcard[255] = { 0 }; ZeroMemory(tempcard, 255 * sizeof(TCHAR)); #ifdef _UNICODE _snwprintf(tempcard, 255, TEXT("操作命令->操作代码:0x%x,操作扑克:0x%02x"), cbOperateCode, cbOperateCard); #else _snprintf(tempcard, 255, TEXT("操作命令->操作代码:0x%x,操作扑克:0x%02x"), cbOperateCode, cbOperateCard); #endif StringCchCat(pBuffer, iLen / sizeof(TCHAR), tempcard); return true; } }; //用户托管 struct CMD_C_Trustee { bool bTrustee; //是否托管 }; //出牌命令 struct CMD_C_RePlay { UINT32 m_UUID; //回放记录ID }; //包台 struct CMD_C_BAO { BYTE cbTaiNum; //包台 255 表示放弃包台 }; //选财 struct CMD_C_Magic { BYTE cbMagicFirst; //财神1 BYTE cbMagicSenced; //财神2 0 表示该财神不需要 }; //定财神 struct CMD_C_DING_CAI { BYTE isdingcai; //1定 0 取消 }; struct CMD_S_NOTIFY_QIANGGH { WORD wResumeUser; //还原用户 int cbActionMask; //动作掩码 byte cbActionCard; //动作扑克 BYTE caiCards[2]; }; ////////////////////////////////////////////////////////////////////////// #pragma pack() #endif