#include "StdAfx.h" #include "TableFrame.h" #include "DataBasePacket.h" #include "AttemperEngineSink.h" #include "..\..\..\Games\Normal\松滋晃晃血流\消息定义\CMD_Sparrow.h" #include "BaiDuMap.h" #include "../../MessageDef/Pb_UserInfo.pb.h" #include "../../MessageDef/Pb_GameInfo.pb.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ////////////////////////////////////////////////////////////////////////////////// //断线定义 #define IDI_OFF_LINE (TIME_TABLE_SINK_RANGE+1) //断线标识 #define MAX_OFF_LINE 3 //断线次数 #define TIME_OFF_LINE 60000L //断线时间 #define TIME_CREATE_OUT 60000 * 30L //15分钟后检测牌桌状态 #define TIME_OFF_STARTED 60000 * 120 //2个小时后检测牌桌状态 //开始超时 #define IDI_START_OVERTIME (TIME_TABLE_SINK_RANGE+2) //开始超时 #define IDI_START_OVERTIME_END (TIME_TABLE_SINK_RANGE+22) //开始超时 #define IDI_START_DISMISS_PRIVATE (TIME_TABLE_SINK_RANGE+50) //解散桌子消息 #define IDI_START_TIME (TIME_TABLE_SINK_RANGE+150) //牌桌开始计时 #define IDI_STARTED_TIME (TIME_TABLE_SINK_RANGE+161) //牌桌开始计时,开始后的计时 #define IDI_TABLE_TIME 200 //牌桌模块计时 #ifndef _DEBUG #define TIME_OVERTIME 15000L #define TIME_DISMISS_PRIVATE 2 * 60 * 1000L //超时时间 1分钟 #else #define TIME_OVERTIME 15000L #define TIME_DISMISS_PRIVATE 60000 * 2L //超时时间 1分钟 #endif ////////////////////////////////////////////////////////////////////////////////// //游戏记录 CGameScoreRecordArray CTableFrame::m_GameScoreRecordBuffer; ////////////////////////////////////////////////////////////////////////////////// //构造函数 CTableFrame::CTableFrame() { w_SendChairID = 65535; //固有属性 m_wTableID = 0; m_wChairCount = 0; m_cbStartMode = START_MODE_ALL_READY; m_wUserCount = 0; m_wStartCount = 0; m_bJieSan = false; //标志变量 m_iLastDismissVoteTime = 0; m_bDismissVoteStarted = false; m_bGameStarted = false; m_bDrawStarted = false; m_bTableStarted = false; m_bTableInitFinish = false; ZeroMemory(&m_bAllowLookon, sizeof(m_bAllowLookon)); ZeroMemory(&m_lFrozenedScore, sizeof(m_lFrozenedScore)); ZeroMemory(&m_jgrUserLockData, sizeof(m_jgrUserLockData)); ZeroMemory(m_GameRead, sizeof(bool) * MAX_CHAIR); //游戏变量 m_lCellScore = 0L; m_cbGameStatus = GAME_STATUS_FREE; m_wDrawCount = 0; //时间变量 m_dwDrawStartTime = 0L; ZeroMemory(&m_SystemTimeStart, sizeof(m_SystemTimeStart)); //回放记录 m_ReplayRecordData = NULL; m_ReplayRecordDataSize = 0; //动态属性 m_dwTableOwnerID = 0L; m_wPrivateTableOwnerID = 0L; ZeroMemory(m_szEnterPassword, sizeof(m_szEnterPassword)); //断线变量 ZeroMemory(m_wOffLineCount, sizeof(m_wOffLineCount)); ZeroMemory(m_dwOffLineTime, sizeof(m_dwOffLineTime)); //配置信息 m_pGameParameter = NULL; m_pGameServiceAttrib = NULL; m_pGameServiceOption = NULL; ZeroMemory(&mGameConfig, sizeof(mGameConfig)); //组件接口 m_pITimerEngine = NULL; m_pITableFrameSink = NULL; m_pIMainServiceFrame = NULL; m_pIAndroidUserManager = NULL; //扩张接口 m_pITableUserAction = NULL; m_pITableUserRequest = NULL; m_pIMatchTableAction = NULL; //数据接口 m_pIKernelDataBaseEngine = NULL; m_pIRecordDataBaseEngine = NULL; //比赛接口 m_pITableFrameHook = NULL; //用户数组 ZeroMemory(m_TableUserItemArray, sizeof(m_TableUserItemArray)); m_wPrivateTablParentNodeID = 0; m_dwClubID = 0; m_wTableKind = 0; wXianZhi = 0; ZeroMemory(m_GameShuffleRead, sizeof(bool) * MAX_CHAIR); return; } //析构函数 CTableFrame::~CTableFrame() { //释放对象 SafeRelease(m_pITableFrameSink); SafeRelease(m_pITableFrameHook); return; } //接口查询 VOID * CTableFrame::QueryInterface(REFGUID Guid, DWORD dwQueryVer) { QUERYINTERFACE(ITableFrame, Guid, dwQueryVer); QUERYINTERFACE(ICompilationSink, Guid, dwQueryVer); QUERYINTERFACE_IUNKNOWNEX(ITableFrame, Guid, dwQueryVer); return NULL; } USHORT CTableFrame::GetNeedPayCxz() { USHORT uRet = 0; CString juShuCfg; CString payCoinCfg; juShuCfg = m_pGameParameter->msParameter[2].juShuCfg; payCoinCfg = m_pGameParameter->msParameter[2].payCoinCfg; CList list1; CList list2; int pos = juShuCfg.Find(_T('#')); int i = 0; while (pos != -1) { CString field = juShuCfg.Left(pos); int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); i++; juShuCfg = juShuCfg.Right(juShuCfg.GetLength() - pos - 1); pos = juShuCfg.Find(_T('#')); } if (juShuCfg.GetLength() > 0) { int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); } pos = payCoinCfg.Find(_T('#')); i = 0; while (pos != -1) { CString field = payCoinCfg.Left(pos); int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); i++; payCoinCfg = payCoinCfg.Right(payCoinCfg.GetLength() - pos - 1); pos = payCoinCfg.Find(_T('#')); } if (payCoinCfg.GetLength() > 0) { int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); } bool bFind = false; int iNum = 0; int iCount = list1.GetCount(); for (int var = 0; var < iCount; var++) { int iRet = list1.GetAt(list1.FindIndex(var)); if (iRet == mGameConfig.wPlayCountRule) { bFind = true; iNum = var; break; } } if (!bFind) { return 0XFF; } if (NULL == list2.FindIndex(iNum)) { return 0XFF; } int iBao = list2.GetAt(list2.FindIndex(iNum)); return iBao; } //此局总共需要多少元宝 USHORT CTableFrame::GetNeedPay() { USHORT uRet = 0; CString juShuCfg; CString payCoinCfg; juShuCfg = m_pGameParameter->msParameter[0].juShuCfg; payCoinCfg = m_pGameParameter->msParameter[0].payCoinCfg; CList list1; CList list2; int pos = juShuCfg.Find(_T('#')); int i = 0; while (pos != -1) { CString field = juShuCfg.Left(pos); int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); i++; juShuCfg = juShuCfg.Right(juShuCfg.GetLength() - pos - 1); pos = juShuCfg.Find(_T('#')); } if (juShuCfg.GetLength() > 0) { int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); } pos = payCoinCfg.Find(_T('#')); i = 0; while (pos != -1) { CString field = payCoinCfg.Left(pos); int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); i++; payCoinCfg = payCoinCfg.Right(payCoinCfg.GetLength() - pos - 1); pos = payCoinCfg.Find(_T('#')); } if (payCoinCfg.GetLength() > 0) { int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); } bool bFind = false; int iNum = 0; int iCount = list1.GetCount(); for (int var = 0; var < iCount; var++) { int iRet = list1.GetAt(list1.FindIndex(var)); if (iRet == mGameConfig.wPlayCountRule) { bFind = true; iNum = var; break; } } if (!bFind) { return 0XFF; } if (NULL == list2.FindIndex(iNum)) { return 0XFF; } int iBao = list2.GetAt(list2.FindIndex(iNum)); return iBao; } //此局总共需要多少元宝 USHORT CTableFrame::GetNeedPayZhiPai() { USHORT uRet = 0; CString juShuCfg; CString payCoinCfg; juShuCfg = m_pGameParameter->msParameter[3].juShuCfg; payCoinCfg = m_pGameParameter->msParameter[3].payCoinCfg; CList list1; CList list2; int pos = juShuCfg.Find(_T('#')); int i = 0; while (pos != -1) { CString field = juShuCfg.Left(pos); int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); i++; juShuCfg = juShuCfg.Right(juShuCfg.GetLength() - pos - 1); pos = juShuCfg.Find(_T('#')); } if (juShuCfg.GetLength() > 0) { int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); } pos = payCoinCfg.Find(_T('#')); i = 0; while (pos != -1) { CString field = payCoinCfg.Left(pos); int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); i++; payCoinCfg = payCoinCfg.Right(payCoinCfg.GetLength() - pos - 1); pos = payCoinCfg.Find(_T('#')); } if (payCoinCfg.GetLength() > 0) { int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); } bool bFind = false; int iNum = 0; int iCount = list1.GetCount(); for (int var = 0; var < iCount; var++) { int iRet = list1.GetAt(list1.FindIndex(var)); if (iRet == mGameConfig.wPlayCountRule) { bFind = true; iNum = var; break; } } if (!bFind) { return 0XFF; } if (NULL == list2.FindIndex(iNum)) { return 0XFF; } int iBao = list2.GetAt(list2.FindIndex(iNum)); return iBao; } //此局总共需要多少元宝 USHORT CTableFrame::GetNeedPayEx() { USHORT uRet = 0; CString juShuCfg; CString payCoinCfg; juShuCfg = m_pGameParameter->msParameter[1].juShuCfg; payCoinCfg = m_pGameParameter->msParameter[1].payCoinCfg; CList list1; CList list2; int pos = juShuCfg.Find(_T('#')); int i = 0; while (pos != -1) { CString field = juShuCfg.Left(pos); int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); i++; juShuCfg = juShuCfg.Right(juShuCfg.GetLength() - pos - 1); pos = juShuCfg.Find(_T('#')); } if (juShuCfg.GetLength() > 0) { int iRet = _wtoi(juShuCfg.GetBuffer(0)); list1.AddTail(iRet); juShuCfg.ReleaseBuffer(); } pos = payCoinCfg.Find(_T('#')); i = 0; while (pos != -1) { CString field = payCoinCfg.Left(pos); int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); i++; payCoinCfg = payCoinCfg.Right(payCoinCfg.GetLength() - pos - 1); pos = payCoinCfg.Find(_T('#')); } if (payCoinCfg.GetLength() > 0) { int iRet = _wtoi(payCoinCfg.GetBuffer(0)); list2.AddTail(iRet); payCoinCfg.ReleaseBuffer(); } bool bFind = false; int iNum = 0; int iCount = list1.GetCount(); for (int var = 0; var < iCount; var++) { int iRet = list1.GetAt(list1.FindIndex(var)); if (iRet == mGameConfig.wPlayCountRule) { bFind = true; iNum = var; break; } } if (!bFind) { return 0XFF; } if (NULL == list2.FindIndex(iNum)) { return 0XFF; } int iBao = list2.GetAt(list2.FindIndex(iNum)); return iBao; } //开始游戏 bool CTableFrame::StartGame() { //游戏状态 ASSERT(m_bDrawStarted == false); if (m_bDrawStarted == true) return false; //保存变量 bool bGameStarted = m_bGameStarted; bool bTableStarted = m_bTableStarted; //设置状态 m_bGameStarted = true; m_bDrawStarted = true; m_bTableStarted = true; //自增游戏开始次数 m_wStartCount++; KillGameTimer(IDI_START_TIME);//关闭创建超时定时器。 //开始时间 GetLocalTime(&m_SystemTimeStart); m_dwDrawStartTime = (DWORD)time(NULL); /*if (nullptr !=m_ReplayRecordData) { delete [] m_ReplayRecordData; m_ReplayRecordData = nullptr; }*/ if (!m_sPrivateTableID.empty() && 1 == m_wStartCount) { SetGameTimer(IDI_STARTED_TIME, TIME_OFF_STARTED, 1, 0); //私有房间,需要记录一个总数据 tagScoreInfo* ScoreInfoArray = new tagScoreInfo[m_wChairCount]; ZeroMemory(ScoreInfoArray, sizeof(tagScoreInfo)*m_wChairCount); //初始时生成一个父节点房间记录。 for (int i = 0; i < m_wChairCount; ++i) ScoreInfoArray[i].cbType = SCORE_TYPE_START; WriteTableScore(ScoreInfoArray, m_wChairCount); RecordGameScore(m_bDrawStarted); if (ScoreInfoArray != NULL) { //内存泄露 delete[] ScoreInfoArray; ScoreInfoArray = NULL; } } //开始设置 if (bGameStarted == false) { //状态变量 ZeroMemory(m_wOffLineCount, sizeof(m_wOffLineCount)); ZeroMemory(m_dwOffLineTime, sizeof(m_dwOffLineTime)); //设置用户 for (WORD i = 0; ilServiceScore>0L) { m_lFrozenedScore[i] = m_pGameServiceOption->lServiceScore; pIServerUserItem->FrozenedUserScore(m_pGameServiceOption->lServiceScore); } //设置状态 BYTE cbUserStatus = pIServerUserItem->GetUserStatus(); if ((cbUserStatus != US_OFFLINE) && (cbUserStatus != US_PLAYING)) pIServerUserItem->SetUserStatus(US_PLAYING, m_wTableID, i); } } //发送状态 if (bTableStarted != m_bTableStarted) SendTableStatus(); } //比赛通知 bool bStart = true; if (m_pITableFrameHook != NULL) bStart = m_pITableFrameHook->OnEventGameStart(this, m_wChairCount); //通知事件 ASSERT(m_pITableFrameSink != NULL); if (m_pITableFrameSink != NULL) m_pITableFrameSink->OnEventGameStart(); //通知调度引擎 CAttemperEngineSink * pAttemperEngineSink = (CAttemperEngineSink *)m_pIMainServiceFrame; pAttemperEngineSink->UpdataTableJushu(_ttol(this->GetPrivateTableID().c_str()), this->m_wStartCount); return true; } //解散游戏 bool CTableFrame::DismissGame() { //状态判断 /*ASSERT(m_bTableStarted == true); if (m_bTableStarted == false) return false;*/ //结束游戏 m_bJieSan = true; return DeletePrivateResult(2, TEXT("此房间已经被群主解散!")); } //结束游戏 bool CTableFrame::ConcludeGame(BYTE cbGameStatus, bool bSendState) { CAttemperEngineSink * pAttemperEngineSink = (CAttemperEngineSink *)m_pIMainServiceFrame; //效验状态 if (cbGameStatus == GAME_STATUS_DELETE) { //if (m_wTableKind == 1) //{ // WriteXianLiaoTableRecord();//推送闲聊机器人数据 //} //删除桌子 if (m_wPrivateTablParentNodeID > 0) { RecordGameScore(true, INVALID_TABLE, true); } //变量定义 WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = NULL; for (WORD i = 0; i < m_wChairCount; i++) { //IServerUserItem * pIServerUserItem = GetTableUserItem(i); pIServerUserItem = GetTableUserItem(i); if (pIServerUserItem == NULL) continue; //添加校验 if (pIServerUserItem->GetTableID() != this->GetTableID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("发现异常:ConcludeGame:玩家桌子ID和桌子ID不匹配[ UserTableID=%ld,TableID= %ld, PrivateTableId= %ld ]"), pIServerUserItem->GetTableID(), this->GetTableID(), _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); continue; } PerformStandUpAction(pIServerUserItem, false, bSendState); //pAttemperEngineSink->SetUserServerID(pIServerUserItem, 0); } //旁观用户 起立动作,将其用户状态更新 do { pIServerUserItem = EnumLookonUserItem(0); if (pIServerUserItem == NULL) break; //添加校验 if (pIServerUserItem->GetTableID() != this->GetTableID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("发现异常:ConcludeGame:玩家桌子ID和桌子ID不匹配[ UserTableID=%ld,TableID= %ld, PrivateTableId= %ld ]"), pIServerUserItem->GetTableID(), this->GetTableID(), _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); continue; } PerformStandUpAction(pIServerUserItem, false, bSendState); } while (pIServerUserItem != NULL); return true; } if (m_bGameStarted == false) return false; //保存变量 bool bDrawStarted = m_bDrawStarted; //设置状态 m_bDrawStarted = false; m_cbGameStatus = cbGameStatus; m_bGameStarted = (cbGameStatus >= GAME_STATUS_PLAY) ? true : false; m_wDrawCount++; ZeroMemory(m_GameRead, sizeof(bool) * MAX_CHAIR); //游戏中准备取消 ZeroMemory(m_GameShuffleRead, sizeof(bool) * MAX_CHAIR); if (m_wStartCount == 1 && m_bJieSan) { //解散的方式结束 } else if (m_wStartCount == 1 && !m_bJieSan) { //扣费 把锁定费用扣出 bool bFind = false; for (int i = 0; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] != NULL && m_TableUserItemArray[i]->GetUserID() == m_wPrivateTableOwnerID) { bFind = true; break; } } //如果是均摊扣费的情况 if (mGameConfig.wMaxFanRule == 1) { if (bFind) { //房间创建人参与打牌的情况 全部扣费 for (int i = 0; i < 6; i++) { this->ReduceBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); } for (int i = 0; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] != NULL && m_TableUserItemArray[i]->GetUserID() != m_wPrivateTableOwnerID) { if (mGameConfig.wSubGameID >= 10 && mGameConfig.wSubGameID < 13) { int iNeed = 1; iNeed = GetNeedPayEx(); if (iNeed == 255) { iNeed = 8; ASSERT(false); } NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), iNeed / 4); } else if (mGameConfig.wSubGameID >= 14 && mGameConfig.wSubGameID < 17) { int iNeed = 1; iNeed = GetNeedPayZhiPai(); if (iNeed == 255) { iNeed = 8; ASSERT(false); } NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), iNeed / 3); } else if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) { int iNeed = 1; iNeed = GetNeedPayCxz(); if (iNeed == 255) { iNeed = 6; ASSERT(false); } //戳瞎子 NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), iNeed / 3); } else { int iNeed = 1; iNeed = GetNeedPay(); if (iNeed == 255) { iNeed = 8; ASSERT(false); } NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), iNeed / 4); } } } } else { // 返还房主冻结金额 冻结在桌上玩的四人 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User == m_wPrivateTableOwnerID) { this->UnLockBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); } } for (int i = 0; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] != NULL && m_TableUserItemArray[i]->GetUserID() != m_wPrivateTableOwnerID) { if (mGameConfig.wSubGameID >= 10 && mGameConfig.wSubGameID < 13) { int iNeed = 1; iNeed = GetNeedPayEx(); if (iNeed == 255) { iNeed = 8; ASSERT(false); } NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), iNeed / 4); } else if (mGameConfig.wSubGameID >= 14 && mGameConfig.wSubGameID < 17) { int iNeed = 1; iNeed = GetNeedPayZhiPai(); if (iNeed == 255) { iNeed = 6; ASSERT(false); } NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), iNeed / 3); } else if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) { int iNeed = 1; iNeed = GetNeedPayCxz(); if (iNeed == 255) { iNeed = 6; ASSERT(false); } //戳瞎子 NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), (iNeed / 3)); } else { int iNeed = 1; iNeed = GetNeedPay(); if (iNeed == 255) { iNeed = 8; ASSERT(false); } NowReduceBeans(m_TableUserItemArray[i]->GetUserID(), iNeed / 4); } } } } } else { //房主支付 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { this->ReduceBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); } } } //俱乐部游戏记录 WriteClubTableRecord(); } //游戏积分记录 RecordGameScore(bDrawStarted); //结束设置 if (m_bGameStarted == false) { //变量定义 bool bOffLineWait = false; //设置用户 for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(i); //用户处理 if (pIServerUserItem != NULL) { tagTimeInfo* TimeInfo = pIServerUserItem->GetTimeInfo(); //游戏时间 DWORD dwCurrentTime = (DWORD)time(NULL); TimeInfo->dwEndGameTimer = dwCurrentTime; //解锁游戏币 if (m_lFrozenedScore[i] != 0L) { pIServerUserItem->UnFrozenedUserScore(m_lFrozenedScore[i]); m_lFrozenedScore[i] = 0L; } //设置状态 if (pIServerUserItem->GetUserStatus() == US_OFFLINE) { //断线处理 /*bOffLineWait = true; if (m_pGameServiceOption->wServerType != GAME_GENRE_MATCH) { PerformStandUpAction(pIServerUserItem); } else {*/ // 修改 BY JN 如果是断线,牌局打完了,则把他的状态设置为游戏中等待。 pIServerUserItem->SetClientReady(false); pIServerUserItem->SetUserStatus(US_PLAYINGWAIT, m_wTableID, i); /*}*/ } else { //设置状态 pIServerUserItem->SetUserStatus(US_PLAYINGWAIT, m_wTableID, i); } } } //删除时间 if (bOffLineWait == true) KillGameTimer(IDI_OFF_LINE); } //通知比赛 if (m_pITableFrameHook != NULL) m_pITableFrameHook->OnEventGameEnd(this, 0, NULL, cbGameStatus); //重置桌子 ASSERT(m_pITableFrameSink != NULL); if (m_pITableFrameSink != NULL) m_pITableFrameSink->RepositionSink(); //踢出检测 if (m_bGameStarted == false) { for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 if (m_TableUserItemArray[i] == NULL) continue; IServerUserItem * pIServerUserItem = m_TableUserItemArray[i]; //积分限制 if ((m_pGameServiceOption->lMinTableScore != 0L) && (pIServerUserItem->GetUserScore() < m_pGameServiceOption->lMinTableScore)) { //构造提示 TCHAR szDescribe[128] = TEXT(""); if (m_pGameServiceOption->wServerType&GAME_GENRE_GOLD) { _sntprintf(szDescribe, CountArray(szDescribe), TEXT("您的游戏币少于 ") SCORE_STRING TEXT(",不能继续游戏!"), m_pGameServiceOption->lMinTableScore); } else { _sntprintf(szDescribe, CountArray(szDescribe), TEXT("您的游戏积分少于 ") SCORE_STRING TEXT(",不能继续游戏!"), m_pGameServiceOption->lMinTableScore); } //发送消息 //if (pIServerUserItem->IsAndroidUser() == true) //SendGameMessage(pIServerUserItem, szDescribe, SMT_CHAT | SMT_CLOSE_GAME | SMT_CLOSE_ROOM | SMT_EJECT); //else //SendGameMessage(pIServerUserItem, szDescribe, SMT_CHAT | SMT_CLOSE_GAME | SMT_EJECT); //用户起立 PerformStandUpAction(pIServerUserItem); continue; } //关闭判断 if ((CServerRule::IsForfendGameEnter(m_pGameServiceOption->dwServerRule) == true) && (pIServerUserItem->GetMasterOrder() == 0)) { //发送消息 LPCTSTR pszMessage = TEXT("由于系统维护,当前游戏桌子禁止用户继续游戏!"); SendGameMessage(pIServerUserItem, pszMessage, SMT_TABLE_EXIT); //用户起立 PerformStandUpAction(pIServerUserItem,false, true); continue; } //机器起立 if (pIServerUserItem->GetUserStatus() != US_OFFLINE && (m_pGameServiceOption->wServerType&GAME_GENRE_MATCH) == 0) { //机器处理 if (pIServerUserItem->IsAndroidUser() == true) { //绑定信息 CAttemperEngineSink * pAttemperEngineSink = (CAttemperEngineSink *)m_pIMainServiceFrame; tagBindParameter * pBindParameter = pAttemperEngineSink->GetBindParameter(pIServerUserItem->GetBindIndex()); //查找机器 IAndroidUserItem * pIAndroidUserItem = m_pIAndroidUserManager->SearchAndroidUserItem(pIServerUserItem->GetUserID(), pBindParameter->dwSocketID); if (pIAndroidUserItem == NULL) continue; //离开判断 if (pIAndroidUserItem->JudgeAndroidActionAndRemove(ANDROID_WAITLEAVE)) { //起立处理 PerformStandUpAction(pIServerUserItem); continue; } //起立判断 if (pIAndroidUserItem->JudgeAndroidActionAndRemove(ANDROID_WAITSTANDUP)) { //起立处理 PerformStandUpAction(pIServerUserItem); continue; } } } if (m_sPrivateTableID.empty()) {//公共房间开启准备超时定时器。 if (IsGameStarted() == false && pIServerUserItem->IsMobileUser() && m_pGameServiceAttrib->wChairCount < MAX_CHAIR) SetGameTimer(IDI_START_OVERTIME + i, TIME_OVERTIME, 1, i); } } } //结束桌子 ConcludeTable(); //发送状态 //SendTableStatus(); return true; } //房主在未开始游戏前,请求解散牌桌 bool CTableFrame::SetTableFree() { if (GetStartCount() > 0) { //SendGameMessage(SearchUserItem(m_wPrivateTableOwnerID), TEXT("游戏已经开始,无法解散!"), SMT_EJECT); return false; } //分别请桌上的用户离开 for (int i = 0; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] != NULL && m_TableUserItemArray[i]->GetUserID() != m_wPrivateTableOwnerID) { //发送消息 SendGameMessage(m_TableUserItemArray[i], TEXT("此房间已经被房主解散了!"), SMT_TABLE_EXIT); //先请其他人离开 //如果发现该玩家的桌子索引和本桌子索引不一致 if (m_TableUserItemArray[i]->GetTableID() != this->GetTableID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("发现异常:SetTableFree1:用户ID不匹配[ userTableID=%ld,TableID=%ld,PrivateTableID = %ld ]"), m_TableUserItemArray[i]->GetUserInfo()->wTableID, this->GetTableID(), _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); } PerformStandUpAction(m_TableUserItemArray[i], false, true); } } //分别请桌上旁观用户离开 for (INT_PTR i = 0; i < m_LookonUserItemArray.GetCount(); i++) { if (m_LookonUserItemArray[i] != NULL && m_LookonUserItemArray[i]->GetUserID() != m_wPrivateTableOwnerID) { //发送消息 SendGameMessage(m_LookonUserItemArray[i], TEXT("此房间已经被房主解散了!"), SMT_TABLE_EXIT); //请旁观的人离开 if (m_LookonUserItemArray[i]->GetTableID() != this->GetTableID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("发现异常:SetTableFree2:用户ID不匹配[ userTableID=%ld,TableID=%ld,PrivateTableID = %ld ]"), m_LookonUserItemArray[i]->GetUserInfo()->wTableID, this->GetTableID(), _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); } PerformStandUpAction(m_LookonUserItemArray[i], false, true); } } //返还房主冻结元宝 UnAdminLockBeans(); IServerUserItem * pIServerUserItem = SearchUserItem(m_wPrivateTableOwnerID); if (pIServerUserItem != NULL) { //请房主离开 SendGameMessage(pIServerUserItem, TEXT("此房间已经解散了!"), SMT_TABLE_EXIT); if (pIServerUserItem->GetTableID() != this->GetTableID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("发现异常:SetTableFree3:用户ID不匹配[ userTableID=%ld,TableID=%ld,PrivateTableID = %ld ]"), pIServerUserItem->GetUserInfo()->wTableID, this->GetTableID(), _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); } //请旁观的人离开 PerformStandUpAction(pIServerUserItem, false, true); } KillGameTimer(IDI_START_TIME); //删除房间 return DeletePrivateTableNow(); } //++交换座位 bool CTableFrame::SwapChair() { IServerUserItem * pISrcUserItem[4] = { NULL }; for (int i = 0; i < 4; i++) { if (m_TableUserItemArray[i]) { pISrcUserItem[i] = m_TableUserItemArray[i]; } } for (int i = 0; i < 4; i++) { if (pISrcUserItem[i]) { m_TableUserItemArray[pISrcUserItem[i]->GetChairID()] = pISrcUserItem[i]; } } return true; } //私有桌子号码 bool CTableFrame::GetPrivateTableID(TCHAR *pTableID, DWORD dLen) { int iLen = m_sPrivateTableID.length(); if (dLen>iLen) { StringCchCopy(pTableID, dLen, m_sPrivateTableID.c_str()); } return true; } //结束桌子 bool CTableFrame::ConcludeTable() { //结束桌子 if ((m_bGameStarted == false) && (m_bTableStarted == true)) { //人数判断 WORD wTableUserCount = GetSitUserCount(); if (wTableUserCount == 0) m_bTableStarted = false; if (m_pGameServiceAttrib->wChairCount == MAX_CHAIR) m_bTableStarted = false; //模式判断 if (m_cbStartMode == START_MODE_FULL_READY) m_bTableStarted = false; if (m_cbStartMode == START_MODE_PAIR_READY) m_bTableStarted = false; if (m_cbStartMode == START_MODE_ALL_READY) m_bTableStarted = false; } return true; } bool CTableFrame::DeletePrivateTableReq(IServerUserItem * pIUserItem, CMD_GR_DELETE_PRIVATE_ROOM_REQ req) { if (m_bDismissVoteStarted) return true; auto now = time(0); /* #ifdef DEBUG if (now - m_iLastDismissVoteTime < 10) #else if (now - m_iLastDismissVoteTime < 30) #endif { LPCTSTR pszMessage = TEXT("申请解散私有桌子,最少间隔30秒!请稍后再试。"); SendRequestFailure(pIUserItem, pszMessage, 0); return false; }*/ w_SendChairID = pIUserItem->GetChairID(); m_iLastDismissVoteTime = now; m_bDismissVoteStarted = true; req.leftTime = TIME_DISMISS_PRIVATE /1000; m_AgreeDeletePriTableUsers[pIUserItem->GetUserID()] = 1; //在房间中广播 申请消息 for (WORD i = 0; i < m_wChairCount; i++) { IServerUserItem * pIServerUserItem = GetTableUserItem(i); if (pIServerUserItem == NULL) continue; UserInfo::PB_CS_C_DELETE_PRIVATE_ROOM_REQ RoomReq; RoomReq.set_wtableid(req.wTableID); RoomReq.set_wchairid(req.wChairID); RoomReq.set_lefttime(req.leftTime); //发送数据 std::string pbdata = RoomReq.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_REQ, (void*)pbdata.c_str(), pbdata.length()); } WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = EnumLookonUserItem(wEnumIndex++); while (pIServerUserItem) { UserInfo::PB_CS_C_DELETE_PRIVATE_ROOM_REQ RoomReq; RoomReq.set_wtableid(req.wTableID); RoomReq.set_wchairid(req.wChairID); RoomReq.set_lefttime(req.leftTime); //发送数据 std::string pbdata = RoomReq.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_REQ, (void*)pbdata.c_str(), pbdata.length()); pIServerUserItem = EnumLookonUserItem(wEnumIndex++); } //默认此用户同意 SetGameTimer(IDI_START_DISMISS_PRIVATE, TIME_DISMISS_PRIVATE, 1, m_wTableID); if (m_pIMainServiceFrame->IsJC(8888)) { //输出信息 TCHAR szBuffer[128] = TEXT(""); TCHAR szTemp[32] = { 0 }; this->GetPrivateTableID(szTemp, 32); _sntprintf(szBuffer, CountArray(szBuffer), TEXT("定时器开启 ID [ %d ], 桌号 [ %d ], 好友房标识 [ %d ]."), IDI_START_DISMISS_PRIVATE, m_wTableID, szTemp); //输出信息 CTraceService::TraceString(szBuffer, TraceLevel_Normal); } return true; } //设置冻结金额 bool CTableFrame::SetUserLockData(DWORD dwUserID, DWORD dwNum) { int iFirst = 0; int i = 0; for ( i = 0; i < 5; i++) { DWORD dwTemp = m_jgrUserLockData[i].User; //ASSERT(dwTemp != dwUserID); if (dwTemp == dwUserID) { m_jgrUserLockData[i].dwLockNum = dwNum; m_jgrUserLockData[i].User = dwUserID; return true; } if (dwTemp == 0) { iFirst = i; break; } } if (iFirst<=4) { m_jgrUserLockData[iFirst].dwLockNum = dwNum; m_jgrUserLockData[iFirst].User = dwUserID; return true; } return false; } //获取冻结金额 DWORD CTableFrame::GetUserLockData(DWORD dwUserID) { DWORD dwRet = 0; for (int i = 0; i < 5; i++) { DWORD dwTemp = m_jgrUserLockData[i].User; if (dwTemp == dwUserID) { dwRet = m_jgrUserLockData[i].dwLockNum; break; } } return dwRet; } //踢出所有玩家,并删除桌子 bool CTableFrame::DeletePrivateTableResp(IServerUserItem * pIUserItem, BYTE bAgree, bool bSendMe) { if (m_sPrivateTableID.empty()) return false; if (!m_bDismissVoteStarted) return true; if (m_bJieSan) return true; auto dwUserID = pIUserItem->GetUserID(); auto iter = m_AgreeDeletePriTableUsers.find(dwUserID); if (iter!=m_AgreeDeletePriTableUsers.end()) return true; int RealPlayerCount = 0; if (bAgree == 1) //同意 { m_AgreeDeletePriTableUsers[dwUserID] = 1; } else if (bAgree == 2) //拒绝 { m_AgreeDeletePriTableUsers[dwUserID] = 2; } CMD_GR_DELETE_PRIVATE_ROOM_RESP req; req.wTableID = m_wTableID; req.wChairID = pIUserItem->GetChairID(); req.bAgree = bAgree; for (WORD i = 0; i < m_wChairCount; i++) { IServerUserItem * pIServerUserItem = GetTableUserItem(i); if (pIServerUserItem == NULL) continue; RealPlayerCount++; if (bSendMe) continue; UserInfo::PB_CS_C_DELETE_PRIVATE_ROOM_RESP RoomResp; RoomResp.set_wtableid(req.wTableID); RoomResp.set_wchairid(req.wChairID); RoomResp.set_bagree(req.bAgree); //发送数据 std::string pbdata = RoomResp.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_RESP, (void*)pbdata.c_str(), pbdata.length()); } WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = EnumLookonUserItem(wEnumIndex++); while (pIServerUserItem) { UserInfo::PB_CS_C_DELETE_PRIVATE_ROOM_RESP RoomResp; RoomResp.set_wtableid(req.wTableID); RoomResp.set_wchairid(req.wChairID); RoomResp.set_bagree(req.bAgree); //发送数据 std::string pbdata = RoomResp.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_RESP, (void*)pbdata.c_str(), pbdata.length()); pIServerUserItem = EnumLookonUserItem(wEnumIndex++); } std::unordered_map::iterator iter_ = m_AgreeDeletePriTableUsers.begin(); int iNum = 0; int iNone = 0; for (int i = 0; i < m_AgreeDeletePriTableUsers.size(); i++) { if (iter_->second == 1) iNum++; //同意解散 else if (iter_->second == 2) iNone++;//拒绝解散 iter_++; } //if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) //{ // //戳瞎子 // if (iNone >= 1) // { // DeletePrivateResult(0, TEXT("有玩家反对,不能解散房间.")); // return true; // } // else // { // if (iNum == 3) // { // m_bJieSan = true; // return DeletePrivateResult(1, TEXT("所有玩家同意,房间已成功解散!")); // } // } //} //else { //if (iNone >= 2) if (iNone >= 1) { DeletePrivateResult(0, TEXT("根据少数服从多数的原则,不能解散房间.")); return true; } else { //if (iNum > m_wChairCount - 2) if (iNum > m_wChairCount - 1) { m_bJieSan = true; return DeletePrivateResult(1, TEXT("根据少数服从多数的原则,房间已成功解散!")); } if (iNum == RealPlayerCount) { m_bJieSan = true; return DeletePrivateResult(1, TEXT("全部玩家同意解散,房间已成功解散!")); } } } return true; } bool CTableFrame::DeletePrivateTableNow() { if (m_sPrivateTableID.empty()) return false; KillGameTimer(IDI_STARTED_TIME); return m_pIMainServiceFrame->DeletePrivateTable(this); } bool CTableFrame::DeletePrivateResult(USHORT uState, LPCTSTR szDescription) { CMD_GR_DELETE_PRIVATE_ROOM_RESULT result; result.bState = uState; lstrcpy(result.szDescription, szDescription); for (WORD i = 0; i < m_wChairCount; i++) { IServerUserItem * pIServerUserItem = GetTableUserItem(i); if (pIServerUserItem == NULL) continue; UserInfo::PB_CS_S_DELETE_PRIVATE_ROOM_RESULT RoomResult; RoomResult.set_wtableid(result.wTableID); RoomResult.set_bstate(result.bState); std::string szDescription = CW2AEX<1024>(result.szDescription, CP_UTF8).m_psz; RoomResult.set_szdescription(szDescription); //发送数据 std::string pbdata = RoomResult.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_RESULT, (void*)pbdata.c_str(), pbdata.length()); //发送消息 if (result.bState == 2) SendGameMessage(m_TableUserItemArray[i], TEXT("此房间已经被群主解散了!"), SMT_TABLE_EXIT); } WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = EnumLookonUserItem(wEnumIndex++); while (pIServerUserItem) { UserInfo::PB_CS_S_DELETE_PRIVATE_ROOM_RESULT RoomResult; RoomResult.set_wtableid(result.wTableID); RoomResult.set_bstate(result.bState); std::string szDescription = CW2AEX<1024>(result.szDescription, CP_UTF8).m_psz; RoomResult.set_szdescription(szDescription); //发送数据 std::string pbdata = RoomResult.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_RESULT, (void*)pbdata.c_str(), pbdata.length()); pIServerUserItem = EnumLookonUserItem(wEnumIndex++); } KillGameTimer(IDI_START_DISMISS_PRIVATE); KillGameTimer(IDI_STARTED_TIME);//申请解散时,把定时器去掉 m_AgreeDeletePriTableUsers.clear(); m_bDismissVoteStarted = false; if (1 == uState || 2 == uState) { //如果第一局没结束,则退钱给房主 if (m_wDrawCount == 0 && m_cbGameStatus == 101) { UnAdminLockBeans(); } if (2 == uState) //异常结束。 { m_pITableFrameSink->OnEventGameConclude(INVALID_CHAIR, NULL, GER_DELETE_PRIVATE, true); } else //调用游戏内结算,发送当前游戏结算。 { m_pITableFrameSink->OnEventGameConclude(INVALID_CHAIR, NULL, GER_DISMISS, true); } //CTraceService::TraceString(TEXT("定时解散成功!"), TraceLevel_Normal); return false; } return true; } bool CTableFrame::DeletePrivateStarted(USHORT uState, LPCTSTR szDescription) { CMD_GR_DELETE_PRIVATE_ROOM_RESULT result; result.bState = uState; lstrcpy(result.szDescription, szDescription); for (WORD i = 0; i < m_wChairCount; i++) { IServerUserItem * pIServerUserItem = GetTableUserItem(i); if (pIServerUserItem == NULL) continue; UserInfo::PB_CS_S_DELETE_PRIVATE_ROOM_RESULT RoomResult; RoomResult.set_wtableid(result.wTableID); RoomResult.set_bstate(result.bState); std::string szDescription = CW2AEX<1024>(result.szDescription, CP_UTF8).m_psz; RoomResult.set_szdescription(szDescription); //发送数据 std::string pbdata = RoomResult.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_RESULT, (void*)pbdata.c_str(), pbdata.length()); } WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = EnumLookonUserItem(wEnumIndex++); while (pIServerUserItem) { UserInfo::PB_CS_S_DELETE_PRIVATE_ROOM_RESULT RoomResult; RoomResult.set_wtableid(result.wTableID); RoomResult.set_bstate(result.bState); std::string szDescription = CW2AEX<1024>(result.szDescription, CP_UTF8).m_psz; RoomResult.set_szdescription(szDescription); //发送数据 std::string pbdata = RoomResult.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_DELETE_PRIVATE_TABLE_RESULT, (void*)pbdata.c_str(), pbdata.length()); pIServerUserItem = EnumLookonUserItem(wEnumIndex++); } KillGameTimer(IDI_STARTED_TIME); if (1 == uState) { //如果第一局没结束,则退钱给房主 if (m_wDrawCount == 0 && m_cbGameStatus == 101) { UnAdminLockBeans(); } //调用游戏内结算,发送当前游戏结算。 m_pITableFrameSink->OnEventGameConclude(INVALID_CHAIR, NULL, GER_DELETE_PRIVATE, true); //CTraceService::TraceString(TEXT("定时解散成功!"), TraceLevel_Normal); return false; } return true; } //写入积分 bool CTableFrame::WriteUserScore(WORD wChairID, tagScoreInfo & ScoreInfo, DWORD dwGameMemal, DWORD dwPlayGameTime) { //效验参数 if ((wChairID >= m_wChairCount) && (ScoreInfo.cbType == SCORE_TYPE_NULL)) return false; //if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) //{ // //戳瞎子 // if (wChairID == 3) // { // return false; // } //} //获取用户 ASSERT(GetTableUserItem(wChairID) != NULL); IServerUserItem * pIServerUserItem = GetTableUserItem(wChairID); TCHAR szMessage[128] = TEXT(""); //写入积分 //二人麻将异常修改 if (pIServerUserItem == NULL) { return true; //离开用户 //CTraceService::TraceString(TEXT("系统暂时未支持离开用户的补分操作处理!"), TraceLevel_Exception); //return false; } //游戏时间 DWORD dwCurrentTime = (DWORD)time(NULL); DWORD dwPlayTimeCount = ((m_bDrawStarted == true) ? (dwCurrentTime - m_dwDrawStartTime) : 0L); if (dwPlayGameTime != INVALID_DWORD) dwPlayTimeCount = dwPlayGameTime; //变量定义 DWORD dwUserMemal = 0L; //查询是否使用临时积分(临时积分:输赢都不计入用户积分) bool bUseTemporaryScore = m_pITableFrameSink->QueryUseTemporaryScore(); if (!bUseTemporaryScore) { //使用积分 SCORE lRevenueScore = __min(m_lFrozenedScore[wChairID], m_pGameServiceOption->lServiceScore); //扣服务费 if (m_pGameServiceOption->lServiceScore > 0L && m_pGameServiceOption->wServerType == GAME_GENRE_GOLD && m_pITableFrameSink->QueryBuckleServiceCharge(wChairID)) { //扣服务费 ScoreInfo.lScore -= lRevenueScore; ScoreInfo.lRevenue += lRevenueScore; //解锁游戏币 pIServerUserItem->UnFrozenedUserScore(m_lFrozenedScore[wChairID]); m_lFrozenedScore[wChairID] = 0L; } //奖牌计算 if (dwGameMemal != INVALID_DWORD) { dwUserMemal = dwGameMemal; } else if (ScoreInfo.lRevenue > 0L) { WORD wMedalRate = m_pGameParameter->wMedalRate; dwUserMemal = (DWORD)(ScoreInfo.lRevenue*wMedalRate / 1000L); } //变量定义 tagUserProperty * pUserProperty = pIServerUserItem->GetUserProperty(); //道具判断 if (m_pGameServiceOption->wServerType == GAME_GENRE_SCORE) { if (ScoreInfo.lScore > 0L) { //四倍积分 if ((pUserProperty->wPropertyUseMark&PT_USE_MARK_FOURE_SCORE) != 0) { //变量定义 DWORD dwValidTime = pUserProperty->PropertyInfo[1].wPropertyCount*pUserProperty->PropertyInfo[1].dwValidNum; if (pUserProperty->PropertyInfo[1].dwEffectTime + dwValidTime > dwCurrentTime) { //积分翻倍 ScoreInfo.lScore *= 4; _sntprintf(szMessage, CountArray(szMessage), TEXT("[ %s ] 使用了[ 四倍积分卡 ],得分翻四倍!)"), pIServerUserItem->GetNickName()); } else { pUserProperty->wPropertyUseMark &= ~PT_USE_MARK_FOURE_SCORE; } } //双倍积分 else if ((pUserProperty->wPropertyUseMark&PT_USE_MARK_DOUBLE_SCORE) != 0) { //变量定义 DWORD dwValidTime = pUserProperty->PropertyInfo[0].wPropertyCount*pUserProperty->PropertyInfo[0].dwValidNum; if (pUserProperty->PropertyInfo[0].dwEffectTime + dwValidTime > dwCurrentTime) { //积分翻倍 ScoreInfo.lScore *= 2L; _sntprintf(szMessage, CountArray(szMessage), TEXT("[ %s ] 使用了[ 双倍积分卡 ],得分翻倍!"), pIServerUserItem->GetNickName()); } else { pUserProperty->wPropertyUseMark &= ~PT_USE_MARK_DOUBLE_SCORE; } } } else { //附身符 if ((pUserProperty->wPropertyUseMark&PT_USE_MARK_POSSESS) != 0) { //变量定义 DWORD dwValidTime = pUserProperty->PropertyInfo[3].wPropertyCount*pUserProperty->PropertyInfo[3].dwValidNum; if (pUserProperty->PropertyInfo[3].dwEffectTime + dwValidTime > dwCurrentTime) { //积分翻倍 ScoreInfo.lScore = 0; _sntprintf(szMessage, CountArray(szMessage), TEXT("[ %s ] 使用了[ 护身符卡 ],积分不变!"), pIServerUserItem->GetNickName()); } else { pUserProperty->wPropertyUseMark &= ~PT_USE_MARK_POSSESS; } } } } //写入积分 DWORD dwWinExperience = ScoreInfo.cbType == SCORE_TYPE_WIN ? m_pGameParameter->dwWinExperience : 0; pIServerUserItem->WriteUserScore(ScoreInfo.lScore, ScoreInfo.lGrade, ScoreInfo.lRevenue, dwUserMemal, ScoreInfo.cbType, dwPlayTimeCount, dwWinExperience); } else { //写入积分 DWORD dwWinExperience = ScoreInfo.cbType == SCORE_TYPE_WIN ? m_pGameParameter->dwWinExperience : 0; pIServerUserItem->WriteUserScore(ScoreInfo.lScore, ScoreInfo.lGrade, ScoreInfo.lRevenue, dwUserMemal, ScoreInfo.cbType, dwPlayTimeCount, dwWinExperience); //使用临时积分 DBR_GR_WriteGameTemporaryScore req; ZeroMemory(&req, sizeof(req)); req.dwUserID = pIServerUserItem->GetUserID(); req.dwClientAddr = pIServerUserItem->GetClientAddr(); req.lScore = ScoreInfo.lScore; if (ScoreInfo.lScore < 0) { req.lScore = 0; //换算成 不含倍数的得分 } if (m_wDrawCount < 1) { req.lScore = 0; //换算成 不含倍数的得分 } if (req.lScore>0) { //req.lScore = req.lScore / mGameConfig.wPlayRule; //底分为0的时候会崩溃 req.lScore = 0; } req.dwPlayTimeCount = dwPlayTimeCount; /*if (SCORE_TYPE_END == ScoreInfo.cbType) { return true; }*/ //修改胜负 switch (ScoreInfo.cbType) { case SCORE_TYPE_WIN: //胜局 case SCORE_TYPE_LOSE: //输局 case SCORE_TYPE_DRAW: //平局 m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_WRITE_GAME_TEMPORARY_SCORE, 0, &req, sizeof(req)); break; default: break; //case SCORE_TYPE_WIN: //胜局 //{ // req.dwWinCount++; //}break; //case SCORE_TYPE_LOSE: //输局 //{ // req.dwLostCount++; //}break; //case SCORE_TYPE_DRAW: //{ // req.dwPingCount++; // break; //} } } //游戏记录 if (pIServerUserItem->IsAndroidUser() == false && CServerRule::IsRecordGameScore(m_pGameServiceOption->dwServerRule) == true) { //变量定义 tagGameScoreRecord * pGameScoreRecord = NULL; //查询库存 if (m_GameScoreRecordBuffer.GetCount() > 0L) { //获取对象 INT_PTR nCount = m_GameScoreRecordBuffer.GetCount(); pGameScoreRecord = m_GameScoreRecordBuffer[nCount - 1]; //删除对象 m_GameScoreRecordBuffer.RemoveAt(nCount - 1); } //创建对象 if (pGameScoreRecord == NULL) { try { //创建对象 pGameScoreRecord = new tagGameScoreRecord; if (pGameScoreRecord == NULL) throw TEXT("游戏记录对象创建失败"); } catch (...) { ASSERT(FALSE); } } //记录数据 if (pGameScoreRecord != NULL) { //用户信息 pGameScoreRecord->wChairID = wChairID; pGameScoreRecord->dwUserID = pIServerUserItem->GetUserID(); lstrcpy(pGameScoreRecord->szUserName , pIServerUserItem->GetNickName()); lstrcpy(pGameScoreRecord->szHeadImg, pIServerUserItem->GetUserInfo()->szHeadUrl); pGameScoreRecord->cbAndroid = (pIServerUserItem->IsAndroidUser() ? TRUE : FALSE); //用户信息 pGameScoreRecord->dwDBQuestID = pIServerUserItem->GetDBQuestID(); pGameScoreRecord->dwInoutIndex = pIServerUserItem->GetInoutIndex(); //成绩信息 pGameScoreRecord->lScore = ScoreInfo.lScore; pGameScoreRecord->lGrade = ScoreInfo.lGrade; pGameScoreRecord->lRevenue = ScoreInfo.lRevenue; //附加信息 pGameScoreRecord->dwUserMemal = dwUserMemal; pGameScoreRecord->dwPlayTimeCount = dwPlayTimeCount; //机器人免税 if (pIServerUserItem->IsAndroidUser()) { pGameScoreRecord->lScore += pGameScoreRecord->lRevenue; pGameScoreRecord->lRevenue = 0L; } //插入数据 m_GameScoreRecordActive.Add(pGameScoreRecord); } } //游戏记录 if (dwGameMemal != INVALID_DWORD || dwPlayGameTime != INVALID_DWORD) { DWORD dwStartGameTime = INVALID_DWORD; if (dwPlayGameTime != INVALID_DWORD) { dwStartGameTime = (dwCurrentTime - dwPlayGameTime); } RecordGameScore(true, dwStartGameTime); } //广播消息 if (szMessage[0] != 0) { //变量定义 IServerUserItem * pISendUserItem = NULL; WORD wEnumIndex = 0; //游戏玩家 for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 pISendUserItem = GetTableUserItem(i); if (pISendUserItem == NULL) continue; SendRequestFailure(pIServerUserItem, szMessage, 0); //发送消息 //SendGameMessage(pISendUserItem, szMessage, SMT_CHAT); } //旁观用户 do { pISendUserItem = EnumLookonUserItem(wEnumIndex++); if (pISendUserItem != NULL) { SendRequestFailure(pIServerUserItem, szMessage, 0); //发送消息 //SendGameMessage(pISendUserItem, szMessage, SMT_CHAT); } } while (pISendUserItem != NULL); } return true; } //锁定元宝 bool CTableFrame::LockBeans(DWORD dwUserID, UINT32 dwConsumeCurrency) { if (dwUserID == 0 || dwConsumeCurrency == 0) return true; DWORD dwSocketID = 0; auto pIUserItem = m_pIMainServiceFrame->SearchUserItem(dwUserID); if (pIUserItem) { auto bindParam = m_pIMainServiceFrame->GetBindParameter(pIUserItem->GetBindIndex()); if (bindParam) dwSocketID = bindParam->dwSocketID; } DBR_GR_UserReduceBeans req; ZeroMemory(&req, sizeof(DBR_GR_UserReduceBeans)); req.ConsumeCurrency = dwConsumeCurrency; req.dwUserID = dwUserID; req.dwTableID = this->GetTableID(); if (pIUserItem) req.dwClientAddr = pIUserItem->GetClientAddr(); m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_USER_LUCK_BEANS, dwSocketID, &req, sizeof(DBR_GR_UserReduceBeans)); return true; } //在桌子解散的情况下,按照约定处理房间创建者需要解锁的元宝 void CTableFrame::UnAdminLockBeans() { //先处理创建者的元宝,查看创建者是否参与游戏中。 IServerUserItem * pIServerUserItem = NULL; for (WORD i = 0; i < m_wChairCount; i++) { IServerUserItem * p = GetTableUserItem(i); if ((p != NULL) && (p->GetUserID() == this->GetPrivateTableOwnerID())) { pIServerUserItem = p; break; } } if (pIServerUserItem != NULL) { //创建者参与或者群主支付 if (mGameConfig.wMaxFanRule == 0) { //创建者支付 if (m_wDrawCount >= 1) { //游戏已经打过一局的情况。扣款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User == this->GetPrivateTableOwnerID()) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { ReduceBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; break; } } } } else { //游戏没打,就解散了。退款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User == this->GetPrivateTableOwnerID()) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { UnLockBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; } } } } } else if (mGameConfig.wMaxFanRule >= 10) { //创建者支付 if (m_wDrawCount >= 1) { //游戏已经打过一局的情况。扣款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { ReduceBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; break; } } } } else { //游戏没打,就解散了。退款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { UnLockBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; break; } } } } } else { //平摊 if (m_wDrawCount >= 1) { //游戏已经打过一局的情况。扣款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { if (m_jgrUserLockData[i].dwLockNum > 0) { int a = m_jgrUserLockData[i].dwLockNum; m_jgrUserLockData[i].dwLockNum = 0; ReduceBeans(m_jgrUserLockData[i].User, a); } } } } else { //游戏没打,就解散了。退款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { if (m_jgrUserLockData[i].dwLockNum > 0) { int a = m_jgrUserLockData[i].dwLockNum; m_jgrUserLockData[i].dwLockNum = 0; UnLockBeans(m_jgrUserLockData[i].User, a); } } } } } } else { //创建者不参与 if (mGameConfig.wMaxFanRule == 0) { //创建者支付 if (m_wDrawCount >= 1) { //游戏已经打过一局的情况。扣款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User == this->GetPrivateTableOwnerID()) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { ReduceBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; break; } } } } else { //游戏没打,就解散了。退款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User == this->GetPrivateTableOwnerID()) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { UnLockBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; break; } } } } } else if (mGameConfig.wMaxFanRule >= 10) { //创建者支付 if (m_wDrawCount >= 1) { //游戏已经打过一局的情况。扣款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { ReduceBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; break; } } } } else { //游戏没打,就解散了。退款 for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { UnLockBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; break; } } } } } else { //平摊 if (m_wDrawCount >= 1) { for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { //是创建者 if (m_jgrUserLockData[i].dwLockNum > 0) { if (m_jgrUserLockData[i].User == this->GetPrivateTableOwnerID()) { UnLockBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); } else { ReduceBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); } m_jgrUserLockData[i].dwLockNum = 0; } } } } else { for (int i = 0; i < 6; i++) { if (m_jgrUserLockData[i].User != 0) { if (m_jgrUserLockData[i].dwLockNum > 0) { UnLockBeans(m_jgrUserLockData[i].User, m_jgrUserLockData[i].dwLockNum); m_jgrUserLockData[i].dwLockNum = 0; } } } } } } } //解锁元宝 bool CTableFrame::UnLockBeans(DWORD dwUserID, UINT32 dwConsumeCurrency) { if (dwUserID == 0 || dwConsumeCurrency == 0) return true; DWORD dwSocketID = 0; auto pIUserItem = m_pIMainServiceFrame->SearchUserItem(dwUserID); if (pIUserItem) { auto bindParam = m_pIMainServiceFrame->GetBindParameter(pIUserItem->GetBindIndex()); if (bindParam) dwSocketID = bindParam->dwSocketID; } DBR_GR_UserReduceBeans req; ZeroMemory(&req, sizeof(DBR_GR_UserReduceBeans)); req.ConsumeCurrency = dwConsumeCurrency; req.dwUserID = dwUserID; req.dwTableID = this->GetTableID(); if (pIUserItem) req.dwClientAddr = pIUserItem->GetClientAddr(); m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_USER_UNLUCK_BEANS, dwSocketID, &req, sizeof(DBR_GR_UserReduceBeans)); return true; } //消耗房卡 bool CTableFrame::ReduceBeans(DWORD dwUserID,UINT32 dwConsumeCurrency) { if (dwUserID == 0 || dwConsumeCurrency == 0) return true; DWORD dwSocketID = 0; auto pIUserItem = m_pIMainServiceFrame->SearchUserItem(dwUserID); if (pIUserItem) { auto bindParam = m_pIMainServiceFrame->GetBindParameter(pIUserItem->GetBindIndex()); if (bindParam) dwSocketID = bindParam->dwSocketID; } DBR_GR_UserReduceBeans req; ZeroMemory(&req, sizeof(DBR_GR_UserReduceBeans)); req.ConsumeCurrency = dwConsumeCurrency; req.dwUserID = dwUserID; req.dwTableID = this->GetTableID(); if (pIUserItem) req.dwClientAddr = pIUserItem->GetClientAddr(); m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_USER_REDUCE_BEANS, dwSocketID, &req, sizeof(DBR_GR_UserReduceBeans)); return true; } //直接扣除房卡 bool CTableFrame::NowReduceBeans(DWORD dwUserID, UINT32 dwConsumeCurrency) { if (dwUserID == 0 || dwConsumeCurrency == 0) return true; DWORD dwSocketID = 0; auto pIUserItem = m_pIMainServiceFrame->SearchUserItem(dwUserID); if (pIUserItem) { auto bindParam = m_pIMainServiceFrame->GetBindParameter(pIUserItem->GetBindIndex()); if (bindParam) dwSocketID = bindParam->dwSocketID; } DBR_GR_UserReduceBeans req; ZeroMemory(&req, sizeof(DBR_GR_UserReduceBeans)); req.ConsumeCurrency = dwConsumeCurrency; req.dwUserID = dwUserID; req.dwTableID = this->GetTableID(); if(pIUserItem) req.dwClientAddr = pIUserItem->GetClientAddr(); m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_USER_CHECK_BEANS, dwSocketID, &req, sizeof(DBR_GR_UserReduceBeans)); return true; } //写入积分 bool CTableFrame::WriteTableScore(tagScoreInfo ScoreInfoArray[], WORD wScoreCount) { //写入分数 for (WORD i = 0; i < m_wChairCount; i++) { if (ScoreInfoArray[i].cbType != SCORE_TYPE_NULL && !(1 == i && GetStartMode() == START_MODE_ALL_READY)) { WriteUserScore(i, ScoreInfoArray[i]); } } return true; } //推送闲聊机器人 //void CTableFrame::WriteXianLiaoTableRecord() //{ // IServerUserItem * pIServerUserItem = NULL; // DBR_GR_ClubRecordXianLiao FenXiangXianLiao = { 0 }; // FenXiangXianLiao.WanFa = this->GetGameConfig().wSubGameID; // FenXiangXianLiao.dwClubID = m_dwClubID; // FenXiangXianLiao.dwTableID = stoi(m_sPrivateTableID);//桌子号 // FenXiangXianLiao.dwUserCount = m_wChairCount; // if (m_wChairCount == 3 && this->GetStartMode() == START_MODE_ALL_READY) // { // FenXiangXianLiao.dwUserCount = 2; // } // FenXiangXianLiao.Jushu = m_wStartCount; // FenXiangXianLiao.DiFen = this->GetGameConfig().wPlayRule; // BYTE TempCount = 0; // for (BYTE i = 0; i < m_wChairCount; i++) // { // pIServerUserItem = GetTableUserItem(i); // if (pIServerUserItem == NULL) continue; // FenXiangXianLiao.Player[TempCount].userID = pIServerUserItem->GetUserID(); // CopyMemory(&FenXiangXianLiao.Player[TempCount].szName, pIServerUserItem->GetUserInfo()->szNickName, sizeof(FenXiangXianLiao.Player[i].szName)); // CopyMemory(&FenXiangXianLiao.Player[TempCount].szImgHead, pIServerUserItem->GetUserInfo()->szHeadUrl, sizeof(FenXiangXianLiao.Player[i].szImgHead)); // FenXiangXianLiao.Player[TempCount].gScore = m_pITableFrameSink->QueryTatolScore(i); // TempCount++; // } // //投递数据 // m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_CLUB_XIANLIAO_RECORD, 0, &FenXiangXianLiao, sizeof(FenXiangXianLiao)); //} //写入俱乐部记录 void CTableFrame::WriteClubTableRecord() { if (this->m_wTableKind == 1) { //变量定义 DBR_GR_ClubRecordWrite ClubRecordWrite; ZeroMemory(&ClubRecordWrite, sizeof(ClubRecordWrite)); //设置变量 ClubRecordWrite.dwClubID = m_dwClubID; ClubRecordWrite.SystemTimeStart = m_SystemTimeStart; ClubRecordWrite.dwUserID = this->GetPrivateTableOwnerID(); ClubRecordWrite.dwTableID = _wtoi(this->GetPrivateTableID().c_str()); ClubRecordWrite.PayWay = this->GetGameConfig().wMaxFanRule; ClubRecordWrite.Jushu = this->GetGameConfig().wPlayCountRule; ClubRecordWrite.dwUserCount = m_wChairCount; if (this->GetStartMode() == START_MODE_ALL_READY && m_wChairCount == 3) { ClubRecordWrite.dwUserCount = 2; } for (int i = 0; i < m_wChairCount; i++) { if (GetTableUserItem(i)) { ClubRecordWrite.Player[i] = GetTableUserItem(i)->GetUserInfo()->dwUserID; } } //投递数据 m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_CLUB_WRITE_RECORD, 0, &ClubRecordWrite, sizeof(ClubRecordWrite)); } } //回放 bool CTableFrame::SaveReplayRecord(void* pData, WORD wDataSize) { if (nullptr != m_ReplayRecordData) { delete [] m_ReplayRecordData; m_ReplayRecordData = nullptr; } m_ReplayRecordData = new char[wDataSize]; ZeroMemory(m_ReplayRecordData, sizeof(char) * wDataSize); CopyMemory(m_ReplayRecordData, pData, sizeof(char) * wDataSize); //m_ReplayRecordData = pData; m_ReplayRecordDataSize = wDataSize; return true; } //计算税收 SCORE CTableFrame::CalculateRevenue(WORD wChairID, SCORE lScore) { //效验参数 ASSERT(wChairID= m_wChairCount) return 0L; //计算税收 if ((m_pGameServiceOption->wRevenueRatio>0) && (lScore >= REVENUE_BENCHMARK)) { //获取用户 ASSERT(GetTableUserItem(wChairID) != NULL); IServerUserItem * pIServerUserItem = GetTableUserItem(wChairID); //计算税收 SCORE lRevenue = lScore*m_pGameServiceOption->wRevenueRatio / REVENUE_DENOMINATOR; return lRevenue; } return 0L; } //消费限额 SCORE CTableFrame::QueryConsumeQuota(IServerUserItem * pIServerUserItem) { //用户效验 ASSERT(pIServerUserItem->GetTableID() == m_wTableID); if (pIServerUserItem->GetTableID() != m_wTableID) return 0L; //查询额度 SCORE lTrusteeScore = pIServerUserItem->GetTrusteeScore(); SCORE lMinEnterScore = m_pGameServiceOption->lMinTableScore; SCORE lUserConsumeQuota = m_pITableFrameSink->QueryConsumeQuota(pIServerUserItem); //效验额度 ASSERT((lUserConsumeQuota >= 0L) && (lUserConsumeQuota <= pIServerUserItem->GetUserScore() - lMinEnterScore)); if ((lUserConsumeQuota<0L) || (lUserConsumeQuota>pIServerUserItem->GetUserScore() - lMinEnterScore)) return 0L; return lUserConsumeQuota + lTrusteeScore; } //寻找用户 IServerUserItem * CTableFrame::SearchUserItem(DWORD dwUserID) { //变量定义 WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = NULL; //桌子用户 for (WORD i = 0; i < m_wChairCount; i++) { pIServerUserItem = GetTableUserItem(i); if ((pIServerUserItem != NULL) && (pIServerUserItem->GetUserID() == dwUserID)) return pIServerUserItem; } //旁观用户 do { pIServerUserItem = EnumLookonUserItem(wEnumIndex++); if ((pIServerUserItem != NULL) && (pIServerUserItem->GetUserID() == dwUserID)) return pIServerUserItem; } while (pIServerUserItem != NULL); return NULL; } //游戏用户 IServerUserItem * CTableFrame::GetTableUserItem(WORD wChairID) { //效验参数 //ASSERT(wChairID < m_wChairCount); if (wChairID >= m_wChairCount) return NULL; //获取用户 return m_TableUserItemArray[wChairID]; } //旁观用户 IServerUserItem * CTableFrame::EnumLookonUserItem(WORD wEnumIndex) { if (wEnumIndex >= m_LookonUserItemArray.GetCount()) return NULL; return m_LookonUserItemArray[wEnumIndex]; } //设置时间 bool CTableFrame::SetGameTimer(DWORD dwTimerID, DWORD dwElapse, DWORD dwRepeat, WPARAM dwBindParameter) { //效验参数 ASSERT((dwTimerID > 0) && (dwTimerID < TIME_TABLE_MODULE_RANGE)); if ((dwTimerID <= 0) || (dwTimerID >= TIME_TABLE_MODULE_RANGE)) return false; //设置时间 DWORD dwEngineTimerID = IDI_TABLE_MODULE_START + m_wTableID*TIME_TABLE_MODULE_RANGE; if (m_pITimerEngine != NULL) m_pITimerEngine->SetTimer(dwEngineTimerID + dwTimerID, dwElapse, dwRepeat, dwBindParameter); return true; } //删除时间 bool CTableFrame::KillGameTimer(DWORD dwTimerID) { //效验参数 ASSERT((dwTimerID > 0) && (dwTimerID <= TIME_TABLE_MODULE_RANGE)); if ((dwTimerID <= 0) || (dwTimerID > TIME_TABLE_MODULE_RANGE)) return false; //删除时间 DWORD dwEngineTimerID = IDI_TABLE_MODULE_START + m_wTableID*TIME_TABLE_MODULE_RANGE; if (m_pITimerEngine != NULL) m_pITimerEngine->KillTimer(dwEngineTimerID + dwTimerID); return true; } //发送数据 bool CTableFrame::SendUserItemData(IServerUserItem * pIServerUserItem, WORD wSubCmdID) { //状态效验 ASSERT((pIServerUserItem != NULL) && (pIServerUserItem->IsClientReady() == true)); if ((pIServerUserItem == NULL) && (pIServerUserItem->IsClientReady() == false)) return false; //发送数据 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_GAME, wSubCmdID, NULL, 0); return true; } //发送数据 bool CTableFrame::SendUserItemData(IServerUserItem * pIServerUserItem, WORD wSubCmdID, VOID * pData, WORD wDataSize) { //状态效验 ASSERT((pIServerUserItem != NULL) && (pIServerUserItem->IsClientReady() == true)); if ((pIServerUserItem == NULL) && (pIServerUserItem->IsClientReady() == false)) return false; //发送数据 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_GAME, wSubCmdID, pData, wDataSize); return true; } //发送数据 bool CTableFrame::SendTableData(WORD wChairID, WORD wSubCmdID) { //用户群发 if (wChairID == INVALID_CHAIR) { for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(i); if (pIServerUserItem == NULL) continue; //效验状态 ASSERT(pIServerUserItem->IsClientReady() == true); if (pIServerUserItem->IsClientReady() == false) continue; //发送数据 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_GAME, wSubCmdID, NULL, 0); } return true; } else { //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(wChairID); if (pIServerUserItem == NULL) return false; //效验状态 ASSERT(pIServerUserItem->IsClientReady() == true); if (pIServerUserItem->IsClientReady() == false) return false; //发送数据 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_GAME, wSubCmdID, NULL, 0); return true; } return false; } //发送数据 bool CTableFrame::SendTableData(WORD wChairID, WORD wSubCmdID, VOID * pData, WORD wDataSize, WORD wMainCmdID) { //用户群发 if (wChairID == INVALID_CHAIR) { for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(i); if ((pIServerUserItem == NULL) || (pIServerUserItem->IsClientReady() == false)) continue; //发送数据 m_pIMainServiceFrame->SendData(pIServerUserItem, wMainCmdID, wSubCmdID, pData, wDataSize); } return true; } else { //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(wChairID); if ((pIServerUserItem == NULL) || (pIServerUserItem->IsClientReady() == false)) return false; //发送数据 m_pIMainServiceFrame->SendData(pIServerUserItem, wMainCmdID, wSubCmdID, pData, wDataSize); return true; } return false; } //发送数据 bool CTableFrame::SendLookonData(WORD wChairID, WORD wSubCmdID) { //变量定义 WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = NULL; //枚举用户 do { //获取用户 pIServerUserItem = EnumLookonUserItem(wEnumIndex++); if (pIServerUserItem == NULL) break; //效验状态 ASSERT(pIServerUserItem->IsClientReady() == true); if (pIServerUserItem->IsClientReady() == false) return false; //发送数据 if ((wChairID == INVALID_CHAIR) || (pIServerUserItem->GetChairID() == wChairID)) { m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_GAME, wSubCmdID, NULL, 0); } } while (true); return true; } //发送数据 ///---发送旁观数据 bool CTableFrame::SendLookonData(WORD wChairID, WORD wSubCmdID, VOID * pData, WORD wDataSize) { //变量定义 WORD wEnumIndex = 0; IServerUserItem * pIServerUserItem = NULL; //枚举用户 do { //获取用户 pIServerUserItem = EnumLookonUserItem(wEnumIndex++); if (pIServerUserItem == NULL) break; //效验状态 //ASSERT(pIServerUserItem->IsClientReady()==true); if (pIServerUserItem->IsClientReady() == false) return false; //发送数据 //if ((wChairID == INVALID_CHAIR) || (pIServerUserItem->GetChairID() == wChairID)) //{ m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_GAME, wSubCmdID, pData, wDataSize); //} } while (true); return true; } //发送消息 bool CTableFrame::SendGameMessage(LPCTSTR lpszMessage, WORD wType) { //变量定义 WORD wEnumIndex = 0; //发送消息 for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(i); if ((pIServerUserItem == NULL) || (pIServerUserItem->IsClientReady() == false)) continue; //发送消息 m_pIMainServiceFrame->SendGameMessage(pIServerUserItem, lpszMessage, wType); } //枚举用户 do { //获取用户 IServerUserItem * pIServerUserItem = EnumLookonUserItem(wEnumIndex++); if (pIServerUserItem == NULL) break; //效验状态 //ASSERT(pIServerUserItem->IsClientReady() == true); //if (pIServerUserItem->IsClientReady() == false) return false; //发送消息 m_pIMainServiceFrame->SendGameMessage(pIServerUserItem, lpszMessage, wType); } while (true); return true; } //房间消息 bool CTableFrame::SendRoomMessage(IServerUserItem * pIServerUserItem, LPCTSTR lpszMessage, WORD wType) { //用户效验 ASSERT(pIServerUserItem != NULL); if (pIServerUserItem == NULL) return false; //发送消息 m_pIMainServiceFrame->SendRoomMessage(pIServerUserItem, lpszMessage, wType); return true; } //游戏消息 bool CTableFrame::SendGameMessage(IServerUserItem * pIServerUserItem, LPCTSTR lpszMessage, WORD wType) { //用户效验 ASSERT(pIServerUserItem != NULL); if (pIServerUserItem == NULL) return false; //发送消息 return m_pIMainServiceFrame->SendGameMessage(pIServerUserItem, lpszMessage, wType); } //发送场景 bool CTableFrame::SendGameScene(IServerUserItem * pIServerUserItem, VOID * pData, WORD wDataSize) { //用户效验 ASSERT(pIServerUserItem != NULL); if (pIServerUserItem == NULL) return false; if (m_cbGameStatus == 0) { CMD_S_StatusFree* pStat = (CMD_S_StatusFree*)pData; if (m_bDismissVoteStarted) { auto now = time(0); int aa = now - m_iLastDismissVoteTime; aa = TIME_DISMISS_PRIVATE / 1000 - aa; if (aa < 0) { aa = 0; } //投票过程中 pStat->leftTime = aa; pStat->wchairId = w_SendChairID; std::unordered_map::iterator iter_ = m_AgreeDeletePriTableUsers.begin(); int iNum = 0; int iNone = 0; for (int i = 0; i < m_AgreeDeletePriTableUsers.size(); i++) { if (iter_->second == 1) { //同意解散 DWORD UserID = iter_->first; IServerUserItem* pUser = SearchUserItem(UserID); if (pUser) { WORD wChair = pUser->GetChairID(); ASSERT(wChair < GAME_PLAYER); if (wChair <= GAME_PLAYER) pStat->options[wChair] = 1; } } else if (iter_->second == 2) { //拒绝解散 DWORD UserID = iter_->first; IServerUserItem* pUser = SearchUserItem(UserID); if (pUser) { WORD wChair = pUser->GetChairID(); ASSERT(wChair < GAME_PLAYER); if (wChair <= GAME_PLAYER) pStat->options[wChair] = 2; } } iter_++; } } else { //非投票时间 pStat->leftTime = 255; } //发送场景 ASSERT(m_pIMainServiceFrame != NULL); GameInfo::PB_CS_S_StatusFree Status; for (int i = 0; i < 4; i++) { Status.add_lusertmpscore(pStat->lUserTmpScore[i]); } Status.set_lefttime(pStat->leftTime); Status.set_wchairid(pStat->wchairId); for (int i = 0; i < 4; i++) { Status.add_options(pStat->options[i]); } Status.set_userstat(pStat->UserStat); Status.mutable_gameconfig()->set_wsubgameid(pStat->gameConfig.wSubGameID); Status.mutable_gameconfig()->set_wplayrule(pStat->gameConfig.wDiScore); Status.mutable_gameconfig()->set_wmaxfanrule(pStat->gameConfig.wFanFei); Status.mutable_gameconfig()->set_wmaxscore(pStat->gameConfig.wIpLimit); Status.mutable_gameconfig()->set_wplaycountrule(pStat->gameConfig.wPlayCountRule); Status.mutable_gameconfig()->set_whadplaycount(pStat->gameConfig.wHadPlayCount); Status.mutable_gameconfig()->set_zmextrarule(pStat->gameConfig.IsOwner); Status.mutable_gameconfig()->set_dghrule(pStat->gameConfig.RoomId); std::string sPrivateTableID = CW2AEX<1024>(pStat->gameConfig.sPrivateTableID, CP_UTF8).m_psz; Status.mutable_gameconfig()->set_sprivatetableid(sPrivateTableID); Status.mutable_gameconfig()->set_bduolai(pStat->gameConfig.GameScoreType); Status.mutable_gameconfig()->set_wfengding(pStat->gameConfig.tmp2); Status.mutable_gameconfig()->set_tmp1(pStat->gameConfig.temp3); //发送数据 std::string pbdata = Status.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME,SUB_GF_GAME_SCENE, (void*)pbdata.c_str(), pbdata.length()); } else { CMD_S_StatusPlay_ZhuJi* pStat = (CMD_S_StatusPlay_ZhuJi*)pData; if (m_bDismissVoteStarted) { auto now = time(0); int aa = now - m_iLastDismissVoteTime; aa = TIME_DISMISS_PRIVATE / 1000 - aa; if (aa < 0) { aa = 0; } //投票过程中 pStat->leftTime = aa; pStat->wchairId = w_SendChairID; std::unordered_map::iterator iter_ = m_AgreeDeletePriTableUsers.begin(); int iNum = 0; int iNone = 0; for (int i = 0; i < m_AgreeDeletePriTableUsers.size(); i++) { if (iter_->second == 1) { //同意解散 DWORD UserID = iter_->first; IServerUserItem* pUser = SearchUserItem(UserID); if (pUser) { WORD wChair = pUser->GetChairID(); ASSERT(wChair < GAME_PLAYER); if (wChair <= GAME_PLAYER) pStat->options[wChair] = 1; } } else if (iter_->second == 2) { //拒绝解散 DWORD UserID = iter_->first; IServerUserItem* pUser = SearchUserItem(UserID); if (pUser) { WORD wChair = pUser->GetChairID(); ASSERT(wChair < GAME_PLAYER); if (wChair <= GAME_PLAYER) pStat->options[wChair] = 2; } } iter_++; } } else { //非投票时间 pStat->leftTime = 255; } //发送场景 ASSERT(m_pIMainServiceFrame != NULL); GameInfo::PB_CS_S_StatusPlay Status; Status.mutable_gameconfig()->set_wsubgameid(pStat->gameConfig.wSubGameID); Status.mutable_gameconfig()->set_wplayrule(pStat->gameConfig.wDiScore); Status.mutable_gameconfig()->set_wmaxfanrule(pStat->gameConfig.wFanFei); Status.mutable_gameconfig()->set_wmaxscore(pStat->gameConfig.wIpLimit); Status.mutable_gameconfig()->set_wplaycountrule(pStat->gameConfig.wPlayCountRule); Status.mutable_gameconfig()->set_whadplaycount(pStat->gameConfig.wHadPlayCount); Status.mutable_gameconfig()->set_zmextrarule(pStat->gameConfig.IsOwner); Status.mutable_gameconfig()->set_dghrule(pStat->gameConfig.RoomId); std::string sPrivateTableID = CW2AEX<1024>(pStat->gameConfig.sPrivateTableID, CP_UTF8).m_psz; Status.mutable_gameconfig()->set_sprivatetableid(sPrivateTableID); Status.mutable_gameconfig()->set_bduolai(pStat->gameConfig.GameScoreType); Status.mutable_gameconfig()->set_wfengding(pStat->gameConfig.tmp2); Status.mutable_gameconfig()->set_tmp1(pStat->gameConfig.temp3); for (int i = 0; i < 4; i++) { Status.add_lusertmpscore(pStat->lUserTmpScore[i]); } Status.set_lefttime(pStat->leftTime); Status.set_wchairid(pStat->wchairId); for (int i = 0; i < 4; i++) { Status.add_options(pStat->options[i]); } for (BYTE j = 0; j < GAME_PLAYER; j++) { Status.add_bputcarddata(pStat->bPutCardData[j]); Status.add_cbcardcount(pStat->cbCardCount[j]); Status.add_cbweavecount(pStat->cbWeaveCount[j]); Status.add_cbdiscardcount(pStat->cbDiscardCount[j]); GameInfo::pb_cbDiscardCard* DiscardCard = Status.add_cbdiscardcard(); for (BYTE i = 0; i < pStat->cbDiscardCount[j]; i++) { DiscardCard->add_cbdiscardcard(pStat->cbDiscardCard[j][i]); } //Status.add_cbdiscardcard(DiscardCard); GameInfo::pb_WeaveItemArray* WeaveItemArray = Status.add_weaveitemarray(); for (BYTE i = 0; i < pStat->cbWeaveCount[j]; i++) { GameInfo::pb_WeaveItem* WeaveItem = WeaveItemArray->add_weaveitem(); WeaveItem->set_cbcentercard(pStat->WeaveItemArray[j][i].cbCenterCard); WeaveItem->set_cbpubliccard(pStat->WeaveItemArray[j][i].cbPublicCard); WeaveItem->set_cbweavekind(pStat->WeaveItemArray[j][i].cbWeaveKind); WeaveItem->set_wprovideuser(pStat->WeaveItemArray[j][i].wProvideUser); for (BYTE k = 0; k < 4; k++) { WeaveItem->add_cbmargicoffset(pStat->WeaveItemArray[j][i].cbMargicOffset[k]); } } } Status.set_cbtotalcardcount(pStat->cbTotalCardCount); Status.set_cbleftcardcount(pStat->cbLeftCardCount); Status.set_wbankeruser(pStat->wBankerUser); for (BYTE j = 0; j < 4; j++) { Status.add_lsizi(pStat->lSiZi[j]); } for (BYTE j = 0; j < 14; j++) { Status.add_cbcarddata(pStat->cbCardData[j]); } Status.set_dwownerid(pStat->dwOwnerID); Status.set_wcurrentuser(pStat->wCurrentUser); Status.set_totalopttime(pStat->totalOptTime); Status.set_leftopttime(pStat->leftOptTime); Status.set_cbactionmask(pStat->cbActionMask); for (BYTE j = 0; j < 6; j++) { Status.add_gangcards(pStat->gangCards[j]); } //发送数据 std::string pbdata = Status.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME,SUB_GF_GAME_SCENEING, (void*)pbdata.c_str(), pbdata.length()); } //开始判断 if ((pIServerUserItem->GetUserInfo()->cbUserStatus == US_READY) && (EfficacyStartGame(pIServerUserItem->GetUserInfo()->wChairID) == true)) { StartGame(); } return true; } //设置接口 bool CTableFrame::SetTableFrameHook(IUnknownEx * pIUnknownEx) { ASSERT(pIUnknownEx != NULL); if (pIUnknownEx == NULL) return false; //类型判断 if ((m_pGameServiceOption->wServerType&GAME_GENRE_MATCH) == 0) return false; //查询接口 m_pITableFrameHook = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITableFrameHook); m_pIMatchTableAction = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITableUserAction); return true; } //上线事件 bool CTableFrame::OnEventUserOnLine(IServerUserItem * pIServerUserItem) { //modify by picker,2016-8-29,增加玩家掉线重连机制 WORD wChairID = pIServerUserItem->GetChairID(); if (wChairID > m_wChairCount) return false; //添加校验 auto pIOldServerUserItem = GetTableUserItem(wChairID); if (pIOldServerUserItem == NULL)return false; if (pIOldServerUserItem->GetUserID() != pIServerUserItem->GetUserID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("断线重连失败:OnEventUserOnLine1:用户ID不匹配[ newUserID=%ld,oldUserID=%ld, tableID = %ld]"), pIServerUserItem->GetUserID(), pIOldServerUserItem->GetUserID(), _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); return false; } if (pIServerUserItem->GetTableID() != this->GetTableID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("断线重连校验:OnEventUserOnLine2:用户桌子ID不匹配[ pIServerUserItem=%ld,talbe=%ld, tableID = %ld]"), pIServerUserItem->GetTableID(), this->GetTableID(), _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); } m_TableUserItemArray[wChairID] = pIServerUserItem; if (IsGameStarted()) { //设置状态 pIServerUserItem->SetUserStatus(US_PLAYING, m_wTableID, wChairID); } else { if (m_wDrawCount >= 1) { pIServerUserItem->SetUserStatus(US_PLAYINGWAIT, m_wTableID, wChairID); } else { pIServerUserItem->SetUserStatus(US_READY, m_wTableID, wChairID); } } //发送桌子上所有用户信息 for (int j = 0; j < GetChairCount(); j++) { if (pIServerUserItem->GetChairID() == j) continue; IServerUserItem * pUser = GetTableUserItem(j); if (!pUser) continue; //检验添加提示 if (pUser->GetUserInfo()->wTableID != this->GetTableID()) { TCHAR szString[512] = { 0 }; _sntprintf(szString, CountArray(szString), TEXT("发现异常:OnEventUserOnLine3:用户ID不匹配[ userTableID=%ld,TableID=%ld,重连UserID=%ld,问题UserID=%ld,wChaird=%d,j=%d, PrivateTableID = %ld ]"), pUser->GetUserInfo()->wTableID, this->GetTableID(), pIServerUserItem->GetUserID(), pUser->GetUserID(), wChairID, j, _ttol(this->GetPrivateTableID().c_str())); CTraceService::TraceString(szString, TraceLevel_Warning); DismissGame(); return false; } //变量定义 tagMobileUserInfoHead pUserInfoHead; tagUserInfo *pUserInfo = pUser->GetUserInfo(); //用户属性 pUserInfoHead.wFaceID = pUserInfo->wFaceID; pUserInfoHead.dwGameID = pUserInfo->dwGameID; pUserInfoHead.dwUserID = pUserInfo->dwUserID; pUserInfoHead.dwCustomID = pUserInfo->dwCustomID; //用户属性 pUserInfoHead.cbGender = pUserInfo->cbGender; pUserInfoHead.cbMemberOrder = pUserInfo->cbMemberOrder; //用户状态 pUserInfoHead.wTableID = pUserInfo->wTableID; pUserInfoHead.wChairID = pUserInfo->wChairID; pUserInfoHead.cbUserStatus = pUserInfo->cbUserStatus; //用户局数 pUserInfoHead.dwWinCount = pUserInfo->dwWinCount; pUserInfoHead.dwLostCount = pUserInfo->dwLostCount; pUserInfoHead.dwDrawCount = pUserInfo->dwDrawCount; pUserInfoHead.dwFleeCount = pUserInfo->dwFleeCount; pUserInfoHead.dwExperience = pUserInfo->dwExperience; //用户成绩 pUserInfoHead.lScore = pUserInfo->lScore; pUserInfoHead.lScore += pUser->GetTrusteeScore(); pUserInfoHead.lScore += pUser->GetFrozenedScore(); pUserInfoHead.llDingWeiX = pUserInfo->dDingWeiX; pUserInfoHead.llDingWeiY = pUserInfo->dDingWeiY; pUserInfoHead.iJiePing = pUserInfo->llJiePing; pUserInfoHead.iXinYong = pUserInfo->iXinYong; lstrcpyn(pUserInfoHead.szNickname, pUserInfo->szNickName, CountArray(pUserInfo->szNickName)); //用户头像地址 lstrcpyn(pUserInfoHead.szHeadUrl, pUserInfo->szHeadUrl, CountArray(pUserInfo->szHeadUrl)); //IP地址 pUserInfoHead.dwClientAddr = pUser->GetClientAddr(); lstrcpyn(pUserInfoHead.RetTime, pUserInfo->RegisterDate, CountArray(pUserInfo->RegisterDate)); lstrcpyn(pUserInfoHead.ChengShi, pUserInfo->szChengShi, CountArray(pUserInfo->szChengShi)); UserInfo::PB_CS_S_tagMobileUserInfoHead UserInfoHead; UserInfoHead.set_wfaceid(pUserInfoHead.wFaceID); UserInfoHead.set_dwgameid(pUserInfoHead.dwGameID); UserInfoHead.set_dwuserid(pUserInfoHead.dwUserID); UserInfoHead.set_dwcustomid(pUserInfoHead.dwCustomID); UserInfoHead.set_cbgender(pUserInfoHead.cbGender); UserInfoHead.set_cbmemberorder(pUserInfoHead.cbMemberOrder); UserInfoHead.set_wtableid(pUserInfoHead.wTableID); UserInfoHead.set_wchairid(pUserInfoHead.wChairID); UserInfoHead.set_cbuserstatus(pUserInfoHead.cbUserStatus); UserInfoHead.set_lscore(pUserInfoHead.lScore); UserInfoHead.set_dwwincount(pUserInfoHead.dwWinCount); UserInfoHead.set_dwlostcount(pUserInfoHead.dwLostCount); UserInfoHead.set_dwdrawcount(pUserInfoHead.dwDrawCount); UserInfoHead.set_dwfleecount(pUserInfoHead.dwFleeCount); UserInfoHead.set_dwexperience(pUserInfoHead.dwExperience); std::string szNickname = CW2AEX<1024>(pUserInfoHead.szNickname, CP_UTF8).m_psz; std::string szHeadUrl = CW2AEX<1024>(pUserInfoHead.szHeadUrl, CP_UTF8).m_psz; std::string RetTime = CW2AEX<1024>(pUserInfoHead.RetTime, CP_UTF8).m_psz; std::string ChengShi = CW2AEX<1024>(pUserInfoHead.ChengShi, CP_UTF8).m_psz; UserInfoHead.set_sznickname(szNickname); UserInfoHead.set_szheadurl(szHeadUrl); UserInfoHead.set_dwclientaddr(pUserInfoHead.dwClientAddr); UserInfoHead.set_ixinyong(pUserInfoHead.iXinYong); UserInfoHead.set_rettime(RetTime); UserInfoHead.set_chengshi(ChengShi); UserInfoHead.set_lldingweix(pUserInfoHead.llDingWeiX); UserInfoHead.set_lldingweiy(pUserInfoHead.llDingWeiY); UserInfoHead.set_ijieping(pUserInfoHead.iJiePing); //发送数据 std::string pbdata = UserInfoHead.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_USER_ENTER, (void*)pbdata.c_str(), pbdata.length()); } //发送场景 bool bRet1 = m_pITableFrameSink->OnEventSendGameScene(pIServerUserItem->GetChairID(), pIServerUserItem, m_cbGameStatus, true); pIServerUserItem->SetClientReady(true); //重入 bool bRet2 = m_pITableUserAction->OnActionUserConnect(pIServerUserItem->GetChairID(), pIServerUserItem); return bRet1 && bRet2; } //断线事件 bool CTableFrame::OnEventUserOffLine(IServerUserItem * pIServerUserItem) { //参数效验 ASSERT(pIServerUserItem != NULL); if (pIServerUserItem == NULL) return false; //用户变量 tagUserInfo * pUserInfo = pIServerUserItem->GetUserInfo(); IServerUserItem * pITableUserItem = m_TableUserItemArray[pUserInfo->wChairID]; //用户属性 WORD wChairID = pIServerUserItem->GetChairID(); BYTE cbUserStatus = pIServerUserItem->GetUserStatus(); //游戏用户 if (cbUserStatus != US_LOOKON) { //效验用户 ASSERT(pIServerUserItem == GetTableUserItem(wChairID)); if (pIServerUserItem != GetTableUserItem(wChairID)) return false; //断线处理 if (!m_sPrivateTableID.empty() || ((cbUserStatus == US_PLAYING) && (m_wOffLineCount[wChairID] < MAX_OFF_LINE))) { //用户设置 pIServerUserItem->SetClientReady(false); pIServerUserItem->SetUserStatus(US_OFFLINE, m_wTableID, wChairID); //比赛类型 if (m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) { if (pIServerUserItem->IsTrusteeUser() == false) { //设置托管 pIServerUserItem->SetTrusteeUser(true); //掉线通知 if (m_pITableUserAction != NULL) m_pITableUserAction->OnActionUserOffLine(wChairID, pIServerUserItem); } return true; } //掉线通知 if (m_pITableUserAction != NULL) m_pITableUserAction->OnActionUserOffLine(wChairID, pIServerUserItem); //断线处理 if (m_dwOffLineTime[wChairID] == 0L && m_sPrivateTableID.empty()) { //设置变量 m_wOffLineCount[wChairID]++; m_dwOffLineTime[wChairID] = (DWORD)time(NULL); //时间设置 WORD wOffLineCount = GetOffLineUserCount(); if (wOffLineCount == 1) SetGameTimer(IDI_OFF_LINE, TIME_OFF_LINE, 1, wChairID); } return true; } } PerformStandUpAction(pIServerUserItem, true); if (m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) { if (pIServerUserItem->IsTrusteeUser() == true) return true; } //删除用户 ASSERT(pIServerUserItem->GetUserStatus() == US_FREE); pIServerUserItem->SetUserStatus(US_NULL, INVALID_TABLE, INVALID_CHAIR); return true; } //积分事件 bool CTableFrame::OnUserScroeNotify(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason) { //通知游戏 return m_pITableFrameSink->OnUserScroeNotify(wChairID, pIServerUserItem, cbReason); } //时间事件 bool CTableFrame::OnEventTimer(DWORD dwTimerID, WPARAM dwBindParameter) { //回调事件 if ((dwTimerID >= 0) && (dwTimerID < TIME_TABLE_SINK_RANGE)) { ASSERT(m_pITableFrameSink != NULL); return m_pITableFrameSink->OnTimerMessage(dwTimerID, dwBindParameter); } //事件处理 switch (dwTimerID) { case IDI_START_DISMISS_PRIVATE://申请解散私有房间超时 { int iNum = 0; int iNone = 0; for (std::unordered_map::iterator iter = m_AgreeDeletePriTableUsers.begin(); iter != m_AgreeDeletePriTableUsers.end(); iter++) { if (iter->second == 1) iNum++; //同意解散 else if (iter->second == 2) iNone++;//拒绝解散 } iNum = iNum + (m_wChairCount - iNum - iNone); //if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) ///---modify by yd 2017-12-26 产品变更解散规则 { //戳瞎子 if (iNone >= 1) { DeletePrivateResult(0, TEXT("有玩家反对,不能解散房间.")); if (m_pIMainServiceFrame->IsJC(8888)) { //输出信息 TCHAR szBuffer[128] = TEXT(""); TCHAR szTemp[32] = { 0 }; this->GetPrivateTableID(szTemp, 32); _sntprintf(szBuffer, CountArray(szBuffer), TEXT("有玩家反对,不能解散房间. 同意[ %d ], 拒绝 [ %d ], 好友房标识 [ %d ]."), iNum, iNone, szTemp); //输出信息 CTraceService::TraceString(szBuffer, TraceLevel_Normal); } return true; } else { m_bJieSan = true; if (m_pIMainServiceFrame->IsJC(8888)) { //输出信息 TCHAR szBuffer[128] = TEXT(""); TCHAR szTemp[32] = { 0 }; this->GetPrivateTableID(szTemp, 32); _sntprintf(szBuffer, CountArray(szBuffer), TEXT("根据少数服从多数的原则,房间已成功解散! 同意[ %d ], 拒绝 [ %d ], 好友房标识 [ %d ]."), iNum, iNone, szTemp); //输出信息 CTraceService::TraceString(szBuffer, TraceLevel_Normal); } return DeletePrivateResult(1, TEXT("全数玩家同意,房间已成功解散!")); } } //else //{ // if (iNone >= 2) // { // DeletePrivateResult(0, TEXT("根据少数服从多数的原则,不能解散房间.")); // if (m_pIMainServiceFrame->IsJC(8888)) // { // //输出信息 // TCHAR szBuffer[128] = TEXT(""); // TCHAR szTemp[32] = { 0 }; // this->GetPrivateTableID(szTemp, 32); // _sntprintf(szBuffer, CountArray(szBuffer), TEXT("根据少数服从多数的原则,不能解散房间. 同意[ %d ], 拒绝 [ %d ], 好友房标识 [ %d ]."), iNum, iNone, szTemp); // //输出信息 // CTraceService::TraceString(szBuffer, TraceLevel_Normal); // } // return true; // } // else // { // m_bJieSan = true; // if (m_pIMainServiceFrame->IsJC(8888)) // { // //输出信息 // TCHAR szBuffer[128] = TEXT(""); // TCHAR szTemp[32] = { 0 }; // this->GetPrivateTableID(szTemp, 32); // _sntprintf(szBuffer, CountArray(szBuffer), TEXT("根据少数服从多数的原则,房间已成功解散! 同意[ %d ], 拒绝 [ %d ], 好友房标识 [ %d ]."), iNum, iNone, szTemp); // //输出信息 // CTraceService::TraceString(szBuffer, TraceLevel_Normal); // } // return DeletePrivateResult(1, TEXT("根据少数服从多数的原则,房间已成功解散!")); // } //} return true; }break; case IDI_START_TIME://创建私有房间,超时未开始检测。 { KillGameTimer(IDI_START_TIME); //检查游戏状态是否开始。 if (this->GetStartCount() == 0) { //返还房主冻结元宝 UnAdminLockBeans(); //让所有人返回大厅,解散。 for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 if (m_TableUserItemArray[i] == NULL) continue; IServerUserItem * pIServerUserItem = m_TableUserItemArray[i]; SendGameMessage(pIServerUserItem, TEXT("此游戏桌已经超时解散了!"), SMT_TABLE_EXIT); //用户起立 PerformStandUpAction(pIServerUserItem, false, true); } //发送消息 for (INT_PTR i = 0; i < m_LookonUserItemArray.GetCount(); i++) { //获取用户 IServerUserItem * pILookonUserItem = m_LookonUserItemArray[i]; if (pILookonUserItem == NULL) continue; //发送消息 SendGameMessage(pILookonUserItem, TEXT("此游戏桌已经超时解散了!"), SMT_TABLE_EXIT); //用户离开 PerformStandUpAction(pILookonUserItem, false, true); } DeletePrivateTableNow(); return true; } } break; case IDI_STARTED_TIME: { KillGameTimer(IDI_STARTED_TIME); return DeletePrivateStarted(1, TEXT("房间超时,房间已成功解散!")); } break; case IDI_OFF_LINE: //断线事件 { //效验状态 ASSERT(m_bGameStarted == true); if (m_bGameStarted == false) return false; //变量定义 DWORD dwOffLineTime = 0L; WORD wOffLineChair = INVALID_CHAIR; //寻找用户 for (WORD i = 0; i < m_wChairCount; i++) { if ((m_dwOffLineTime[i] != 0L) && ((m_dwOffLineTime[i] < dwOffLineTime) || (wOffLineChair == INVALID_CHAIR))) { wOffLineChair = i; dwOffLineTime = m_dwOffLineTime[i]; } } //位置判断 ASSERT(wOffLineChair != INVALID_CHAIR); if (wOffLineChair == INVALID_CHAIR) return false; //用户判断 ASSERT(dwBindParameter < m_wChairCount); if (wOffLineChair != (WORD)dwBindParameter) { //时间计算 DWORD dwCurrentTime = (DWORD)time(NULL); DWORD dwLapseTime = dwCurrentTime - m_dwOffLineTime[wOffLineChair]; //设置时间 dwLapseTime = __min(dwLapseTime, TIME_OFF_LINE - 2000L); SetGameTimer(IDI_OFF_LINE, TIME_OFF_LINE - dwLapseTime, 1, wOffLineChair); return true; } //获取用户 ASSERT(GetTableUserItem(wOffLineChair) != NULL); IServerUserItem * pIServerUserItem = GetTableUserItem(wOffLineChair); //结束游戏 if (pIServerUserItem != NULL) { //设置变量 m_dwOffLineTime[wOffLineChair] = 0L; //用户起立 PerformStandUpAction(pIServerUserItem); } //继续时间 if (m_bGameStarted == true) { //变量定义 DWORD dwOffLineTime = 0L; WORD wOffLineChair = INVALID_CHAIR; //寻找用户 for (WORD i = 0; i < m_wChairCount; i++) { if ((m_dwOffLineTime[i] != 0L) && ((m_dwOffLineTime[i] < dwOffLineTime) || (wOffLineChair == INVALID_CHAIR))) { wOffLineChair = i; dwOffLineTime = m_dwOffLineTime[i]; } } //设置时间 if (wOffLineChair != INVALID_CHAIR) { //时间计算 DWORD dwCurrentTime = (DWORD)time(NULL); DWORD dwLapseTime = dwCurrentTime - m_dwOffLineTime[wOffLineChair]; //设置时间 dwLapseTime = __min(dwLapseTime, TIME_OFF_LINE - 2000L); SetGameTimer(IDI_OFF_LINE, TIME_OFF_LINE - dwLapseTime, 1, wOffLineChair); } } return true; } } //未开始超时 if (dwTimerID >= IDI_START_OVERTIME && dwTimerID <= IDI_START_OVERTIME_END) { //变量定义 WORD wChair = (WORD)dwBindParameter; // if (wChair != (WORD)(dwTimerID - IDI_START_OVERTIME)) return false; //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(wChair); //超时处理 if (pIServerUserItem && pIServerUserItem->GetUserStatus() == US_SIT) { //用户起立 PerformStandUpAction(pIServerUserItem); } return false; } //错误断言 ASSERT(FALSE); return false; } //游戏事件 bool CTableFrame::OnEventSocketGame(WORD wSubCmdID, VOID * pData, WORD wDataSize, IServerUserItem * pIServerUserItem) { //效验参数 ASSERT(pIServerUserItem != NULL); ASSERT(m_pITableFrameSink != NULL); //消息处理 return m_pITableFrameSink->OnGameMessage(wSubCmdID, pData, wDataSize, pIServerUserItem); } //设置游戏配置 void CTableFrame::OnEventSetGameConfig(VOID * pData, WORD wDataSize, std::wstring sPrivateRoomId) { //效验参数 ASSERT(m_pITableFrameSink != NULL); this->GetChairCount(); //消息处理 return this->m_pITableFrameSink->SetGameConfig(pData, wDataSize, sPrivateRoomId); } //框架事件 bool CTableFrame::OnEventSocketFrame(WORD wSubCmdID, VOID * pData, WORD wDataSize, IServerUserItem * pIServerUserItem) { //游戏处理 if (m_pITableFrameSink->OnFrameMessage(wSubCmdID, pData, wDataSize, pIServerUserItem) == true) return true; //默认处理 switch (wSubCmdID) { case SUB_GF_GAME_OPTION: //游戏配置 { return false; //效验参数 //ASSERT(wDataSize == sizeof(CMD_GF_GameOption)); //if (wDataSize != sizeof(CMD_GF_GameOption)) return false; //变量定义 //CMD_GF_GameOption * pGameOption = (CMD_GF_GameOption *)pData; //获取属性 WORD wChairID = pIServerUserItem->GetChairID(); BYTE cbUserStatus = pIServerUserItem->GetUserStatus(); //断线清理 if ((cbUserStatus != US_LOOKON) && ((m_dwOffLineTime[wChairID] != 0L))) { //设置变量 m_dwOffLineTime[wChairID] = 0L; //删除时间 WORD wOffLineCount = GetOffLineUserCount(); if (wOffLineCount == 0) KillGameTimer(IDI_OFF_LINE); } //设置状态 pIServerUserItem->SetClientReady(true); //if (cbUserStatus != US_LOOKON) m_bAllowLookon[wChairID] = pGameOption->cbAllowLookon ? true : false; //发送状态 //CMD_GF_GameStatus GameStatus; //GameStatus.cbGameStatus = m_cbGameStatus; //GameStatus.cbAllowLookon = m_bAllowLookon[wChairID] ? TRUE : FALSE; //m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME, SUB_GF_GAME_STATUS, &GameStatus, sizeof(GameStatus)); //发送消息 //TCHAR szMessage[128] = TEXT(""); //_sntprintf(szMessage, CountArray(szMessage), TEXT("欢迎您进入“%s”游戏,祝您游戏愉快!"), m_pGameServiceAttrib->szGameName); //m_pIMainServiceFrame->SendGameMessage(pIServerUserItem, szMessage, SMT_CHAT); //发送场景 bool bSendSecret = ((cbUserStatus != US_LOOKON) || (m_bAllowLookon[wChairID] == true)); m_pITableFrameSink->OnEventSendGameScene(wChairID, pIServerUserItem, m_cbGameStatus, bSendSecret); //取消托管 if (m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) { if (pIServerUserItem->IsTrusteeUser() == true) { //设置托管 pIServerUserItem->SetTrusteeUser(false); } //回归通知 //if(m_pITableFrameHook) m_pITableFrameHook->OnUserBackMatch(this,pIServerUserItem); } //开始判断 if ((cbUserStatus == US_READY) && (EfficacyStartGame(wChairID) == true)) { StartGame(); } return true; } case SUB_GF_USER_READY: //用户准备 { //获取属性 WORD wChairID = pIServerUserItem->GetChairID(); BYTE cbUserStatus = pIServerUserItem->GetUserStatus(); //效验状态 ASSERT(GetTableUserItem(wChairID) == pIServerUserItem); if (GetTableUserItem(wChairID) != pIServerUserItem) return false; //效验状态 //ASSERT(cbUserStatus==US_SIT); if (cbUserStatus != US_SIT && cbUserStatus != US_PLAYINGWAIT) return true; //防作弊分组判断 if ((CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule) && (m_pGameServiceAttrib->wChairCount < MAX_CHAIR)) && (m_wDrawCount >= m_pGameServiceOption->wDistributeDrawCount || CheckDistribute())) { //发送消息 LPCTSTR pszMessage = TEXT("系统重新分配桌子,请稍后!"); SendRequestFailure(pIServerUserItem, pszMessage, 0); //发送消息 m_pIMainServiceFrame->InsertDistribute(pIServerUserItem); ////用户起立 //PerformStandUpAction(pIServerUserItem); return true; } //事件通知 if (m_pIMatchTableAction != NULL && !m_pIMatchTableAction->OnActionUserOnReady(wChairID, pIServerUserItem, pData, wDataSize)) { return true; } //事件通知 if (m_pITableUserAction != NULL) { m_pITableUserAction->OnActionUserOnReady(wChairID, pIServerUserItem, pData, wDataSize); } if (m_sPrivateTableID.empty()) { //删除定时 if (m_pGameServiceAttrib->wChairCount < MAX_CHAIR) KillGameTimer(IDI_START_OVERTIME + wChairID); } pIServerUserItem->SetClientReady(true); //设置状态 pIServerUserItem->SetUserStatus(US_READY, m_wTableID, wChairID); if (m_wStartCount > 0) { m_GameRead[wChairID] = true; } //开始判断 if (EfficacyStartGame(wChairID)) { USER_SHUFFLE_ALL_ACK ss; ZeroMemory(&ss, sizeof(ss)); DWORD dwUserID = INVALID_DWORD, nIndex = 0; for (WORD i = 0; i < m_wChairCount; i++) { if (!m_GameShuffleRead[i])continue; lstrcpyn(ss.dwUserName[nIndex], m_TableUserItemArray[i]->GetNickName(), CountArray(ss.dwUserName[nIndex])); dwUserID = m_TableUserItemArray[i]->GetUserID(); DeductWLZuanshi(dwUserID);//开始洗牌 准备扣钻 nIndex++; } ss.cbCount = nIndex; GameInfo::PB_CS_S_SHUFFLE_ALL_ACK Shuffle; Shuffle.set_cbcount(ss.cbCount); for (WORD i = 0; i < m_wChairCount; i++) { GameInfo::pb_dwUserName* UserName = Shuffle.add_dwusername(); std::string dwUserName = CW2AEX<1024>(ss.dwUserName[i], CP_UTF8).m_psz; UserName->set_dwusername(dwUserName); } //发送数据 std::string pbdata = Shuffle.SerializePartialAsString(); //发送消息 if (0 < nIndex) SendTableData(INVALID_CHAIR, SUB_GF_USER_SHUFFLE_ALL_ACK, (void*)pbdata.c_str(), pbdata.length()); StartGame(); } return true; } case SUB_GF_USER_SHUFFLE: //洗牌准备 { //获取属性 WORD wChairID = pIServerUserItem->GetChairID(); BYTE cbUserStatus = pIServerUserItem->GetUserStatus(); //效验状态 ASSERT(GetTableUserItem(wChairID) == pIServerUserItem); if (GetTableUserItem(wChairID) != pIServerUserItem) return false; //效验状态 //ASSERT(cbUserStatus==US_SIT); if (cbUserStatus != US_SIT && cbUserStatus != US_PLAYINGWAIT) return true; if (m_sPrivateTableID.empty()) { //删除定时 if (m_pGameServiceAttrib->wChairCount < MAX_CHAIR) KillGameTimer(IDI_START_OVERTIME + wChairID); } pIServerUserItem->SetClientReady(true); //设置状态 pIServerUserItem->SetUserStatus(US_READY, m_wTableID, wChairID); if (m_wStartCount > 0) { m_GameRead[wChairID] = true; m_GameShuffleRead[wChairID] = true; } //开始判断 if (EfficacyStartGame(wChairID)) { USER_SHUFFLE_ALL_ACK ss; ZeroMemory(&ss, sizeof(ss)); DWORD dwUserID = INVALID_DWORD, nIndex = 0; for (WORD i = 0; i < m_wChairCount; i++) { if (!m_GameShuffleRead[i])continue; lstrcpyn(ss.dwUserName[nIndex], m_TableUserItemArray[i]->GetNickName(), CountArray(ss.dwUserName[nIndex])); dwUserID = m_TableUserItemArray[i]->GetUserID(); DeductWLZuanshi(dwUserID);//开始洗牌 准备扣钻 nIndex++; } ss.cbCount = nIndex; GameInfo::PB_CS_S_SHUFFLE_ALL_ACK Shuffle; Shuffle.set_cbcount(ss.cbCount); for (WORD i = 0; i < m_wChairCount; i++) { GameInfo::pb_dwUserName* UserName = Shuffle.add_dwusername(); std::string dwUserName = CW2AEX<1024>(ss.dwUserName[i], CP_UTF8).m_psz; UserName->set_dwusername(dwUserName); } //发送数据 std::string pbdata = Shuffle.SerializePartialAsString(); //发送消息 if (0 < nIndex) SendTableData(INVALID_CHAIR, SUB_GF_USER_SHUFFLE_ALL_ACK, (void*)pbdata.c_str(), pbdata.length()); StartGame(); } return true; } case SUB_GF_GAME_USER_DISTANCE: //玩家距离 @yuanjing { //获取属性 WORD wChairID = pIServerUserItem->GetChairID(); BYTE cbUserStatus = pIServerUserItem->GetUserStatus(); //效验状态 ASSERT(GetTableUserItem(wChairID) == pIServerUserItem); if (GetTableUserItem(wChairID) != pIServerUserItem) return false; //效验状态 //if (cbUserStatus != US_SIT) return false; //构造消息 CMD_GF_UserDistance UserDistance; ZeroMemory(&UserDistance, sizeof(UserDistance)); //游戏用户 WORD count = 0; for (WORD i = 0; i < GAME_PLAYER; i++) { //获取用户 IServerUserItem * pIServerUserItem1 = GetTableUserItem(i); //位置没有用户 if (pIServerUserItem1 == NULL) { //该位置没用户则与其他位置距离为0; for (WORD k = i + 1; k < GAME_PLAYER; k++) { UserDistance.dwUserDistance[count++] = 0; } //所以当前位置定位也没有开启(未开启=0,开启=1) UserDistance.cbOperLocation[i] = 0; continue; } //位置不为空则获取当前位置用户的坐标 BaiDuMap aa; LONGLONG llx1 = pIServerUserItem1->GetUserInfo()->dDingWeiX; LONGLONG lly1 = pIServerUserItem1->GetUserInfo()->dDingWeiY; double dX1 = (double)llx1 / (double)1000000; double dY1 = (double)lly1 / (double)1000000; //判断当前位置用户是否开启定位 if ((int)dX1 != 0 && (int)dY1 != 0) { UserDistance.cbOperLocation[i] = 1; } else { UserDistance.cbOperLocation[i] = 0; } for (WORD j = i + 1; j < GAME_PLAYER; j++) { //获取用户 IServerUserItem * pIServerUserItem2 = GetTableUserItem(j); //该位置没有用户 if (pIServerUserItem2 == NULL) { //该位置没有用户则距离设置为0 UserDistance.dwUserDistance[count++] = 0; continue; } //该位置有用户 LONGLONG llx2 = pIServerUserItem2->GetUserInfo()->dDingWeiX; LONGLONG lly2 = pIServerUserItem2->GetUserInfo()->dDingWeiY; double dX2 = (double)llx2 / (double)1000000; double dY2 = (double)lly2 / (double)1000000; if ((int)dX1 != 0 && (int)dY1 != 0 && (int)dX2 != 0 && (int)dY2 != 0) { double dRet = aa.GetShortDistance(dX1, dY1, dX2, dY2); if (dRet >= 2000) { dRet = 2000; } UserDistance.dwUserDistance[count++] = (int)dRet; } else { UserDistance.dwUserDistance[count++] = 0; } } } GameInfo::PB_CS_S_UserDistance Distance; for (WORD i = 0; i < 4; i++) { Distance.add_cboperlocation(UserDistance.cbOperLocation[i]); } for (WORD i = 0; i < 6; i++) { Distance.add_dwuserdistance(UserDistance.dwUserDistance[i]); } //发送数据 std::string pbdata = Distance.SerializePartialAsString(); //只发送个当前用户 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME, SUB_GF_GAME_USER_DISTANCE, (void*)pbdata.c_str(), pbdata.length()); return true; } case SUB_GF_USER_CHAT: //用户聊天 { //效验参数 GameInfo::PB_CS_UserChat UserChats; UserChats.ParseFromArray(pData, wDataSize); //处理消息 CMD_GF_C_UserChat pUserChat; ZeroMemory(&pUserChat, sizeof(pUserChat)); pUserChat.wChatLength = UserChats.wchatlength(); pUserChat.dwChatColor = UserChats.dwchatcolor(); pUserChat.dwTargetUserID = UserChats.dwtargetuserid(); CString szchatstring = (CA2CTEX<2048>(UserChats.szchatstring().c_str(), CP_UTF8)).m_szBuffer; CopyMemory(pUserChat.szChatString, szchatstring, sizeof(pUserChat.szChatString)); //目标用户 if ((pUserChat.dwTargetUserID != 0) && (SearchUserItem(pUserChat.dwTargetUserID) == NULL)) { ASSERT(FALSE); return true; } //状态判断 if ((CServerRule::IsForfendGameChat(m_pGameServiceOption->dwServerRule) == true) && (pIServerUserItem->GetMasterOrder() == 0L)) { SendRequestFailure(pIServerUserItem, TEXT("抱歉,当前游戏房间禁止游戏聊天!"), 0); return true; } //权限判断 if (CUserRight::CanRoomChat(pIServerUserItem->GetUserRight()) == false) { SendRequestFailure(pIServerUserItem, TEXT("抱歉,您没有游戏聊天的权限,若需要帮助,请联系游戏客服咨询!"), 0); //SendGameMessage(pIServerUserItem, TEXT("抱歉,您没有游戏聊天的权限,若需要帮助,请联系游戏客服咨询!"), SMT_EJECT | SMT_CHAT); return true; } //构造消息 CMD_GF_S_UserChat UserChat; ZeroMemory(&UserChat, sizeof(UserChat)); StringCchCat(UserChat.szChatString, LEN_USER_CHAT, pUserChat.szChatString); //字符过滤 //m_pIMainServiceFrame->SensitiveWordFilter(pUserChat->szChatString, UserChat.szChatString, CountArray(UserChat.szChatString)); //构造数据 UserChat.dwChatColor = pUserChat.dwChatColor; UserChat.wChatLength = pUserChat.wChatLength; UserChat.dwTargetUserID = pUserChat.dwTargetUserID; UserChat.dwSendUserID = pIServerUserItem->GetUserID(); //UserChat.wChatLength = CountStringBuffer(UserChat.szChatString); //发送数据 WORD wHeadSize = sizeof(UserChat) - sizeof(UserChat.szChatString); WORD wSendSize = wHeadSize + UserChat.wChatLength * sizeof(UserChat.szChatString[0]); //游戏用户 for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem* pIServerUserItem = GetTableUserItem(i); if ((pIServerUserItem == NULL) || (pIServerUserItem->IsClientReady() == false)) continue; GameInfo::PB_CS_UserChat Chat; Chat.set_dwchatcolor(UserChat.dwChatColor); Chat.set_wchatlength(UserChat.wChatLength); Chat.set_dwtargetuserid(UserChat.dwTargetUserID); Chat.set_dwsenduserid(UserChat.dwSendUserID); std::string szChatString = CW2AEX<1024>(UserChat.szChatString, CP_UTF8).m_psz; Chat.set_szchatstring(szChatString); //发送数据 std::string pbdata = Chat.SerializePartialAsString(); //发送消息 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME, SUB_GF_USER_CHAT, (void*)pbdata.c_str(), pbdata.length()); } //旁观用户 WORD wEnumIndex = 0; IServerUserItem* pIServerUserItem = NULL; //枚举用户 do { //获取用户 pIServerUserItem = EnumLookonUserItem(wEnumIndex++); if (pIServerUserItem == NULL) break; //发送数据 if (pIServerUserItem->IsClientReady() == true) { GameInfo::PB_CS_UserChat Chat; Chat.set_dwchatcolor(UserChat.dwChatColor); Chat.set_wchatlength(UserChat.wChatLength); Chat.set_dwtargetuserid(UserChat.dwTargetUserID); Chat.set_dwsenduserid(UserChat.dwSendUserID); std::string szChatString = CW2AEX<1024>(UserChat.szChatString, CP_UTF8).m_psz; Chat.set_szchatstring(szChatString); //发送数据 std::string pbdata = Chat.SerializePartialAsString(); //发送消息 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME, SUB_GF_USER_CHAT, (void*)pbdata.c_str(), pbdata.length()); } } while (true); return true; } case SUB_GF_USER_EXPRESSION: //用户表情 { //效验参数 GameInfo::PB_CS_UserExpression Expression; Expression.ParseFromArray(pData, wDataSize); //处理消息 CMD_GF_C_UserExpression pUserExpression; ZeroMemory(&pUserExpression, sizeof(pUserExpression)); pUserExpression.wItemIndex = Expression.witemindex(); pUserExpression.dwTargetUserID = Expression.dwtargetuserid(); //目标用户 if ((pUserExpression.dwTargetUserID != 0) && (SearchUserItem(pUserExpression.dwTargetUserID) == NULL)) { ASSERT(FALSE); return true; } //状态判断 if ((CServerRule::IsForfendGameChat(m_pGameServiceOption->dwServerRule) == true) && (pIServerUserItem->GetMasterOrder() == 0L)) { SendRequestFailure(pIServerUserItem, TEXT("抱歉,当前游戏房间禁止游戏聊天!"), 0); //SendGameMessage(pIServerUserItem, TEXT("抱歉,当前游戏房间禁止游戏聊天!"), SMT_CHAT); return true; } //权限判断 if (CUserRight::CanRoomChat(pIServerUserItem->GetUserRight()) == false) { SendRequestFailure(pIServerUserItem, TEXT("抱歉,您没有游戏聊天的权限,若需要帮助,请联系游戏客服咨询!"), 0); //SendGameMessage(pIServerUserItem, TEXT("抱歉,您没有游戏聊天的权限,若需要帮助,请联系游戏客服咨询!"), SMT_EJECT | SMT_CHAT); return true; } //构造消息 CMD_GR_S_UserExpression UserExpression; ZeroMemory(&UserExpression, sizeof(UserExpression)); //构造数据 UserExpression.wItemIndex = pUserExpression.wItemIndex; UserExpression.dwSendUserID = pIServerUserItem->GetUserID(); UserExpression.dwTargetUserID = pUserExpression.dwTargetUserID; //游戏用户 for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem* pIServerUserItem = GetTableUserItem(i); if ((pIServerUserItem == NULL) || (pIServerUserItem->IsClientReady() == false)) continue; //发送数据 if (pIServerUserItem->IsClientReady() == true) { GameInfo::PB_CS_UserExpression Expressions; Expressions.set_witemindex(UserExpression.wItemIndex); Expressions.set_dwsenduserid(UserExpression.dwSendUserID); Expressions.set_dwtargetuserid(UserExpression.dwTargetUserID); //发送数据 std::string pbdata = Expressions.SerializePartialAsString(); //发送消息 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME, SUB_GF_USER_EXPRESSION, (void*)pbdata.c_str(), pbdata.length()); } } //旁观用户 WORD wEnumIndex = 0; IServerUserItem* pIServerUserItem = NULL; //枚举用户 do { //获取用户 pIServerUserItem = EnumLookonUserItem(wEnumIndex++); if (pIServerUserItem == NULL) break; //发送数据 if (pIServerUserItem->IsClientReady() == true) { GameInfo::PB_CS_UserExpression Expressions; Expressions.set_witemindex(UserExpression.wItemIndex); Expressions.set_dwsenduserid(UserExpression.dwSendUserID); Expressions.set_dwtargetuserid(UserExpression.dwTargetUserID); //发送数据 std::string pbdata = Expressions.SerializePartialAsString(); //发送消息 m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GF_FRAME, SUB_GF_USER_EXPRESSION, (void*)pbdata.c_str(), pbdata.length()); } } while (true); return true; } case SUB_GF_LOOKON_CONFIG: //旁观配置 { //效验参数 /*ASSERT(wDataSize == sizeof(CMD_GF_LookonConfig)); if (wDataSize < sizeof(CMD_GF_LookonConfig)) return false; //变量定义 CMD_GF_LookonConfig * pLookonConfig = (CMD_GF_LookonConfig *)pData; //目标用户 if ((pLookonConfig->dwUserID != 0) && (SearchUserItem(pLookonConfig->dwUserID) == NULL)) { ASSERT(FALSE); return true; } //用户效验 ASSERT(pIServerUserItem->GetUserStatus() != US_LOOKON); if (pIServerUserItem->GetUserStatus() == US_LOOKON) return false; //旁观处理 if (pLookonConfig->dwUserID != 0L) { for (INT_PTR i = 0; i < m_LookonUserItemArray.GetCount(); i++) { //获取用户 IServerUserItem * pILookonUserItem = m_LookonUserItemArray[i]; if (pILookonUserItem->GetUserID() != pLookonConfig->dwUserID) continue; //if (pILookonUserItem->GetChairID() != pIServerUserItem->GetChairID()) continue; //构造消息 CMD_GF_LookonStatus LookonStatus; LookonStatus.cbAllowLookon = pLookonConfig->cbAllowLookon; //发送消息 ASSERT(m_pIMainServiceFrame != NULL); m_pIMainServiceFrame->SendData(pILookonUserItem, MDM_GF_FRAME, SUB_GF_LOOKON_STATUS, &LookonStatus, sizeof(LookonStatus)); break; } } else { //设置判断 bool bAllowLookon = (pLookonConfig->cbAllowLookon == TRUE) ? true : false; if (bAllowLookon == m_bAllowLookon[pIServerUserItem->GetChairID()]) return true; //设置变量 m_bAllowLookon[pIServerUserItem->GetChairID()] = bAllowLookon; //构造消息 CMD_GF_LookonStatus LookonStatus; LookonStatus.cbAllowLookon = pLookonConfig->cbAllowLookon; //发送消息 for (INT_PTR i = 0; i < m_LookonUserItemArray.GetCount(); i++) { //获取用户 IServerUserItem * pILookonUserItem = m_LookonUserItemArray[i]; if (pILookonUserItem->GetChairID() != pIServerUserItem->GetChairID()) continue; //发送消息 ASSERT(m_pIMainServiceFrame != NULL); m_pIMainServiceFrame->SendData(pILookonUserItem, MDM_GF_FRAME, SUB_GF_LOOKON_STATUS, &LookonStatus, sizeof(LookonStatus)); } } return true;*/ } } return false; } //游戏局数 WORD CTableFrame::GetDrawCount() { return m_wDrawCount; } //获取空位 WORD CTableFrame::GetNullChairIDWithoutHost() { //椅子搜索 for (WORD i = 1; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] == NULL) { return i; } } return INVALID_CHAIR; } //获取空位 WORD CTableFrame::GetNullChairID() { //椅子搜索 for (WORD i = 0; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] == NULL) { return i; } } return INVALID_CHAIR; } //随机空位 WORD CTableFrame::GetRandNullChairID() { //椅子搜索 WORD wIndex = rand() % m_wChairCount; for (WORD i = wIndex; i < m_wChairCount + wIndex; i++) { if (m_TableUserItemArray[i%m_wChairCount] == NULL) { return i%m_wChairCount; } } return INVALID_CHAIR; } //用户数目 WORD CTableFrame::GetSitUserCount() { //变量定义 WORD wUserCount = 0; //数目统计 for (WORD i = 0; i < m_wChairCount; i++) { if (GetTableUserItem(i) != NULL) { wUserCount++; } } return wUserCount; } //旁观数目 WORD CTableFrame::GetLookonUserCount() { //获取数目 INT_PTR nLookonCount = m_LookonUserItemArray.GetCount(); return (WORD)(nLookonCount); } //断线数目 WORD CTableFrame::GetOffLineUserCount() { //变量定义 WORD wOffLineCount = 0; //断线人数 for (WORD i = 0; i < m_wChairCount; i++) { if (m_dwOffLineTime[i] != 0L) { wOffLineCount++; } } return wOffLineCount; } //桌子状况 WORD CTableFrame::GetTableUserInfo(tagTableUserInfo & TableUserInfo) { //设置变量 ZeroMemory(&TableUserInfo, sizeof(TableUserInfo)); //用户分析 for (WORD i = 0; i < m_pGameServiceAttrib->wChairCount; i++) { //获取用户 IServerUserItem * pIServerUserItem = GetTableUserItem(i); if (pIServerUserItem == NULL) continue; //用户类型 if (pIServerUserItem->IsAndroidUser() == false) { TableUserInfo.wTableUserCount++; } else { TableUserInfo.wTableAndroidCount++; } //准备判断 if (pIServerUserItem->GetUserStatus() == US_READY) { TableUserInfo.wTableReadyCount++; } } //最少数目 switch (m_cbStartMode) { case START_MODE_ALL_READY: //所有准备 { TableUserInfo.wMinUserCount = 2; break; } case START_MODE_PAIR_READY: //配对开始 { TableUserInfo.wMinUserCount = 2; break; } case START_MODE_TIME_CONTROL: //时间控制 { TableUserInfo.wMinUserCount = 1; break; } default: //默认模式 { TableUserInfo.wMinUserCount = m_pGameServiceAttrib->wChairCount; break; } } return TableUserInfo.wTableAndroidCount + TableUserInfo.wTableUserCount; } //配置桌子 bool CTableFrame::InitializationFrame(WORD wTableID, tagTableFrameParameter & TableFrameParameter, WORD wGameType) { //设置变量 m_wTableID = wTableID; m_wChairCount = TableFrameParameter.pGameServiceAttrib->wChairCount; //配置参数 m_pGameParameter = TableFrameParameter.pGameParameter; m_pGameServiceAttrib = TableFrameParameter.pGameServiceAttrib; m_pGameServiceOption = TableFrameParameter.pGameServiceOption; //组件接口 m_pITimerEngine = TableFrameParameter.pITimerEngine; m_pIMainServiceFrame = TableFrameParameter.pIMainServiceFrame; m_pIAndroidUserManager = TableFrameParameter.pIAndroidUserManager; m_pIKernelDataBaseEngine = TableFrameParameter.pIKernelDataBaseEngine; m_pIRecordDataBaseEngine = TableFrameParameter.pIRecordDataBaseEngine; //创建桌子 IGameServiceManager * pIGameServiceManager = TableFrameParameter.pIGameServiceManager; if (wGameType < 3) { m_pITableFrameSink = (ITableFrameSink *)pIGameServiceManager->CreateTableFrameSink(IID_ITableFrameSink, VER_ITableFrameSink); } else if (wGameType >= 3 && wGameType <= 5) { m_pITableFrameSink = (ITableFrameSink *)pIGameServiceManager->CreateTableFrameSink(IID_ITableFrameSink, VER_ITableFrameSinkCxz); } else if (wGameType >= 10 && wGameType < 14) { m_pITableFrameSink = (ITableFrameSink *)pIGameServiceManager->CreateTableFrameSink(IID_ITableFrameSink, VER_ITableFrameSinkOther); } else if (wGameType >= 14 && wGameType <= 16) { m_pITableFrameSink = (ITableFrameSink *)pIGameServiceManager->CreateTableFrameSink(IID_ITableFrameSink, VER_ITableFrameSinkZhiPai); } else { m_pITableFrameSink = (ITableFrameSink *)pIGameServiceManager->CreateTableFrameSink(IID_ITableFrameSink, VER_ITableFrameSink); } //错误判断 if (m_pITableFrameSink == NULL) { //ASSERT(FALSE); return false; } //设置变量 m_lCellScore = m_pGameServiceOption->lCellScore; //设置桌子 IUnknownEx * pITableFrame = QUERY_ME_INTERFACE(IUnknownEx); if (m_pITableFrameSink->Initialization(pITableFrame) == false) return false; //设置标识 m_bTableInitFinish = true; //扩展接口 m_pITableUserAction = QUERY_OBJECT_PTR_INTERFACE(m_pITableFrameSink, ITableUserAction); m_pITableUserRequest = QUERY_OBJECT_PTR_INTERFACE(m_pITableFrameSink, ITableUserRequest); return true; } //用户创建私有房间 bool CTableFrame::OnTCPNetworkSubUserCreateRoom(IServerUserItem * pIServerUserItem) { //建立定时器 SetGameTimer(IDI_START_TIME, TIME_CREATE_OUT, 1, 0); return true; } //起立动作 bool CTableFrame::PerformStandUpAction(IServerUserItem * pIServerUserItem, bool bInitiative/*=false*/, bool bSendState) { //效验参数 ASSERT(pIServerUserItem != NULL); ASSERT(pIServerUserItem->GetTableID() == m_wTableID); //如果是旁观的状态。则让此人离开。 bool currUserLookOn = false; for (INT_PTR i = 0; i < m_LookonUserItemArray.GetCount(); i++) { if (pIServerUserItem == m_LookonUserItemArray[i]) { //删除子项 currUserLookOn = true; m_LookonUserItemArray.RemoveAt(i); break; } } if (pIServerUserItem->GetUserStatus() == US_LOOKON) { if (currUserLookOn) { //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR, bSendState); return true; } return true; } ASSERT(pIServerUserItem->GetChairID() <= m_wChairCount); //用户属性 WORD wChairID = pIServerUserItem->GetChairID(); BYTE cbUserStatus = pIServerUserItem->GetUserStatus(); IServerUserItem * pITableUserItem = GetTableUserItem(wChairID); //游戏用户 if ((m_bGameStarted == true) && ((cbUserStatus == US_PLAYING) || (cbUserStatus == US_PLAYINGWAIT) || (cbUserStatus == US_OFFLINE))) { //比赛类型 if (m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) { //设置托管 pIServerUserItem->SetTrusteeUser(true); //掉线通知 if (m_pITableUserAction != NULL) m_pITableUserAction->OnActionUserOffLine(wChairID, pIServerUserItem); return true; } //结束游戏 BYTE cbConcludeReason = (cbUserStatus == US_OFFLINE) ? GER_NETWORK_ERROR : GER_USER_LEAVE; m_pITableFrameSink->OnEventGameConclude(wChairID, pIServerUserItem, cbConcludeReason); //告诉游戏模块 断线了 或是有人强退了 //离开判断 if (m_TableUserItemArray[wChairID] != pIServerUserItem) return true; } else { CAttemperEngineSink * pAttemperEngineSink = (CAttemperEngineSink *)m_pIMainServiceFrame; pAttemperEngineSink->SetUserServerID(pIServerUserItem, 0, 0);//通知协调服务器 这个用户已经离开了桌子。 } if ((m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) && (bInitiative == true)) { if (pIServerUserItem->IsTrusteeUser() == false) { pIServerUserItem->SetTrusteeUser(true); //掉线通知 if (m_pITableUserAction != NULL) m_pITableUserAction->OnActionUserOffLine(wChairID, pIServerUserItem); } return true; } //设置变量 if (pIServerUserItem == pITableUserItem) { if (m_sPrivateTableID.empty()) { //公共房间开启准备超时定时器。 //删除定时 if (m_pGameServiceAttrib->wChairCount < MAX_CHAIR) KillGameTimer(IDI_START_OVERTIME + wChairID); } //设置变量 m_TableUserItemArray[wChairID] = NULL; //解锁游戏币 if (m_lFrozenedScore[wChairID] != 0L) { pIServerUserItem->UnFrozenedUserScore(m_lFrozenedScore[wChairID]); m_lFrozenedScore[wChairID] = 0L; } //事件通知 if (m_pITableUserAction != NULL) { m_pITableUserAction->OnActionUserStandUp(wChairID, pIServerUserItem, false); } //事件通知 if (m_pIMatchTableAction != NULL) m_pIMatchTableAction->OnActionUserStandUp(wChairID, pIServerUserItem, false); //用户状态 //pIServerUserItem->SetClientReady(false); pIServerUserItem->SetUserStatus((cbUserStatus == US_OFFLINE) ? US_NULL : US_FREE, INVALID_TABLE, INVALID_CHAIR, bSendState); //变量定义 bool bTableLocked = IsTableLocked(); bool bTableStarted = IsTableStarted(); WORD wTableUserCount = GetSitUserCount(); //设置变量 m_wUserCount = wTableUserCount; //桌子信息 if (wTableUserCount == 0) { m_dwTableOwnerID = 0L; m_szEnterPassword[0] = 0; } //结束桌子 ConcludeTable(); //发送状态 if ((bTableLocked != IsTableLocked()) || (bTableStarted != IsTableStarted())) { SendTableStatus(); } //防作弊分组判断 if (CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule) && (m_pGameServiceAttrib->wChairCount < MAX_CHAIR)) { //防作弊分组判断 if (IsTableStarted() == false && CheckDistribute()) { for (int i = 0; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] != NULL && m_TableUserItemArray[i]->GetUserStatus() == US_READY) { //发送消息 LPCTSTR pszMessage = TEXT("由玩家离开,系统重新分配桌子,请稍后!"); SendRequestFailure(m_TableUserItemArray[i], pszMessage, 0); //发送消息 m_pIMainServiceFrame->InsertDistribute(m_TableUserItemArray[i]); ////用户起立 //PerformStandUpAction(m_TableUserItemArray[i]); } } } } return true; } else { if (currUserLookOn) { //事件通知 if (m_pITableUserAction != NULL) { m_pITableUserAction->OnActionUserStandUp(wChairID, pIServerUserItem, true); } //事件通知 if (m_pIMatchTableAction != NULL) m_pIMatchTableAction->OnActionUserStandUp(wChairID, pIServerUserItem, true); //用户状态 //pIServerUserItem->SetClientReady(false); pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR, bSendState); return true; } } return true; } //比对客户端版本 bool CTableFrame::CheckClient(TCHAR *pNow, LPCTSTR pOld) { for (int i = 0; i < (LEN_MACHINE_ID - 5); i++) { if (pNow[i] > pOld[i]) { //CString str; //str.Format(TEXT("当前版本没有旁观功能")); //CTraceService::TraceString(str, TraceLevel_Normal); return false; } } return true; } //游戏中途旁观进入 bool CTableFrame::PerformLookonLogin(IServerUserItem * pIServerUserItem) { //判断客户端版本 /*TCHAR szBanBen[LEN_MACHINE_ID]; LPCTSTR csBanBen = pIServerUserItem->GetMachineID(); ZeroMemory(szBanBen, sizeof(TCHAR) * LEN_MACHINE_ID); StringCchCat(szBanBen, LEN_MACHINE_ID, _T("1.1.6")); //比对版本 此版本以前不允许进入旁观 //比较版本 if (!CheckClient(szBanBen, csBanBen)) return false;*/ /*if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) { //判断客户端版本 TCHAR szBanBen[LEN_MACHINE_ID]; ZeroMemory(szBanBen, sizeof(TCHAR) * LEN_MACHINE_ID); StringCchCat(szBanBen, LEN_MACHINE_ID, _T("2.0.0")); //比对版本 此版本以前不允许进入旁观 //比较版本 if (!CheckClient(szBanBen, pIServerUserItem->GetMachineID())) { //发送消息 SendGameMessage(pIServerUserItem, TEXT("您的游戏版本不支持戳虾子游戏,请更新版本哟!"), SMT_TABLE_EXIT); //请旁观的人离开 return false; } }*/ bool bRet = false; if (m_wStartCount == 0) { return false; } if (m_pITableUserAction == NULL) { //CString str; //str.Format(TEXT("游戏中途旁观进入失败:%d"), pIServerUserItem->GetUserID()); //CTraceService::TraceString(str, TraceLevel_Normal); return false; } //游戏未开始,不算中途 if (m_pITableUserAction != NULL) { bRet = m_pITableUserAction->PerformLookonLogin(pIServerUserItem); } if (bRet) { //CString str; //str.Format(TEXT("游戏中途旁观进入场景发送成功:%d"), pIServerUserItem->GetUserID()); //CTraceService::TraceString(str, TraceLevel_Normal); } return true; } //旁观动作 bool CTableFrame::PerformLookonAction(IServerUserItem * pIServerUserItem) { //效验参数 ASSERT((pIServerUserItem != NULL)); ASSERT((pIServerUserItem->GetTableID() == INVALID_TABLE) && (pIServerUserItem->GetChairID() == INVALID_CHAIR)); //变量定义 tagUserInfo * pUserInfo = pIServerUserItem->GetUserInfo(); tagUserRule * pUserRule = pIServerUserItem->GetUserRule(); //模拟处理 if (m_pGameServiceAttrib->wChairCount < MAX_CHAIR && pIServerUserItem->IsAndroidUser() == false) { //定义变量 CAttemperEngineSink * pAttemperEngineSink = (CAttemperEngineSink *)m_pIMainServiceFrame; //查找机器 for (WORD i = 0; i < m_pGameServiceAttrib->wChairCount; i++) { //获取用户 IServerUserItem *pIUserItem = m_TableUserItemArray[i]; if (pIUserItem == NULL) continue; if (pIUserItem->IsAndroidUser() == false)break; //获取参数 tagBindParameter * pBindParameter = pAttemperEngineSink->GetBindParameter(pIUserItem->GetBindIndex()); IAndroidUserItem * pIAndroidUserItem = m_pIAndroidUserManager->SearchAndroidUserItem(pIUserItem->GetUserID(), pBindParameter->dwSocketID); tagAndroidParameter * pAndroidParameter = pIAndroidUserItem->GetAndroidParameter(); //模拟判断 if ((pAndroidParameter->dwServiceMode&ANDROID_SIMULATE) != 0 && (pAndroidParameter->dwServiceMode&ANDROID_PASSIVITY) == 0 && (pAndroidParameter->dwServiceMode&ANDROID_INITIATIVE) == 0) { //SendRequestFailure(pIServerUserItem, TEXT("抱歉,当前游戏桌子禁止用户旁观!"), REQUEST_FAILURE_NORMAL); CMD_GR_UserSitDownAck req; req.cbRet = 1; req.szText; StringCchCopy(req.szText, _countof(req.szText), _T("抱歉,当前游戏桌子禁止用户旁观!")); UserInfo::PB_CS_S_UserSitDownAck SitDownAck; SitDownAck.set_cbret(req.cbRet); std::string szText = CW2AEX<1024>(req.szText, CP_UTF8).m_psz; SitDownAck.set_sztext(szText); //发送数据 std::string pbdata = SitDownAck.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_USER_ADDCREATE_TABLE_ID, (void*)pbdata.c_str(), pbdata.length()); return false; } break; } } //状态判断 if ((CServerRule::IsForfendGameLookon(m_pGameServiceOption->dwServerRule) == true) && (pIServerUserItem->GetMasterOrder() == 0)) { //SendRequestFailure(pIServerUserItem, TEXT("抱歉,当前游戏房间禁止用户旁观!"), REQUEST_FAILURE_NORMAL); CMD_GR_UserSitDownAck req; req.cbRet = 1; req.szText; StringCchCopy(req.szText, _countof(req.szText), _T("抱歉,当前游戏房间禁止用户旁观!")); UserInfo::PB_CS_S_UserSitDownAck SitDownAck; SitDownAck.set_cbret(req.cbRet); std::string szText = CW2AEX<1024>(req.szText, CP_UTF8).m_psz; SitDownAck.set_sztext(szText); //发送数据 std::string pbdata = SitDownAck.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_USER_ADDCREATE_TABLE_ID, (void*)pbdata.c_str(), pbdata.length()); return false; } if (pUserInfo->cbUserStatus > US_FREE) { CString csTest; csTest.Format(_T("旁观玩家%d状态:%d "), pUserInfo->dwUserID, pUserInfo->cbUserStatus); //提示消息 CTraceService::TraceString(csTest, TraceLevel_Warning); return false; } //密码效验 if ((IsTableLocked() == true) && (pIServerUserItem->GetMasterOrder() == 0L) && (lstrcmp(pUserRule->szPassword, m_szEnterPassword) != 0)) { //SendRequestFailure(pIServerUserItem, TEXT("游戏桌进入密码不正确,不能旁观游戏!"), REQUEST_FAILURE_PASSWORD); CMD_GR_UserSitDownAck req; req.cbRet = 1; req.szText; StringCchCopy(req.szText, _countof(req.szText), _T("游戏桌进入密码不正确,不能旁观游戏!")); UserInfo::PB_CS_S_UserSitDownAck SitDownAck; SitDownAck.set_cbret(req.cbRet); std::string szText = CW2AEX<1024>(req.szText, CP_UTF8).m_psz; SitDownAck.set_sztext(szText); //发送数据 std::string pbdata = SitDownAck.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_USER_ADDCREATE_TABLE_ID, (void*)pbdata.c_str(), pbdata.length()); return false; } /*if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) { //判断客户端版本 TCHAR szBanBen[LEN_MACHINE_ID]; ZeroMemory(szBanBen, sizeof(TCHAR) * LEN_MACHINE_ID); StringCchCat(szBanBen, LEN_MACHINE_ID, _T("2.0.0")); //比对版本 此版本以前不允许进入旁观 //比较版本 if (!CheckClient(szBanBen, pIServerUserItem->GetMachineID())) { //发送消息 SendGameMessage(pIServerUserItem, TEXT("您的游戏版本不支持戳虾子游戏,请更新版本哟!"), SMT_TABLE_EXIT); //请旁观的人离开 return false; } }*/ if (m_wStartCount > 0) { //设置用户 m_LookonUserItemArray.Add(pIServerUserItem); } else { //设置用户 m_LookonUserItemArray.Add(pIServerUserItem); } return true; } //发送在坐用户状态 bool CTableFrame::SendUserInfoStat(IServerUserItem * pIServerUserItem) { //变量定义 tagUserInfo * pUserInfo = pIServerUserItem->GetUserInfo(); for (int i = 0; i < m_wChairCount; i++) { if (m_TableUserItemArray[i] != NULL) { IServerUserItem *p = m_TableUserItemArray[i]; if (p == pIServerUserItem) continue; //变量定义 CMD_GR_UserStatus UserStatus; ZeroMemory(&UserStatus, sizeof(UserStatus)); //构造数据 UserStatus.dwUserID = p->GetUserID(); UserStatus.UserStatus.wTableID = p->GetTableID(); UserStatus.UserStatus.wChairID = p->GetChairID(); UserStatus.UserStatus.cbUserStatus = p->GetUserStatus(); UserInfo::PB_CS_S_UserStatus Status; Status.set_dwuserid(UserStatus.dwUserID); Status.mutable_userstatus()->set_cbuserstatus(UserStatus.UserStatus.cbUserStatus); Status.mutable_userstatus()->set_wchairid(UserStatus.UserStatus.wChairID); Status.mutable_userstatus()->set_wtableid(UserStatus.UserStatus.wTableID); //发送数据 std::string pbdata = Status.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_USER_STATUS, (void*)pbdata.c_str(), pbdata.length()); } } return true; } //坐下动作 bool CTableFrame::PerformSitDownAction(WORD wChairID, IServerUserItem * pIServerUserItem, LPCTSTR lpszPassword) { //效验参数 ASSERT((pIServerUserItem != NULL) && (wChairID < m_wChairCount)); ASSERT((pIServerUserItem->GetChairID() == INVALID_CHAIR)); //变量定义 tagUserInfo * pUserInfo = pIServerUserItem->GetUserInfo(); tagUserRule * pUserRule = pIServerUserItem->GetUserRule(); IServerUserItem * pITableUserItem = GetTableUserItem(wChairID); //积分变量 SCORE lUserScore = pIServerUserItem->GetUserScore(); SCORE lMinTableScore = m_pGameServiceOption->lMinTableScore; SCORE lLessEnterScore = m_pITableFrameSink->QueryLessEnterScore(wChairID, pIServerUserItem); //清楚旁观的我的数据 for (INT_PTR i = 0; i < m_LookonUserItemArray.GetCount(); i++) { if (pIServerUserItem == m_LookonUserItemArray[i]) { //删除子项 m_LookonUserItemArray.RemoveAt(i); } } //状态判断 if ((CServerRule::IsForfendGameEnter(m_pGameServiceOption->dwServerRule) == true) && (pIServerUserItem->GetMasterOrder() == 0)) { SendRequestFailure(pIServerUserItem, TEXT("抱歉,当前游戏桌子禁止用户进入!"), REQUEST_FAILURE_NORMAL); return false; } //动态加入 bool bDynamicJoin = true; if (m_pGameServiceAttrib->cbDynamicJoin == FALSE) bDynamicJoin = false; if (CServerRule::IsAllowDynamicJoin(m_pGameServiceOption->dwServerRule) == false) bDynamicJoin = false; //游戏状态 if ((m_bGameStarted == true) && (bDynamicJoin == false)) { //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); SendRequestFailure(pIServerUserItem, TEXT("游戏已经开始了!"), REQUEST_FAILURE_NORMAL); return false; } //椅子判断 if (pITableUserItem != NULL) { //防作弊 if (CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule)) return false; //构造信息 TCHAR szDescribe[128] = TEXT(""); _sntprintf(szDescribe, CountArray(szDescribe), TEXT("椅子已经被 [ %s ] 捷足先登了,下次动作要快点了!"), pITableUserItem->GetNickName()); //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); //发送信息 SendRequestFailure(pIServerUserItem, szDescribe, REQUEST_FAILURE_NORMAL); return false; } //密码效验 if (m_wChairCount <= MAX_CHAIR_GENERAL) { //防作弊 if (CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule) == false) { if ((m_pGameServiceOption->wServerType&GAME_GENRE_MATCH) == 0 && ((IsTableLocked() == true) && (pIServerUserItem->GetMasterOrder() == 0L)) && ((lpszPassword == NULL) || (lstrcmp(lpszPassword, m_szEnterPassword) != 0))) { SendRequestFailure(pIServerUserItem, TEXT("游戏桌进入密码不正确,不能加入游戏!"), REQUEST_FAILURE_PASSWORD); return false; } } } //规则效验 if ((m_pGameServiceOption->wServerType&GAME_GENRE_MATCH) == 0 && EfficacyEnterTableScoreRule(wChairID, pIServerUserItem) == false) return false; if (mGameConfig.wMaxScore == 0 && EfficacyIPAddress(pIServerUserItem) == false) { //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); return false; } if (mGameConfig.wMaxScore == 2 && EfficacyIPAddress(pIServerUserItem) == false) { //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); return false; } //校验准入 if (wXianZhi > 0) { if (pIServerUserItem->GetUserInfo()->dwBean < wXianZhi) { CString csTest; csTest.Format(_T("抱歉,当前房间准入标准为%d个钻石,您目前不符合条件,无法入座."), wXianZhi); //小于准入标准 //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); SendRequestFailure(pIServerUserItem, csTest, REQUEST_FAILURE_NORMAL); return false; } } if (mGameConfig.wMaxScore == 2 ) { //校验当前玩家的位置信息(主要是校验第一个玩家入座的时候) LONGLONG llx3 = pIServerUserItem->GetUserInfo()->dDingWeiX; LONGLONG lly3 = pIServerUserItem->GetUserInfo()->dDingWeiY; double dX3 = (double)llx3 / (double)1000000; double dY3 = (double)lly3 / (double)1000000; if (dX3 == 0.0f && dY3 == 0.0f) { //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); //定位信息不完整 SendRequestFailure(pIServerUserItem, TEXT("抱歉,未获取到您的位置信息,当前为反作弊专场,请选择其他房间!"), REQUEST_FAILURE_NORMAL); return false; } //校验地理位置 for (int i = 0; i < GAME_PLAYER; i++) { IServerUserItem * pCheckUserItem = GetTableUserItem(i); if (pCheckUserItem) { BaiDuMap aa; LONGLONG llx1 = pCheckUserItem->GetUserInfo()->dDingWeiX; LONGLONG lly1 = pCheckUserItem->GetUserInfo()->dDingWeiY; double dX1 = (double)llx1 / (double)1000000; double dY1 = (double)lly1 / (double)1000000; LONGLONG llx2 = pIServerUserItem->GetUserInfo()->dDingWeiX; LONGLONG lly2 = pIServerUserItem->GetUserInfo()->dDingWeiY; double dX2 = (double)llx2 / (double)1000000; double dY2 = (double)lly2 / (double)1000000; if (dX1 != 0.0f && dY1 != 0.0f&& dX2 != 0.0f&& dY2 != 0.0f) { double dRet = aa.GetShortDistance(dX1, dY1, dX2, dY2); CString csTest; csTest.Format(L"\r\n%d->%d距离信息:%f", pCheckUserItem->GetUserInfo()->dwUserID, pIServerUserItem->GetUserInfo()->dwUserID, dRet); OutputDebugString(csTest); //if (dRet < 350) //{ // //用户状态 // pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); // //小于350 则拒绝进入 // SendRequestFailure(pIServerUserItem, TEXT("抱歉,当前在座玩家与您的距离过近,当前为反作弊专场,请选择其他房间!"), REQUEST_FAILURE_NORMAL); // return false; //} } else { //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); //定位信息不完整 SendRequestFailure(pIServerUserItem, TEXT("抱歉,未获取到您的位置信息,当前为反作弊专场,请选择其他房间!"), REQUEST_FAILURE_NORMAL); return false; } } } } if ((m_pGameServiceOption->wServerType&GAME_GENRE_MATCH) == 0 && EfficacyScoreRule(pIServerUserItem) == false) return false; //扩展效验 if ((m_pGameServiceOption->wServerType&GAME_GENRE_MATCH) == 0 && m_pITableUserRequest != NULL) { //变量定义 tagRequestResult RequestResult; ZeroMemory(&RequestResult, sizeof(RequestResult)); //坐下效验 if (m_pITableUserRequest->OnUserRequestSitDown(wChairID, pIServerUserItem, RequestResult) == false) { //发送信息 SendRequestFailure(pIServerUserItem, RequestResult.szFailureReason, RequestResult.cbFailureCode); return false; } } //还需要多少元宝 UINT wReduceBeans = 0; UINT wBean = 0; if (mGameConfig.wSubGameID >= 10 && mGameConfig.wSubGameID <20) { //新版本 血流 wBean = GetNeedPayEx(); } else if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) { //新版本 wBean = GetNeedPayCxz(); } else { //检验房间参数 wBean = GetNeedPay(); } if (wBean == 0xff) { return false; } //检验元宝 if (m_wPrivateTableOwnerID == pIServerUserItem->GetUserID()) { //是创建者 已经扣完元宝了 wReduceBeans = 0; } else { if (mGameConfig.wMaxFanRule == 0) { //房主支付 wReduceBeans = 0; } else if (mGameConfig.wMaxFanRule >= 10) { //群主支付 wReduceBeans = 0; } else { if (mGameConfig.wSubGameID >= 3 && mGameConfig.wSubGameID <= 5) { //戳瞎子 wReduceBeans = wBean / 3; } else { //正常版本 wReduceBeans = wBean / MAX_CHAIR; } } } auto UserInfo = pIServerUserItem->GetUserInfo(); if (UserInfo->dwBean < wReduceBeans && pIServerUserItem->GetUserID() != m_wPrivateTableOwnerID) { //用户状态 pIServerUserItem->SetUserStatus(US_FREE, INVALID_TABLE, INVALID_CHAIR); SendRequestFailure(pIServerUserItem, TEXT("钻石不足,不能进行选座."), 0); ///---元宝改钻石 2017-8-3 return false; } //设置变量 m_TableUserItemArray[wChairID] = pIServerUserItem; m_wDrawCount = 0; //用户状态 if ((IsGameStarted() == false) || (m_cbStartMode != START_MODE_TIME_CONTROL)) { if (CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule) == false && (m_pGameServiceOption->wServerType&GAME_GENRE_MATCH) == 0) { pIServerUserItem->SetClientReady(true); pIServerUserItem->SetUserStatus(US_SIT, m_wTableID, wChairID); } else { if (m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) { pIServerUserItem->SetClientReady(pIServerUserItem->IsTrusteeUser()); pIServerUserItem->SetUserStatus(US_READY, m_wTableID, wChairID); } else { pIServerUserItem->SetClientReady(true); pIServerUserItem->SetUserStatus(US_SIT, m_wTableID, wChairID); } } } else { //设置变量 m_wOffLineCount[wChairID] = 0L; m_dwOffLineTime[wChairID] = 0L; //设置状态 pIServerUserItem->SetClientReady(true); pIServerUserItem->SetUserStatus(US_SIT, m_wTableID, wChairID); } //设置变量 m_wUserCount = GetSitUserCount(); if (m_sPrivateTableID.empty()) {//公共房间开启准备超时定时器。 //启动定时 if (IsGameStarted() == false && pIServerUserItem->IsMobileUser() && m_pGameServiceAttrib->wChairCount < MAX_CHAIR) SetGameTimer(IDI_START_OVERTIME + wChairID, TIME_OVERTIME, 1, wChairID); } //事件通知 if (m_pITableUserAction != NULL) { m_pITableUserAction->OnActionUserSitDown(wChairID, pIServerUserItem, false); } //事件通知 if (m_pIMatchTableAction != NULL) m_pIMatchTableAction->OnActionUserSitDown(wChairID, pIServerUserItem, false); if (m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) { //开始判断 if (EfficacyStartGame(INVALID_CHAIR) == true) { StartGame(); } } CAttemperEngineSink * pAttemperEngineSink = (CAttemperEngineSink *)m_pIMainServiceFrame; pAttemperEngineSink->SetUserServerID(pIServerUserItem, 1, 0);//通知协调服务器 这个用户已经进入桌子了。 return true; } //单元积分 VOID CTableFrame::SetCellScore(LONG lCellScore) { m_lCellScore = lCellScore; if (m_bTableInitFinish == true) { SendTableStatus(); m_pITableFrameSink->SetGameBaseScore(lCellScore); } } //桌子状态 bool CTableFrame::SendTableStatus() { return true; //变量定义 CMD_GR_TableStatus TableStatus; ZeroMemory(&TableStatus, sizeof(TableStatus)); //构造数据 TableStatus.wTableID = m_wTableID; TableStatus.TableStatus.lCellScore = m_lCellScore; TableStatus.TableStatus.cbTableLock = IsTableLocked() ? TRUE : FALSE; TableStatus.TableStatus.cbPlayStatus = IsTableStarted() ? TRUE : FALSE; //电脑数据 //m_pIMainServiceFrame->SendData(BG_COMPUTER, MDM_GR_STATUS, SUB_GR_TABLE_STATUS, &TableStatus, sizeof(TableStatus)); //手机数据 } //请求失败 bool CTableFrame::SendRequestFailure(IServerUserItem * pIServerUserItem, LPCTSTR pszDescribe, LONG lErrorCode) { //变量定义 CMD_GR_RequestFailure RequestFailure; ZeroMemory(&RequestFailure, sizeof(RequestFailure)); //构造数据 RequestFailure.lErrorCode = lErrorCode; lstrcpyn(RequestFailure.szDescribeString, pszDescribe, CountArray(RequestFailure.szDescribeString)); UserInfo::PB_CS_S_RequestFailure Failure; Failure.set_lerrorcode(RequestFailure.lErrorCode); std::string szDescribeString = CW2AEX<1024>(RequestFailure.szDescribeString, CP_UTF8).m_psz; Failure.set_szdescribestring(szDescribeString); //发送数据 std::string pbdata = Failure.SerializePartialAsString(); m_pIMainServiceFrame->SendData(pIServerUserItem, MDM_GR_USER, SUB_GR_REQUEST_FAILURE, (void*)pbdata.c_str(), pbdata.length()); return true; } //开始效验 bool CTableFrame::EfficacyStartGame(WORD wReadyChairID) { //状态判断 if (m_bGameStarted == true) return false; //模式过滤 if (m_cbStartMode == START_MODE_TIME_CONTROL) return false; if (m_cbStartMode == START_MODE_MASTER_CONTROL) return false; //准备人数 WORD wReadyUserCount = 0; for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem * pITableUserItem = GetTableUserItem(i); if (pITableUserItem == NULL) continue; //用户统计 if (pITableUserItem != NULL) { //状态判断 //if (pITableUserItem->IsClientReady() == false) return false; if (!m_bGameStarted) { if (pITableUserItem->GetUserStatus() == US_READY || pITableUserItem->GetUserStatus() == US_OFFLINE || US_PLAYING == pITableUserItem->GetUserStatus()) { //用户计数 wReadyUserCount++; } } else { //游戏开始以后 看是否在游戏中已经点了准备 if (m_GameRead[i] == true) { //用户计数 wReadyUserCount++; } } } } //开始处理 switch (m_cbStartMode) { case START_MODE_ALL_READY: //所有准备 { //数目判断 if (wReadyUserCount >= 2L) return true; return false; } case START_MODE_FULL_READY: //满人开始 { //人数判断 if (wReadyUserCount == m_wChairCount) return true; return false; } case START_MODE_PAIR_READY: //配对开始 { //数目判断 if (wReadyUserCount == m_wChairCount) return true; if ((wReadyUserCount < 2L) || (wReadyUserCount % 2) != 0) return false; //位置判断 for (WORD i = 0; i < m_wChairCount / 2; i++) { //获取用户 IServerUserItem * pICurrentUserItem = GetTableUserItem(i); IServerUserItem * pITowardsUserItem = GetTableUserItem(i + m_wChairCount / 2); //位置过滤 if ((pICurrentUserItem == NULL) && (pITowardsUserItem != NULL)) return false; if ((pICurrentUserItem != NULL) && (pITowardsUserItem == NULL)) return false; } return true; } default: { ASSERT(FALSE); return false; } } return false; } //地址效验 bool CTableFrame::EfficacyIPAddress(IServerUserItem * pIServerUserItem) { //管理员不受限制 if (pIServerUserItem->GetMasterOrder() != 0) return true; //规则判断 //if (CServerRule::IsForfendGameRule(m_pGameServiceOption->dwServerRule) == true) return true; //防作弊 //if (CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule)) return true; //百人不限制 if (m_wChairCount > MAX_CHAIR_GENERAL) return true; //地址效验 const tagUserRule * pUserRule = pIServerUserItem->GetUserRule(), *pTableUserRule = NULL; bool bCheckSameIP = true; //地址效验 if (bCheckSameIP == true) { DWORD dwUserIP = pIServerUserItem->GetClientAddr(); for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem * pITableUserItem = GetTableUserItem(i); if(pITableUserItem != NULL) if (pITableUserItem->GetClientAddr() == 0) continue; if ((pITableUserItem != NULL) && (pITableUserItem != pIServerUserItem) && (!pITableUserItem->IsAndroidUser()) && (pITableUserItem->GetMasterOrder() == 0) && (pITableUserItem->GetClientAddr() == dwUserIP)) { if (!pUserRule->bLimitSameIP) { //发送信息 LPCTSTR pszDescribe = TEXT("此游戏桌玩家设置了不跟相同 IP 地址的玩家游戏,您 IP 地址与此玩家的 IP 地址相同,不能加入游戏!"); SendRequestFailure(pIServerUserItem, pszDescribe, REQUEST_FAILURE_NORMAL); return false; } else { //发送信息 LPCTSTR pszDescribe = TEXT("您设置了不跟相同 IP 地址的玩家游戏,此游戏桌存在与您 IP 地址相同的玩家,不能加入游戏!"); SendRequestFailure(pIServerUserItem, pszDescribe, REQUEST_FAILURE_NORMAL); return false; } } } for (WORD i = 0; i < m_wChairCount - 1; i++) { //获取用户 IServerUserItem * pITableUserItem = GetTableUserItem(i); if (pITableUserItem != NULL && (!pITableUserItem->IsAndroidUser()) && (pITableUserItem->GetMasterOrder() == 0)) { for (WORD j = i + 1; j < m_wChairCount; j++) { //获取用户 IServerUserItem * pITableNextUserItem = GetTableUserItem(j); if (pITableUserItem != NULL) if (pITableUserItem->GetClientAddr() == 0) continue; if ((pITableNextUserItem != NULL) && (!pITableNextUserItem->IsAndroidUser()) && (pITableNextUserItem->GetMasterOrder() == 0) && (pITableUserItem->GetClientAddr() == pITableNextUserItem->GetClientAddr())) { LPCTSTR pszDescribe = TEXT("您设置了不跟相同 IP 地址的玩家游戏,此游戏桌存在 IP 地址相同的玩家,不能加入游戏!"); SendRequestFailure(pIServerUserItem, pszDescribe, REQUEST_FAILURE_NORMAL); return false; } } } } } return true; } //积分效验 bool CTableFrame::EfficacyScoreRule(IServerUserItem * pIServerUserItem) { //管理员不受限制 if (pIServerUserItem->GetMasterOrder() != 0) return true; //规则判断 if (CServerRule::IsForfendGameRule(m_pGameServiceOption->dwServerRule) == true) return true; //防作弊 if (CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule)) return true; //百人不限制 if (m_wChairCount > MAX_CHAIR_GENERAL) return true; //变量定义 WORD wWinRate = pIServerUserItem->GetUserWinRate(); WORD wFleeRate = pIServerUserItem->GetUserFleeRate(); //积分范围 for (WORD i = 0; i < m_wChairCount; i++) { //获取用户 IServerUserItem * pITableUserItem = GetTableUserItem(i); //规则效验 if (pITableUserItem != NULL) { //获取规则 tagUserRule * pTableUserRule = pITableUserItem->GetUserRule(); //逃率效验 if ((pTableUserRule->bLimitFleeRate) && (wFleeRate > pTableUserRule->wMaxFleeRate)) { //构造信息 TCHAR szDescribe[128] = TEXT(""); _sntprintf(szDescribe, CountArray(szDescribe), TEXT("您的逃跑率太高,与 %s 设置的设置不符,不能加入游戏!"), pITableUserItem->GetNickName()); //发送信息 SendRequestFailure(pIServerUserItem, szDescribe, REQUEST_FAILURE_NORMAL); return false; } //胜率效验 if ((pTableUserRule->bLimitWinRate) && (wWinRate < pTableUserRule->wMinWinRate)) { //构造信息 TCHAR szDescribe[128] = TEXT(""); _sntprintf(szDescribe, CountArray(szDescribe), TEXT("您的胜率太低,与 %s 设置的设置不符,不能加入游戏!"), pITableUserItem->GetNickName()); //发送信息 SendRequestFailure(pIServerUserItem, szDescribe, REQUEST_FAILURE_NORMAL); return false; } //积分效验 if (pTableUserRule->bLimitGameScore == true) { //最高积分 if (pIServerUserItem->GetUserScore() > pTableUserRule->lMaxGameScore) { //构造信息 TCHAR szDescribe[128] = TEXT(""); _sntprintf(szDescribe, CountArray(szDescribe), TEXT("您的积分太高,与 %s 设置的设置不符,不能加入游戏!"), pITableUserItem->GetNickName()); //发送信息 SendRequestFailure(pIServerUserItem, szDescribe, REQUEST_FAILURE_NORMAL); return false; } //最低积分 if (pIServerUserItem->GetUserScore() < pTableUserRule->lMinGameScore) { //构造信息 TCHAR szDescribe[128] = TEXT(""); _sntprintf(szDescribe, CountArray(szDescribe), TEXT("您的积分太低,与 %s 设置的设置不符,不能加入游戏!"), pITableUserItem->GetNickName()); //发送信息 SendRequestFailure(pIServerUserItem, szDescribe, REQUEST_FAILURE_NORMAL); return false; } } } } return true; } //积分效验 bool CTableFrame::EfficacyEnterTableScoreRule(WORD wChairID, IServerUserItem * pIServerUserItem) { //积分变量 SCORE lUserScore = pIServerUserItem->GetUserScore(); SCORE lMinTableScore = m_pGameServiceOption->lMinTableScore; SCORE lLessEnterScore = m_pITableFrameSink->QueryLessEnterScore(wChairID, pIServerUserItem); if (((lMinTableScore != 0L) && (lUserScore < lMinTableScore)) || ((lLessEnterScore != 0L) && (lUserScore < lLessEnterScore))) { //构造信息 TCHAR szDescribe[128] = TEXT(""); if (m_pGameServiceOption->wServerType == GAME_GENRE_GOLD) _sntprintf(szDescribe, CountArray(szDescribe), TEXT("加入游戏至少需要 ") SCORE_STRING TEXT(" 的游戏币,您的游戏币不够,不能加入!"), __max(lMinTableScore, lLessEnterScore)); else if (m_pGameServiceOption->wServerType == GAME_GENRE_MATCH) _sntprintf(szDescribe, CountArray(szDescribe), TEXT("加入游戏至少需要 ") SCORE_STRING TEXT(" 的比赛币,您的比赛币不够,不能加入!"), __max(lMinTableScore, lLessEnterScore)); else _sntprintf(szDescribe, CountArray(szDescribe), TEXT("加入游戏至少需要 ") SCORE_STRING TEXT(" 的游戏积分,您的积分不够,不能加入!"), __max(lMinTableScore, lLessEnterScore)); //发送信息 SendRequestFailure(pIServerUserItem, szDescribe, REQUEST_FAILURE_NOSCORE); return false; } return true; } //检查分配 bool CTableFrame::CheckDistribute() { //防作弊 if (CServerRule::IsAllowAvertCheatMode(m_pGameServiceOption->dwServerRule)) { //桌子状况 tagTableUserInfo TableUserInfo; WORD wUserSitCount = GetTableUserInfo(TableUserInfo); //用户起立 if (wUserSitCount < TableUserInfo.wMinUserCount) { return true; } } return false; } //游戏记录 void CTableFrame::RecordGameScore(bool bDrawStarted, DWORD dwStartGameTime, bool bUpdateParent) { if (bDrawStarted == true) { //写入记录 if (CServerRule::IsRecordGameScore(m_pGameServiceOption->dwServerRule) == true) { //变量定义 DBR_GR_GameScoreRecord GameScoreRecord; ZeroMemory(&GameScoreRecord, sizeof(GameScoreRecord)); //设置变量 GameScoreRecord.cbUpdateParent = bUpdateParent ? 1 : 0; GameScoreRecord.wPrivateTableParentNodeID = m_wPrivateTablParentNodeID; //设置记录的父节点(0表示没有父节点) lstrcpy(GameScoreRecord.szPrivateTableID, m_sPrivateTableID.c_str()); GameScoreRecord.wTableID = m_wTableID; GameScoreRecord.wTableType = m_wTableKind; GameScoreRecord.dwPlayTimeCount = (bDrawStarted == true) ? (DWORD)time(NULL) - m_dwDrawStartTime : 0; GameScoreRecord.wRePlayRecordSize = m_ReplayRecordDataSize; //游戏时间 if (dwStartGameTime != INVALID_DWORD) { CTime startTime(dwStartGameTime); startTime.GetAsSystemTime(GameScoreRecord.SystemTimeStart); } else { GameScoreRecord.SystemTimeStart = m_SystemTimeStart; } GetLocalTime(&GameScoreRecord.SystemTimeConclude); if (INVALID_TABLE == dwStartGameTime) { //游戏结束 int iPlayNum = m_wStartCount << 8; GameScoreRecord.lWasteCount = mGameConfig.wSubGameID + iPlayNum; GetLocalTime(&GameScoreRecord.SystemTimeConclude); } for (int i = 0; i < 4; i++) { //奖牌统计 GameScoreRecord.wUserMemal += m_pITableFrameSink->QueryTatolLaiGang(i); } GameScoreRecord.wDiFen = mGameConfig.wPlayRule; //用户积分 for (INT_PTR i = 0; i < m_GameScoreRecordActive.GetCount(); i++) { //获取对象 ASSERT(m_GameScoreRecordActive[i] != NULL); tagGameScoreRecord * pGameScoreRecord = m_GameScoreRecordActive[i]; //用户数目 if (pGameScoreRecord->cbAndroid == FALSE) { GameScoreRecord.wUserCount++; } else { GameScoreRecord.wAndroidCount++; } //统计信息 if (pGameScoreRecord->cbAndroid == FALSE) { //GameScoreRecord.lWasteCount -= (pGameScoreRecord->lScore + pGameScoreRecord->lRevenue); GameScoreRecord.lRevenueCount += pGameScoreRecord->lRevenue; } //成绩信息 if (GameScoreRecord.wRecordCountGetStartMode() == START_MODE_ALL_READY && wIndex == 1) { pGameScoreRecord->lScore = m_pITableFrameSink->QueryTatolScore(2); } else { pGameScoreRecord->lScore = m_pITableFrameSink->QueryTatolScore(wIndex); } CopyMemory(&GameScoreRecord.GameScoreRecord[wIndex], pGameScoreRecord, sizeof(tagGameScoreRecord)); } else { CopyMemory(&GameScoreRecord.GameScoreRecord[wIndex], pGameScoreRecord, sizeof(tagGameScoreRecord)); } } } if (this->GetStartMode() == START_MODE_ALL_READY && GameScoreRecord.wRecordCount == 2)//二人玩法额外加一条 { CopyMemory(&GameScoreRecord.GameScoreRecord[2], &GameScoreRecord.GameScoreRecord[1], sizeof(tagGameScoreRecord)); GameScoreRecord.GameScoreRecord[1].lScore = 0; GameScoreRecord.wRecordCount++; } //投递数据 if (GameScoreRecord.wUserCount > 0) { WORD wHeadSize = sizeof(GameScoreRecord)-sizeof(GameScoreRecord.GameScoreRecord); WORD wDataSize = sizeof(GameScoreRecord.GameScoreRecord[0])*GameScoreRecord.wRecordCount; int totalData = wHeadSize + wDataSize + m_ReplayRecordDataSize; char *data = new char[totalData]; CopyMemory(data, &GameScoreRecord, wHeadSize + wDataSize); if (m_ReplayRecordDataSize > 0) { //如果回放数据已存档,则删除 CopyMemory(data + wHeadSize + wDataSize,m_ReplayRecordData, m_ReplayRecordDataSize); if (nullptr != m_ReplayRecordData) { delete[] m_ReplayRecordData; m_ReplayRecordData = nullptr; } m_ReplayRecordDataSize = 0; } m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GR_GAME_SCORE_RECORD, 0, data, totalData); //内存泄露 if (data != NULL) { delete[] data; data = NULL; } } } //清理记录 if (m_GameScoreRecordActive.GetCount() > 0L) { m_GameScoreRecordBuffer.Append(m_GameScoreRecordActive); m_GameScoreRecordActive.RemoveAll(); m_GameScoreRecordActive.FreeMemory(); } } } //扣钻 调用数据库接口 bool CTableFrame::DeductWLZuanshi(DWORD dwUserID) { m_pIRecordDataBaseEngine->PostDataBaseRequest(DBR_GP_DEDUCT_ZUANSHI_INFO, 0, &dwUserID, sizeof(dwUserID)); return true; } //////////////////////////////////////////////////////////////////////////////////