Files
wnmj-normal/Servers/游戏组件/诈金花/游戏服务器/TableFrameSink.cpp

1086 lines
31 KiB
C++
Raw Normal View History

2026-03-03 13:56:44 +08:00
#include "StdAfx.h"
#include "TableFrameSink.h"
const WORD CTableFrameSink::m_wPlayerCount = GAME_PLAYER;
CTableFrameSink::CTableFrameSink()
: m_pITableFrame(nullptr)
, m_pGameServiceOption(nullptr)
{
m_wFirstChairID = INVALID_CHAIR;
m_wBankerUser = INVALID_CHAIR;
m_wCurrentUser = INVALID_CHAIR;
m_wFirstOperateUser = INVALID_CHAIR;
m_lCurChipScore = 0;
m_dwOperateCode = 0;
m_cbCurPlayRound = 0;
m_cbGamingUserCount = 0;
m_cbPlayTimes = 0;
m_cbMasterCtrlType = 0;
m_wMasterChairID = INVALID_CHAIR;
ZeroMemory(m_cbUserResponse, sizeof(m_cbUserResponse));
ZeroMemory(m_cbHandCardData, sizeof(m_cbHandCardData));
ZeroMemory(m_lUserChipScore, sizeof(m_lUserChipScore));
ZeroMemory(m_cbGamingStatus, sizeof(m_cbGamingStatus));
ZeroMemory(&m_PrivateEndInfo, sizeof(CMD_S_Private_End_Info));
ZeroMemory(m_cbHideCardRound, sizeof(m_cbHideCardRound));
}
CTableFrameSink::~CTableFrameSink(void)
{
}
void * CTableFrameSink::QueryInterface(const IID & Guid, DWORD dwQueryVer)
{
QUERYINTERFACE(ITableFrameSink, Guid, dwQueryVer);
QUERYINTERFACE(ITableUserAction, Guid, dwQueryVer);
QUERYINTERFACE_IUNKNOWNEX(ITableFrameSink, Guid, dwQueryVer);
return nullptr;
}
bool CTableFrameSink::Initialization(IUnknownEx * pIUnknownEx)
{
ASSERT(nullptr != pIUnknownEx);
m_pITableFrame = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITableFrame);
ASSERT(nullptr != m_pITableFrame);
if (nullptr == m_pITableFrame) return false;
m_pGameServiceOption = m_pITableFrame->GetGameServiceOption();
ASSERT(nullptr != m_pGameServiceOption);
if (nullptr == m_pGameServiceOption) return false;
//<2F><>ʼģʽ;
m_pITableFrame->SetStartMode(START_MODE_ALL_READY);
//<2F>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>;
ASSERT(m_pITableFrame->GetCustomRule() != NULL);
m_pGameCustomRule = (tagCustomRule *)m_pITableFrame->GetCustomRule();
//Ĭ<><C4AC><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>ע;
m_lCfgMinChipScore = m_pGameCustomRule->lMinChipScore;
//Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע;
m_lCfgMaxChipScore = m_pGameCustomRule->lMaxChipScore;
//Ĭ<>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
m_cbCfgMaxPlayRound = m_pGameCustomRule->cbMaxPlayRound;
//Ĭ<><C4AC><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
m_cbCfgMinCompareUser = m_pGameCustomRule->cbMinCompareUser;
//Ĭ<>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
m_cbCfgMinLookRound = m_pGameCustomRule->cbMinLookRound;
//Ĭ<>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
m_cbCfgMinCompareRound = m_pGameCustomRule->cbMinCompareRound;
// <20><><EFBFBD><EFBFBD>;
//BYTE cbFirstCardData[MAX_COUNT] = { 0x2b, 0x0a, 0x39 };
//BYTE cbNextCardData[MAX_COUNT] = {0x3b, 0x1a, 0x19};
//BYTE cbFirstCardData[MAX_COUNT] = { 0x2b, 0x0b, 0x39 };
//BYTE cbNextCardData[MAX_COUNT] = { 0x3b, 0x1b, 0x19 };
//BYTE cbFirstCardData[MAX_COUNT] = { 0x2b, 0x2a, 0x29 };
//BYTE cbNextCardData[MAX_COUNT] = { 0x3b, 0x3a, 0x39 };
//if (m_GameLogic.AutoCompareCard(cbFirstCardData, cbNextCardData, MAX_COUNT))
//{
// ASSERT(true);
//}
//else
//{
// ASSERT(false);
//}
//
return true;
}
bool CTableFrameSink::IsUserPlaying(WORD wChairID)
{
ASSERT(wChairID>=0 && wChairID<GAME_PLAYER);
if (wChairID >= GAME_PLAYER) return false;
return (ST_GAMING_NULL!=m_cbGamingStatus[wChairID]) ? true : false;
}
bool CTableFrameSink::OnActionUserSitDown(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
{
if (!bLookonUser && INVALID_CHAIR == m_wFirstChairID)
{
m_wFirstChairID = wChairID;
}
return true;
}
bool CTableFrameSink::OnActionUserStandUp(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
WORD wUserCount = 0;
//<2F><>Ŀͳ<C4BF><CDB3>;
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (i == wChairID) continue;
if (m_pITableFrame->GetTableUserItem(i) != nullptr)
{
wUserCount++;
}
}
if (!bLookonUser && (0 == wUserCount))
{
m_wFirstChairID = INVALID_CHAIR;
}
return true;
}
void CTableFrameSink::RepositionSink()
{
m_wCurrentUser = INVALID_CHAIR;
m_wFirstOperateUser = INVALID_CHAIR;
m_lCurChipScore = 0;
m_dwOperateCode = 0;
m_cbCurPlayRound = 0;
m_cbGamingUserCount = 0;
ZeroMemory(m_cbUserResponse, sizeof(m_cbUserResponse));
ZeroMemory(m_cbHandCardData, sizeof(m_cbHandCardData));
ZeroMemory(m_lUserChipScore, sizeof(m_lUserChipScore));
ZeroMemory(m_cbGamingStatus, sizeof(m_cbGamingStatus));
ZeroMemory(m_cbHideCardRound, sizeof(m_cbHideCardRound));
}
bool CTableFrameSink::OnEventSendGameScene(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret)
{
switch (cbGameStatus)
{
case GS_ZJH_FREE:
{
CMD_S_StatusFree free = { 0 };
free.lCellScore = m_pITableFrame->GetCellScore();
free.cbCurRound = m_cbCurPlayRound;
free.cbMaxRound = m_cbCfgMaxPlayRound;
free.lCurChipScore = m_lCurChipScore;
free.lMaxChipScore = m_lCfgMaxChipScore;
free.wOperTimeOut = IDT_WAIT_OPERATE / 1000;
return m_pITableFrame->SendGameScene(pIServerUserItem, &free, sizeof(free));
}
case GS_ZJH_SEND_CARD:
{
CMD_S_StatusSendCard send = { 0 };
send.stBase.lCellScore = m_pITableFrame->GetCellScore();
send.stBase.cbCurRound = m_cbCurPlayRound;
send.stBase.cbMaxRound = m_cbCfgMaxPlayRound;
send.stBase.lCurChipScore = m_lCurChipScore;
send.stBase.lMaxChipScore = m_lCfgMaxChipScore;
send.stBase.wOperTimeOut = IDT_WAIT_OPERATE / 1000;
send.bSendOver = m_cbUserResponse[wChairID];
send.wBankerUser = m_wBankerUser;
CopyMemory(send.lUserChipScore, m_lUserChipScore, sizeof(m_lUserChipScore));
CopyMemory(send.cbGamingStatus, m_cbGamingStatus, sizeof(m_cbGamingStatus));
return m_pITableFrame->SendGameScene(pIServerUserItem, &send, sizeof(send));
}
case GS_ZJH_PLAYING:
{
CMD_S_StatusPlay play = { 0 };
play.stBase.lCellScore = m_pITableFrame->GetCellScore();
play.stBase.cbCurRound = m_cbCurPlayRound;
play.stBase.cbMaxRound = m_cbCfgMaxPlayRound;
play.stBase.lCurChipScore = m_lCurChipScore;
play.stBase.lMaxChipScore = m_lCfgMaxChipScore;
play.stBase.wOperTimeOut = IDT_WAIT_OPERATE / 1000;
play.wBankerUser = m_wBankerUser;
play.wCurrentUser = m_wCurrentUser;
if (m_wCurrentUser == wChairID) play.dwOperateCode = m_dwOperateCode;
CopyMemory(play.lUserChipScore, m_lUserChipScore, sizeof(m_lUserChipScore));
CopyMemory(play.cbGamingStatus, m_cbGamingStatus, sizeof(m_cbGamingStatus));
if (ST_GAMING_LOOK == m_cbGamingStatus[wChairID])
{
CopyMemory(play.cbHandCardData, m_cbHandCardData[wChairID], sizeof(m_cbHandCardData[wChairID]));
}
return m_pITableFrame->SendGameScene(pIServerUserItem, &play, sizeof(play));
}
}
return false;
}
bool CTableFrameSink::OnEventGameStart()
{
tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
if (pPrivateFrame!=nullptr)
{
SetPrivateInfo(pPrivateFrame->cbGameTypeIdex, pPrivateFrame->dwGameRule);
}
m_cbCurPlayRound++;
m_lCurChipScore = m_lCfgMinChipScore;
m_GameLogic.RandCardList(reinterpret_cast<BYTE *>(m_cbHandCardData), sizeof(m_cbHandCardData));
if (m_cbMasterCtrlType > 0 && m_cbMasterCtrlType<3 && m_wMasterChairID!=INVALID_CHAIR)
{
//<2F>ҳ<EFBFBD>Ӯ<EFBFBD><D3AE>ID;
WORD wWinnerIndex = 0;
for (WORD j = 1; j < m_wPlayerCount; j++)
{
//<2F>Ա<EFBFBD><D4B1>˿<EFBFBD>;
if (m_GameLogic.CompareCard(m_cbHandCardData[j], m_cbHandCardData[wWinnerIndex], MAX_COUNT) == true)
{
wWinnerIndex = j;
}
}
//Ӯ<>ҽ<EFBFBD><D2BD><EFBFBD><EFBFBD>˿<EFBFBD>;
if (1==m_cbMasterCtrlType && wWinnerIndex!=m_wMasterChairID)
{
BYTE cbTempCardData[MAX_COUNT] = {0};
CopyMemory(cbTempCardData, m_cbHandCardData[m_wMasterChairID], MAX_COUNT*sizeof(BYTE));
CopyMemory(m_cbHandCardData[m_wMasterChairID], m_cbHandCardData[wWinnerIndex], MAX_COUNT*sizeof(BYTE));
CopyMemory(m_cbHandCardData[wWinnerIndex], cbTempCardData, MAX_COUNT*sizeof(BYTE));
}
//<2F><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD><EFBFBD>˿<EFBFBD>;
if (2 == m_cbMasterCtrlType && wWinnerIndex == m_wMasterChairID)
{
//<2F><><EFBFBD><EFBFBD>ID;
WORD wLoserIndex = (wWinnerIndex+1)%GAME_PLAYER;
BYTE cbTempCardData[MAX_COUNT] = { 0 };
CopyMemory(cbTempCardData, m_cbHandCardData[m_wMasterChairID], MAX_COUNT*sizeof(BYTE));
CopyMemory(m_cbHandCardData[m_wMasterChairID], m_cbHandCardData[wLoserIndex], MAX_COUNT*sizeof(BYTE));
CopyMemory(m_cbHandCardData[wLoserIndex], cbTempCardData, MAX_COUNT*sizeof(BYTE));
}
}
for (WORD i=0; i<m_wPlayerCount; ++i)
{
IServerUserItem *pIUserItem = m_pITableFrame->GetTableUserItem(i);
if (nullptr == pIUserItem) continue;
BYTE cbUserStatus = pIUserItem->GetUserStatus();
BYTE cbReUserStatus = pIUserItem->GetReUserStatus();
if (cbUserStatus == US_PLAYING || (US_OFFLINE == cbUserStatus && cbReUserStatus == US_PLAYING))
{
m_cbGamingUserCount++;
m_lUserChipScore[i] = m_lCurChipScore;
m_cbGamingStatus[i] = ST_GAMING_HIDDEN;
m_GameLogic.SortCardList(m_cbHandCardData[i], MAX_COUNT);
}
}
ASSERT(m_cbGamingUserCount>=2);
if (INVALID_CHAIR==m_wBankerUser)
{
m_wBankerUser = m_wFirstChairID;
ASSERT(INVALID_CHAIR != m_wBankerUser);
if (INVALID_CHAIR == m_wBankerUser || m_pITableFrame->GetTableUserItem(m_wBankerUser)==nullptr)
{
m_wBankerUser = 0;
}
}
m_cbPlayTimes++;
//#ifdef _DEBUG
// if (m_cbPlayTimes == 1)
// {
// m_cbHandCardData[m_wBankerUser][0] = 0x01;
// m_cbHandCardData[m_wBankerUser][1] = 0x11;
// m_cbHandCardData[m_wBankerUser][2] = 0x21;
// }
// else if (m_cbPlayTimes == 2)
// {
// m_cbHandCardData[m_wBankerUser][0] = 0x06;
// m_cbHandCardData[m_wBankerUser][1] = 0x16;
// m_cbHandCardData[m_wBankerUser][2] = 0x26;
// }
// else if (m_cbPlayTimes == 3)
// {
// m_cbHandCardData[m_wBankerUser][0] = 0x0a;
// m_cbHandCardData[m_wBankerUser][1] = 0x0b;
// m_cbHandCardData[m_wBankerUser][2] = 0x0c;
// }
//#endif
CMD_S_GameStart gs = { 0 };
gs.wBankerUser = m_wBankerUser;
gs.cbCurRound = m_cbCurPlayRound;
gs.lCurChipScore = m_lCurChipScore;
CopyMemory(gs.cbGamingStatus, m_cbGamingStatus, sizeof(m_cbGamingStatus));
CopyMemory(gs.lUserChipScore, m_lUserChipScore, sizeof(m_lUserChipScore));
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_START, &gs, sizeof(gs));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_START, &gs, sizeof(gs));
m_pITableFrame->SetGameStatus(GS_ZJH_SEND_CARD);
m_pITableFrame->SetGameTimer(IDI_SEND_CARD, IDT_SEND_CARD, 1, 0);
return true;
}
bool CTableFrameSink::OnTimerMessage(DWORD wTimerID, WPARAM wBindParam)
{
switch (wTimerID)
{
case IDI_SEND_CARD: return OnSendCardOver(INVALID_CHAIR);
case IDI_WAIT_OPERATE: return true;//OnUserGiveUp(m_wCurrentUser);//<2F><><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>;
}
return true;
}
bool CTableFrameSink::OnGameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem)
{
switch (wSubCmdID)
{
case SUB_C_SEND_OVER:
{
ASSERT(pIServerUserItem->GetUserStatus() == US_PLAYING);
if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
return OnSendCardOver(pIServerUserItem->GetChairID());
}
case SUB_C_USER_OPERATE:
{
ASSERT(sizeof(CMD_C_UserOperate) == wDataSize);
if (sizeof(CMD_C_UserOperate) != wDataSize) return false;
ASSERT(pIServerUserItem->GetUserStatus() == US_PLAYING);
if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
WORD wChairID = pIServerUserItem->GetChairID();
CMD_C_UserOperate *pOperate = (CMD_C_UserOperate *)pDataBuffer;
return OnUserOperate(wChairID, pOperate->dwCode, pOperate->lData);
}
case SUB_C_MASTER_CONTROL:
{
ASSERT(sizeof(BYTE) == wDataSize);
if (sizeof(BYTE) != wDataSize) return false;
if (CUserRight::CanGetCard(pIServerUserItem->GetUserRight()))
{
BYTE cbMasterType = *(BYTE*)pDataBuffer;
if (0 == cbMasterType)
{
m_wMasterChairID = INVALID_CHAIR;
m_cbMasterCtrlType = cbMasterType;
}
else if ((1 == cbMasterType) || (2 == cbMasterType))
{
m_wMasterChairID = pIServerUserItem->GetChairID();
m_cbMasterCtrlType = cbMasterType;
}
else if (3 == cbMasterType)
{
ASSERT(pIServerUserItem->GetUserStatus() == US_PLAYING);
if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
CMD_S_CheatCardInfo mCheatInfo = {0};
CopyMemory(mCheatInfo.cbGamingStatus, m_cbGamingStatus, sizeof(m_cbGamingStatus));
CopyMemory(mCheatInfo.cbHandCardData, m_cbHandCardData, sizeof(m_cbHandCardData));
m_pITableFrame->SendTableData(pIServerUserItem->GetChairID(), SUB_S_CHEAT_CARD, &mCheatInfo, sizeof(mCheatInfo));
}
return true;
}
return false;
}
}
ASSERT(0);
return false;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>;
bool CTableFrameSink::OnFrameMessage(WORD wSubCmdID, VOID * pData, WORD wDataSize, IServerUserItem * pIServerUserItem)
{
return false;
}
bool CTableFrameSink::OnSendCardOver(WORD wChairID)
{
ASSERT(GS_ZJH_SEND_CARD == m_pITableFrame->GetGameStatus());
if (GS_ZJH_SEND_CARD != m_pITableFrame->GetGameStatus()) return true;
if (INVALID_CHAIR != wChairID)
{
ASSERT(wChairID>=0 && wChairID<GAME_PLAYER);
if (wChairID >= GAME_PLAYER) return false;
ASSERT(IsUserPlaying(wChairID));
if (!IsUserPlaying(wChairID)) return true;
ASSERT(!m_cbUserResponse[wChairID]);
if (m_cbUserResponse[wChairID]) return true;
m_cbUserResponse[wChairID] = true;
for (int i=0; i<m_wPlayerCount; ++i)
{
if (IsUserPlaying(i) && !m_cbUserResponse[i])
{
return true;
}
}
}
m_pITableFrame->KillGameTimer(IDI_SEND_CARD);
memset(m_cbUserResponse, 1, sizeof(m_cbUserResponse));
ASSERT(1 == m_cbCurPlayRound);
ASSERT(m_wCurrentUser == INVALID_CHAIR);
ASSERT(m_wFirstOperateUser == INVALID_CHAIR);
ASSERT(m_lCurChipScore == m_lCfgMinChipScore);
m_wCurrentUser = m_wBankerUser;
m_wFirstOperateUser = m_wBankerUser;
m_dwOperateCode = MakeOperateCode(m_wCurrentUser);
CMD_S_StartChip sc = { 0 };
sc.cbCurRound = m_cbCurPlayRound;
sc.wCurrentUser = m_wCurrentUser;
sc.dwOperateCode = m_dwOperateCode;
sc.lCurChipScore = m_lCurChipScore;
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_START_CHIP, &sc, sizeof(sc));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_START_CHIP, &sc, sizeof(sc));
m_pITableFrame->SetGameStatus(GS_ZJH_PLAYING);
m_pITableFrame->SetGameTimer(IDI_WAIT_OPERATE, IDT_WAIT_OPERATE, 1, m_wCurrentUser);
return true;
}
bool CTableFrameSink::OnUserOperate(WORD wChairID, DWORD dwOperateCode, LONG lOperateData)
{
ASSERT(GS_ZJH_PLAYING == m_pITableFrame->GetGameStatus());
if (GS_ZJH_PLAYING != m_pITableFrame->GetGameStatus()) return true;
ASSERT(wChairID>=0 && wChairID<GAME_PLAYER);
if (wChairID >= GAME_PLAYER) return false;
ASSERT(IsGamingUser(wChairID));
if (!IsGamingUser(wChairID)) return true;
if (OPERATE_LOOK != dwOperateCode)
{
ASSERT(wChairID == m_wCurrentUser);
if (wChairID != m_wCurrentUser) return true;
ASSERT((m_dwOperateCode&dwOperateCode) != 0);
if (0 == (m_dwOperateCode&dwOperateCode)) return true;
}
switch (dwOperateCode)
{
case OPERATE_GIVEUP:
return OnUserGiveUp(wChairID);
case OPERATE_LOOK:
return OnUserLookCard(wChairID);
case OPERATE_FOLLOW:
case OPERATE_ADD_CHIP:
return OnUserChipScore(wChairID, dwOperateCode, lOperateData);
case OPERATE_COMPARE_CARD:
return OnUserCompareCard(wChairID, dwOperateCode, static_cast<WORD>(lOperateData));
}
ASSERT(0);
return false;
}
bool CTableFrameSink::OnUserGiveUp(WORD wChairID)
{
ASSERT(GS_ZJH_PLAYING == m_pITableFrame->GetGameStatus());
if (GS_ZJH_PLAYING != m_pITableFrame->GetGameStatus()) return true;
ASSERT(wChairID>=0 && wChairID<GAME_PLAYER);
if (wChairID >= GAME_PLAYER) return false;
ASSERT(IsGamingUser(wChairID));
if (!IsGamingUser(wChairID)) return true;
ASSERT(wChairID == m_wCurrentUser);
if (wChairID != m_wCurrentUser) return true;
m_pITableFrame->KillGameTimer(IDI_WAIT_OPERATE);
m_cbGamingUserCount--;
m_cbGamingStatus[wChairID] = ST_GAMING_GIVEUP;
SwitchNextGamingUser(wChairID);
ASSERT(m_wCurrentUser!=INVALID_CHAIR || 1==m_cbGamingUserCount);
CMD_S_GiveUp gu = { 0 };
gu.wGiveUpUser = wChairID;
gu.stChipInfo.cbCurRound = m_cbCurPlayRound;
gu.stChipInfo.wCurrentUser = m_wCurrentUser;
gu.stChipInfo.dwOperateCode = m_dwOperateCode;
gu.stChipInfo.lCurChipScore = m_lCurChipScore;
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GIVE_UP, &gu, sizeof(gu));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GIVE_UP, &gu, sizeof(gu));
if (INVALID_CHAIR == m_wCurrentUser)
{
OnEventGameConclude(INVALID_CHAIR, nullptr, GER_NORMAL);
}
else
{
m_pITableFrame->SetGameTimer(IDI_WAIT_OPERATE, IDT_WAIT_OPERATE, 1, m_wCurrentUser);
}
return true;
}
bool CTableFrameSink::OnUserLookCard(WORD wChairID)
{
ASSERT(GS_ZJH_PLAYING == m_pITableFrame->GetGameStatus());
if (GS_ZJH_PLAYING != m_pITableFrame->GetGameStatus()) return true;
ASSERT(wChairID>=0 && wChairID<GAME_PLAYER);
if (wChairID >= GAME_PLAYER) return false;
ASSERT(IsGamingUser(wChairID));
if (!IsGamingUser(wChairID)) return true;
// <20><><EFBFBD><EFBFBD>״̬;
ASSERT(ST_GAMING_HIDDEN == m_cbGamingStatus[wChairID]);
if (ST_GAMING_HIDDEN != m_cbGamingStatus[wChairID])
{
return true;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
ASSERT(m_cbCurPlayRound >= m_cbCfgMinLookRound);
if (m_cbCurPlayRound < m_cbCfgMinLookRound)
{
return true;
}
m_cbGamingStatus[wChairID] = ST_GAMING_LOOK;
CMD_S_LookCard lc = { 0 };
lc.wLookUser = wChairID;
lc.stChipInfo.wCurrentUser = m_wCurrentUser;
for (int i = 0; i < m_wPlayerCount; ++i)
{
if (i!=wChairID)
{
m_pITableFrame->SendTableData(i, SUB_S_LOOK_CARD, &lc, sizeof(lc));
}
}
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_LOOK_CARD, &lc, sizeof(lc));
CopyMemory(lc.cbCardData, m_cbHandCardData[wChairID], sizeof(lc.cbCardData));
if (wChairID == m_wCurrentUser)
{
m_pITableFrame->KillGameTimer(IDI_WAIT_OPERATE);
m_dwOperateCode = MakeOperateCode(m_wCurrentUser);
lc.stChipInfo.cbCurRound = m_cbCurPlayRound;
lc.stChipInfo.wCurrentUser = m_wCurrentUser;
lc.stChipInfo.dwOperateCode = m_dwOperateCode;
lc.stChipInfo.lCurChipScore = m_lCurChipScore;
}
m_pITableFrame->SendTableData(wChairID, SUB_S_LOOK_CARD, &lc, sizeof(lc));
if (wChairID == m_wCurrentUser)
{
m_pITableFrame->SetGameTimer(IDI_WAIT_OPERATE, IDT_WAIT_OPERATE, 1, m_wCurrentUser);
}
return true;
}
bool CTableFrameSink::OnUserChipScore(WORD wChairID, DWORD dwOperateCode, LONG lUserChip)
{
ASSERT(GS_ZJH_PLAYING == m_pITableFrame->GetGameStatus());
if (GS_ZJH_PLAYING != m_pITableFrame->GetGameStatus()) return true;
ASSERT(wChairID >= 0 && wChairID < GAME_PLAYER);
if (wChairID >= GAME_PLAYER) return false;
ASSERT(IsGamingUser(wChairID));
if (!IsGamingUser(wChairID)) return true;
ASSERT(wChairID == m_wCurrentUser);
if (wChairID != m_wCurrentUser) return true;
ASSERT((m_dwOperateCode&dwOperateCode) != 0);
if (0 == (m_dwOperateCode&dwOperateCode)) return true;
ASSERT(OPERATE_FOLLOW==dwOperateCode || OPERATE_ADD_CHIP==dwOperateCode);
if (OPERATE_FOLLOW!=dwOperateCode && OPERATE_ADD_CHIP!=dwOperateCode) return true;
m_pITableFrame->KillGameTimer(IDI_WAIT_OPERATE);
LONG lChipScore = m_lCurChipScore;
if (OPERATE_ADD_CHIP == dwOperateCode)
{
ASSERT(lUserChip > m_lCurChipScore);
lChipScore = lUserChip;
m_lCurChipScore = lUserChip;
}
lChipScore = IsCardHidden(wChairID) ? lChipScore : lChipScore<<1;
m_lUserChipScore[wChairID] += lChipScore;
SwitchNextGamingUser(wChairID);
CMD_S_ChipScore cs = { 0 };
cs.wChipUser = wChairID;
cs.lChipScore = lChipScore;
cs.lTtlChipScore = m_lUserChipScore[wChairID];
cs.dwOperateCode = dwOperateCode;
cs.stChipInfo.cbCurRound = m_cbCurPlayRound;
cs.stChipInfo.wCurrentUser = m_wCurrentUser;
cs.stChipInfo.dwOperateCode = m_dwOperateCode;
cs.stChipInfo.lCurChipScore = m_lCurChipScore;
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_USER_CHIP, &cs, sizeof(cs));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_USER_CHIP, &cs, sizeof(cs));
if (INVALID_CHAIR == m_wCurrentUser)
{
OnEventGameConclude(INVALID_CHAIR, nullptr, GER_NORMAL);
}
else
{
m_pITableFrame->SetGameTimer(IDI_WAIT_OPERATE, IDT_WAIT_OPERATE, 1, m_wCurrentUser);
}
return true;
}
bool CTableFrameSink::OnUserCompareCard(WORD wChairID, DWORD dwOperateCode, WORD wCompareUser)
{
ASSERT(GS_ZJH_PLAYING == m_pITableFrame->GetGameStatus());
if (GS_ZJH_PLAYING != m_pITableFrame->GetGameStatus()) return true;
ASSERT(wChairID >= 0 && wChairID < GAME_PLAYER);
if (wChairID >= GAME_PLAYER) return false;
ASSERT(IsGamingUser(wChairID));
if (!IsGamingUser(wChairID)) return true;
ASSERT(wChairID == m_wCurrentUser);
if (wChairID != m_wCurrentUser) return true;
ASSERT((m_dwOperateCode&OPERATE_COMPARE_CARD) != 0);
if (0 == (m_dwOperateCode&OPERATE_COMPARE_CARD)) return true;
ASSERT(wCompareUser>=0 && wCompareUser<GAME_PLAYER);
ASSERT(IsUserPlaying(wCompareUser));
ASSERT(wChairID != wCompareUser);
m_pITableFrame->KillGameTimer(IDI_WAIT_OPERATE);
LONG lAddScore = IsCardHidden(wChairID) ? m_lCurChipScore : m_lCurChipScore<<1;
m_lUserChipScore[wChairID] += lAddScore;
bool bWin = m_GameLogic.CompareCard(m_cbHandCardData[wChairID],m_cbHandCardData[wCompareUser],MAX_COUNT);
if (bWin)
{
m_cbGamingStatus[wCompareUser] = ST_GAMING_LOSE;
}
else
{
m_cbGamingStatus[wChairID] = ST_GAMING_LOSE;
}
ASSERT(0 != m_cbGamingUserCount);
m_cbGamingUserCount--;
SwitchNextGamingUser(wChairID);
CMD_S_CompareCard cc = { 0 };
cc.bWin = bWin;
cc.wChairID = wChairID;
cc.wCompareUser = wCompareUser;
cc.lChipScore = lAddScore;
cc.lTtlChipScore = m_lUserChipScore[wChairID];
cc.stChipInfo.cbCurRound = m_cbCurPlayRound;
cc.stChipInfo.wCurrentUser = m_wCurrentUser;
cc.stChipInfo.dwOperateCode = m_dwOperateCode;
cc.stChipInfo.lCurChipScore = m_lCurChipScore;
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_COMPARE_CARD, &cc, sizeof(cc));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_COMPARE_CARD, &cc, sizeof(cc));
if (INVALID_CHAIR == m_wCurrentUser)
{
OnEventGameConclude(INVALID_CHAIR, nullptr, GER_NORMAL);
}
else
{
m_pITableFrame->SetGameTimer(IDI_WAIT_OPERATE, IDT_WAIT_OPERATE, 1, m_wCurrentUser);
}
return true;
}
bool CTableFrameSink::OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason)
{
m_pITableFrame->KillGameTimer(IDI_SEND_CARD);
m_pITableFrame->KillGameTimer(IDI_WAIT_OPERATE);
switch (cbReason)
{
case GER_DISMISS:
{
CMD_S_GameEnd ge = { 0 };
ge.isPrivateEnd = true;
CopyMemory(ge.cbGamingStatus, m_cbGamingStatus, sizeof(m_cbGamingStatus));
CopyMemory(ge.cbHandCardData, m_cbHandCardData, sizeof(m_cbHandCardData));
for (int i = 0; i < m_wPlayerCount; ++i)
{
if (!IsUserPlaying(i)) continue;
ge.cbCardType[i] = m_GameLogic.GetCardType(m_cbHandCardData[i], MAX_COUNT);
m_PrivateEndInfo.aryActiveStatus[i] = m_cbGamingStatus[i];
}
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &ge, sizeof(ge));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &ge, sizeof(ge));
return m_pITableFrame->ConcludeGame(GAME_STATUS_FREE, cbReason);
}
case GER_NORMAL:
{
/********************************˽<>˳<EFBFBD>ͳ<EFBFBD><CDB3>****************************************/
m_pITableFrame->addPrivatePlayCout(1);
/********************************˽<>˳<EFBFBD>ͳ<EFBFBD><CDB3>****************************************/
CMD_S_GameEnd ge = { 0 };
ge.isPrivateEnd = IsPrivateEnd();
WORD wWinUser = (1 == m_cbGamingUserCount ? CountLastWinUser() : INVALID_CHAIR);
WORD wNextRoundBanker = CountGameScore(wWinUser, ge.lGameScore);
CopyMemory(ge.cbGamingStatus, m_cbGamingStatus, sizeof(m_cbGamingStatus));
CopyMemory(ge.cbHandCardData, m_cbHandCardData, sizeof(m_cbHandCardData));
LONG lRevenue[GAME_PLAYER] = { 0 };
for (int i = 0; i < m_wPlayerCount; ++i)
{
if (!IsUserPlaying(i)) continue;
ge.cbCardType[i] = m_GameLogic.GetCardType(m_cbHandCardData[i], MAX_COUNT);
lRevenue[i] = static_cast<LONG>(m_pITableFrame->CalculateRevenue(i, ge.lGameScore[i]));
ge.lGameScore[i] -= lRevenue[i];
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴ<EFBFBD><C6B4><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>1;
if ((ST_GAMING_GIVEUP==m_cbGamingStatus[i]) || (m_cbHideCardRound[i]<1)) continue;
int nXiScore = m_GameLogic.GetXiScore(ge.cbCardType[i], m_cbHandCardData[i][0]);
if (nXiScore>0)
{
for (int j = 0; j < m_wPlayerCount; ++j)
{
if (!IsUserPlaying(j)) continue;
if (j!=i)
{
ge.lXiScore[j] -= nXiScore;
ge.lXiScore[i] += nXiScore;
}
}
}
}
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &ge, sizeof(ge));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &ge, sizeof(ge));
//<2F>޸Ļ<DEB8><C4BB><EFBFBD>;
tagScoreInfo ScoreInfoArray[GAME_PLAYER];
ZeroMemory(ScoreInfoArray, sizeof(ScoreInfoArray));
for (int i = 0; i < m_wPlayerCount; ++i)
{
if (!IsUserPlaying(i)) continue;
m_PrivateEndInfo.aryActiveStatus[i] = m_cbGamingStatus[i];
m_PrivateEndInfo.aryWinScore[i] += ge.lGameScore[i];
m_PrivateEndInfo.aryXiScore[i] += ge.lXiScore[i];
m_PrivateEndInfo.aryTotalScore[i] += ge.lGameScore[i] + ge.lXiScore[i];
ScoreInfoArray[i].cbType = (IsGamingUser(i)) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
ScoreInfoArray[i].lRevenue = lRevenue[i];
ScoreInfoArray[i].lScore = ge.lGameScore[i] + ge.lXiScore[i];
}
//<2F>ƾֽ<C6BE><D6BD><EFBFBD><EFBFBD><EFBFBD>,ÿ8<C3BF><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><E3BEAD>ֵ;
if (IsPrivateEnd())
{
//tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
//SCORE lGrade = pPrivateFrame->dwPlayCost;
ScoreInfoArray[0].lGrade = 2; //<2F><><EFBFBD><EFBFBD>2<EFBFBD><32>;
for (WORD i = 1; i < GAME_PLAYER; i++)
{
ScoreInfoArray[i].lGrade = 1;
}
}
m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray));
//<2F><>һ<EFBFBD><D2BB>ׯ<EFBFBD><D7AF>;
if (INVALID_CHAIR != wNextRoundBanker)
{
m_wBankerUser = wNextRoundBanker;
}
else
{
ASSERT(m_cbGamingUserCount > 1);
m_wBankerUser = FindNextGamingUser(m_wBankerUser);
}
m_pITableFrame->ConcludeGame(GAME_STATUS_FREE, cbReason);
return true;
}
case GER_USER_LEAVE:
case GER_NETWORK_ERROR:
{
ASSERT(0);
return true;
}
}
ASSERT(0);
return false;
}
DWORD CTableFrameSink::MakeOperateCode(WORD wChairID)
{
ASSERT(wChairID>=0 && wChairID<GAME_PLAYER);
ASSERT(wChairID == m_wCurrentUser);
ASSERT(IsGamingUser(wChairID));
if (!IsGamingUser(wChairID)) return OPERATE_NULL;
IServerUserItem *pIServerUserItem = m_pITableFrame->GetTableUserItem(wChairID);
ASSERT(nullptr != pIServerUserItem);
if (nullptr == pIServerUserItem) return OPERATE_NULL;
DWORD dwOperateCode = OPERATE_GIVEUP | OPERATE_FOLLOW;
//// <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>Կ<EFBFBD><D4BF><EFBFBD>;
//if ((m_cbCurPlayRound > m_cbCfgMinLookRound) && (ST_GAMING_HIDDEN == m_cbGamingStatus[wChairID]))
//{
// dwOperateCode |= OPERATE_LOOK;
//}
// <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>Լ<EFBFBD>ע;
if ((m_lCfgMinChipScore != m_lCfgMaxChipScore) && (m_lCurChipScore<m_lCfgMaxChipScore))
{
dwOperateCode |= OPERATE_ADD_CHIP;
}
// <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD>;
if ((m_cbCurPlayRound >= m_cbCfgMinCompareRound) && (m_cbGamingUserCount >= m_cbCfgMinCompareUser))
{
dwOperateCode |= OPERATE_COMPARE_CARD;
}
return dwOperateCode;
}
WORD CTableFrameSink::FindNextGamingUser(WORD wChairID)
{
ASSERT(wChairID>=0 && wChairID<GAME_PLAYER);
ASSERT(0 != m_cbGamingUserCount);
if (1 == m_cbGamingUserCount)
{
return IsGamingUser(wChairID) ? wChairID : INVALID_CHAIR;
}
WORD wNextUser = wChairID;
for (WORD i=0; i<m_wPlayerCount; ++i)
{
if (++wNextUser == m_wPlayerCount)
{
wNextUser = 0;
}
if (IsGamingUser(wNextUser))
{
return wNextUser;
}
}
return INVALID_CHAIR;
}
void CTableFrameSink::SwitchNextGamingUser(WORD wChairID)
{
ASSERT(0 != m_cbGamingUserCount);
ASSERT(wChairID == m_wCurrentUser);
m_dwOperateCode = 0;
m_wCurrentUser = INVALID_CHAIR;
if (1 == m_cbGamingUserCount) return;
m_wCurrentUser = FindNextGamingUser(wChairID);
ASSERT(m_wCurrentUser>=0 && m_wCurrentUser<GAME_PLAYER);
ASSERT(IsGamingUser(m_wCurrentUser));
if (m_wCurrentUser == m_wFirstOperateUser)
{
if ((0 != m_cbCfgMaxPlayRound) && (m_cbCurPlayRound >= m_cbCfgMaxPlayRound))
{
m_wCurrentUser = INVALID_CHAIR;
return;
}
else
{
m_cbCurPlayRound++;
for (WORD i = 0; i<m_wPlayerCount; ++i)
{
if (ST_GAMING_HIDDEN == m_cbGamingStatus[i])
{
m_cbHideCardRound[i]++;
}
}
}
}
//<2F>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>;
if (!IsGamingUser(m_wFirstOperateUser))
{
m_wFirstOperateUser = FindNextGamingUser(m_wFirstOperateUser);
ASSERT(INVALID_CHAIR != m_wFirstOperateUser);
}
m_dwOperateCode = MakeOperateCode(m_wCurrentUser);
ASSERT(0 != m_dwOperateCode);
}
WORD CTableFrameSink::CountLastWinUser()
{
ASSERT(1 == m_cbGamingUserCount);
for (WORD i = 0; i < m_wPlayerCount; ++i)
{
if (IsGamingUser(i))
{
return i;
}
}
ASSERT(0);
return INVALID_CHAIR;
}
WORD CTableFrameSink::CountGameScore(WORD wWinner, LONG lGameScore[GAME_PLAYER])
{
if (INVALID_CHAIR != wWinner)
{
ASSERT(1 == m_cbGamingUserCount);
ASSERT(wWinner == CountLastWinUser());
}
else
{
ASSERT(m_cbGamingUserCount > 1);
}
if (INVALID_CHAIR != wWinner)
{
for (WORD i=0; i<m_wPlayerCount; ++i)
{
if (i == wWinner) continue;
lGameScore[i] = -m_lUserChipScore[i];
lGameScore[wWinner] += m_lUserChipScore[i];
}
return wWinner;
}
else
{
LONG lTotalScore = 0;
WORD wWinnerCount = 0;
WORD wWinUser = INVALID_CHAIR;
for (WORD i=0; i<m_wPlayerCount; ++i)
{
lTotalScore += m_lUserChipScore[i];
if (!IsGamingUser(i)) continue;
for (WORD j=i+1; j<m_wPlayerCount; ++j)
{
if (!IsGamingUser(j)) continue;
//if (m_GameLogic.CompareCard(m_cbHandCardData[j],m_cbHandCardData[i],MAX_COUNT))
if (m_GameLogic.AutoCompareCard(m_cbHandCardData[j], m_cbHandCardData[i], MAX_COUNT))
{
wWinUser = j;
m_cbGamingStatus[i] = ST_GAMING_LOSE;
break;
}
else
{
wWinUser = i;
m_cbGamingStatus[j] = ST_GAMING_LOSE;
}
}
if (IsGamingUser(i))
{
wWinnerCount++;
}
}
ASSERT(lTotalScore > 0);
ASSERT(wWinUser>=0 && wWinUser<GAME_PLAYER);
ASSERT(0 != wWinnerCount);
LONG lWinScore = lTotalScore / wWinnerCount;
for (WORD i=0; i<m_wPlayerCount; i++)
{
if (IsGamingUser(i))
{
ASSERT(i == wWinUser);
lGameScore[i] = lTotalScore - m_lUserChipScore[i];
}
else
{
lGameScore[i] = -m_lUserChipScore[i];
}
}
return wWinUser;
}
ASSERT(0);
return INVALID_CHAIR;
}
////////////////////////////// ˽<>˳<EFBFBD> ////////////////////////////////////////////
void CTableFrameSink::SetPrivateInfo(BYTE cbGameTypeIndex, DWORD dwGameRule)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
if ((dwGameRule&eZJHGameRuleCompareRound2)>0)
{
m_cbCfgMinCompareRound = 2;
}
else if ((dwGameRule&eZJHGameRuleCompareRound3)>0)
{
m_cbCfgMinCompareRound = 3;
}
else
{
m_cbCfgMinCompareRound = 1;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
if ((dwGameRule&eZJHGameRuleOpenCardRound10) > 0)
{
m_cbCfgMaxPlayRound = 10;
}
else if ((dwGameRule&eZJHGameRuleOpenCardRound15) > 0)
{
m_cbCfgMaxPlayRound = 15;
}
else
{
m_cbCfgMaxPlayRound = 5;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
if ((dwGameRule&eZJHGameRuleLookCardRound2) > 0)
{
m_cbCfgMinLookRound = 2;
}
else if ((dwGameRule&eZJHGameRuleLookCardRound3) > 0)
{
m_cbCfgMinLookRound = 3;
}
else
{
m_cbCfgMinLookRound = 0;
}
}
void CTableFrameSink::ResetPrivateEndInfo()
{
ZeroMemory(&m_PrivateEndInfo, sizeof(CMD_S_Private_End_Info));
m_wBankerUser = INVALID_CHAIR;
m_cbPlayTimes = 0;
m_cbMasterCtrlType = 0;
m_wMasterChairID = INVALID_CHAIR;
}
//<2F><><EFBFBD><EFBFBD>˽<EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>;
void CTableFrameSink::GetPrivateEndInfo(DataStream &kDataStream, bool bSend)
{
m_PrivateEndInfo.StreamValue(kDataStream, bSend);
}
//<2F>ж<EFBFBD>˽<EFBFBD>˳<EFBFBD><CBB3>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>;
bool CTableFrameSink::IsPrivateEnd()
{
if (m_pITableFrame == nullptr) return false;
tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
tagPrivateFrameRecordInfo* pPrivateRecord = m_pITableFrame->GetPrivateFrameRecord();
if ((pPrivateFrame == nullptr) || (pPrivateRecord == nullptr)) return false;
if (pPrivateFrame->cbGameCout <= pPrivateRecord->cbFinishCout)
{
return true;
}
return false;
}