当前位置:文档之家› 棋牌游戏 两人斗地主 源代码(服务端)

棋牌游戏 两人斗地主 源代码(服务端)

========================================================================
MICROSOFT 基础类库 : UpGradeDLL 项目概况
========================================================================


应用程序向导已为您创建了此 UpGradeDLL DLL。此 DLL 不仅
说明了使用 Microsoft 基础类的基础,而且
也是编写 DLL 的起点。

此文件包含组成 UpGradeDLL DLL
的每个文件的内容摘要。

UpGradeDLL.vcproj
这是用应用程序向导生成的 VC++ 项目的主项目文件。
它包含有关生成此文件的 Visual C++ 版本的信息,以及
有关使用应用程序向导选择的
平台、配置和项目功能的信息。

UpGradeDLL.cpp
这是包含 DllMain()
定义的主 DLL 源文件。
UpGradeDLL.rc
这是程序使用的所有 Microsoft Windows 资源的列表。
它包含存储在 RES 子目录下的图标、位图和光标。
此文件可在 Microsoft Visual C++ 中直接编辑。


res\UpGradeDLL.rc2
此文件包含不由 Microsoft
Visual C++ 编辑的资源。您应将不能由
资源编辑器编辑的所有资源放置在此文件中。

UpGradeDLL.def
此文件包含有关运行 Microsoft Windows
所需的 DLL 的信息。
它定义此 DLL 的名称和说明等参数。
它还从此 DLL 导出函数。

/////////////////////////////////////////////////////////////////////////////
其他标准文件:

StdAfx.h、StdAfx.cpp
这些文件用于生成名为 UpGradeDLL.pch
的预编译头(PCH)文件以及名为 StdAfx.obj 的预编译类型文件。

Resource.h
这是标准的头文件,它定义了新的资源 ID。
Microsoft Visual C++ 读取和更新此文件。

/////////////////////////////////////////////////////////////////////////////
其他注释:

应用程序向导使用 "TODO:" 注释指示应添加或自定义的源代码部分。

/////////////////////////////////////////////////////////////////////////////
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by UpGradeDLL.rc
//

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 5000
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 5000
#define _APS_NEXT_SYMED_VALUE 5000
#endif
#endif

#include "StdAfx.h"
#include "ServerManage.h"
//处理当前出牌用户申请托管
void CServerGameDesk::TuoGuanNowUser(BYTE bDeskStation,bool isTuoGuan)
{
try//去掉后出现L死了.
{
//if(bWatchUser ) return false;
m_bTuoGuan[bDeskStation]=isTuoGuan;

//群发托管信息
TuoGuanStruct TGS;
for (int i=0;ifor (int i=0;iSendGameData(i,&TGS,sizeof(TGS),MDM_GM_GAME_NOTIFY,ASS_GM_TUOGUAN,0);
SendWatchData(m_bMaxPeople,&TGS,sizeof(TGS),MDM_GM

_GAME_NOTIFY,ASS_GM_TUOGUAN,0);




//结束群发托管信息
if (isTuoGuan)//托管了
{
m_iTuoGuanCount[bDeskStation]++;


//三个托管,游戏结束
for (int i=0;i{
if (!m_bTuoGuan[i])break;
if (i==PLAY_COUNT-1)
{
GameFinish(bDeskStation,GF_SALE);
return;
}
}



switch(m_TuoGuanState)
{
case TG_JIAOFEN://叫分期间断线,放弃叫分,肩头移动到下一家
{
if (m_iOutCardPeople == bDeskStation)//如果当前叫分用户断线,那么叫0分
UserJiaoFen(bDeskStation,0);
break;
}
case TG_QIANGDZ://抢地主期间断线,不抢地主,箭头移动到下一家
{
if (m_iOutCardPeople == bDeskStation)//如果当前抢地主用户断线,那么不抢地主
UserQianDZ(bDeskStation,0);
break;
}
case TG_PLAY://打牌期间断线(明牌期间断线)
{
if (m_iOutCardPeople == bDeskStation){//如果当前出牌用户断线,那么新一轮开始


if ((bDeskStation==m_iLastOutPeople)||(m_iLastOutPeople==255))//如果轮到我出牌,出一张最小的
{
BYTE m_card[1];
m_card[0]=m_iUserCard[bDeskStation][m_iUserCardCount[bDeskStation]-1];
UserOutCard(bDeskStation,m_card,1);//出一张最小的;
}
else{

m_iOutCardPeople = (m_iOutCardPeople + 1) % PLAY_COUNT;//下一个出牌用户

if(m_bTuoGuan[m_iOutCardPeople]){
m_iOutCardPeople = (m_iOutCardPeople + 1) % PLAY_COUNT;//如果下一个下一个该出牌的用户托管,那么再下一个出牌用户
if(m_bTuoGuan[m_iOutCardPeople])GameFinish(bDeskStation,GF_SALE);//三人托管就退出
}


if ((m_iOutCardPeople==m_iLastOutPeople)||(m_iLastOutPeople==255)||(bDeskStation==m_iLastOutPeople)||(bDeskStation==m_iOutCardPeople))//如果轮到我出牌,新一轮从下一个用户开始
{
m_iBaseOutCount=0;
m_iFirstOutPeople=m_iOutCardPeople;//先出用户
m_iLastOutPeople=m_iOutCardPeople;//请空最后出牌用户
::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
for (int i=0;iSendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_NEW_TURN,m_iOutCardPeople);
}
else//否则,我过牌
{
for (int i=0;iSendGameData(i,MDM_GM_GAME_NOTIFY,ASS_PASS,m_iOutCardPeople);
SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_PASS,m_iOutCardPeople);
}
}
}
//以下注释掉了,改成自动出牌了
//else{
//如果托管用户不是当前用户,但是是最后出牌用户,那么新一轮开始,
//if (bDeskStation==m_iLastOutPeople)//如果轮到我出牌,新一轮从下一个用户开


// {

// m_iBaseOutCount=0;
// m_iFirstOutPeople=m_iOutCardPeople;//先出用户
// ::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
// for (int i=0;i// SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_NEW_TURN,m_iOutCardPeople);

// }
//}

break;
}
case TG_AGREE://同意开始到发牌前断线,,直接退出
default://没有开始,直接退出
{
GameFinish(bDeskStation,GF_SALE);//三人托管就退出
break;
}
}
}
}
catch(...)
{
AfxMessageBox("托管异常!!!");
}
}

//初始化函数,服务器加载DLL时候,按数据库中的桌子数量创建线程,执行完构造函数就执行这个
//为在能在初试化实现设置游戏规则,变为虚函数,由子类,各游戏分别设置
void CServerGameDesk::Init(BYTE bDeskIndex, BYTE bMaxPeople, CGameMainManage * pDataManage)
{

__super::Init(bDeskIndex, bMaxPeople,pDataManage);

//疯狂翻倍斗地主游戏中,不同规则对应不同洗牌规则,对RoomRule字段设置如下数值,会产生不同规则
// 默认(随机炸弹)(默认规则) 填写0
// 平均每人1个炸弹(扩展规则一) 填写256
// 平均每人2个炸弹(扩展规则二) 填写512
// 平均每人3个炸弹(扩展规则三) 填写1024
// 平均每人4个炸弹(扩展规则四) 填写2048
m_BombCount=1;
if ((m_pDataManage->m_InitData.dwRoomRule&GRR_ROOM_RULE1)!=0)m_BombCount=2;
else if ((m_pDataManage->m_InitData.dwRoomRule&GRR_ROOM_RULE2)!=0)m_BombCount=3;
else if ((m_pDataManage->m_InitData.dwRoomRule&GRR_ROOM_RULE3)!=0)m_BombCount=4;
else if ((m_pDataManage->m_InitData.dwRoomRule&GRR_ROOM_RULE4)!=0)m_BombCount=5;


}

//发送底牌
void CServerGameDesk::SendBackCard()
{
try
{

//保存数据
m_bGameStation=GS_WAIT_BACK;//等待发底牌状态

//TCHAR ourstr[100];
//sprintf(ourstr,TEXT("%d,%d,%d,%d"),m_iBackCard[0],m_iBackCard[1],m_iBackCard[2],m_iNtPeopole);//第一个树。多少人在线
//AfxMessageBox(ourstr);


::CopyMemory(&m_iUserCard[m_iNtPeopole][m_iUserCardCount[m_iNtPeopole]],m_iBackCard,sizeof(BYTE)*3);//给地主加三张牌
::CopyMemory(&m_iUserCardBake[m_iNtPeopole][m_iUserCardCount[m_iNtPeopole]],m_iBackCard,sizeof(BYTE)*3);//给地主加三张牌
m_iUserCardCount[m_iNtPeopole]+=3;



//int lzdian=-1;//m_Logic.GetCardNum(m_iBackCard[1]) + 1;

//if (m_iBackCard[1]==0x4F || m_iBackCard[1]==0x4E)
// lzdian =3;
//else
//{
// lzdian=m_Logic.GetCardNum(m_iBackCard[1]) + 1;
// if(lzdian > 14)lzdian = 2;
//}

//m_Logic.m_bLaiZiPaiDian = lzdian;
//BackCard.iNtHua=m_Logic.GetNTHuaKind();
//BackCard.iLaiZiPaiDian=m_Logic.m_bLaiZiPaiDian;

BackCardExStruct BackCard;
BackCard.iNtPeopole=m_iNtPeopole;
::CopyMemory(BackCard.iBackCard,m

_iBackCard,sizeof(BYTE)*3);

for (int i=0;iSendWatchData(m_bMaxPeople,&BackCard,sizeof(BackCard),MDM_GM_GAME_NOTIFY,ASS_BACK_CARD_ADD,0);
//

BeginOutCard();

}catch(...)
{
AfxMessageBox("SendBackCard!!!");
}

}

//游戏开始,开始出牌
void CServerGameDesk::BeginOutCard()
{
try{
//设置数据
m_bGameStation=GS_PLAY_GAME;
m_TuoGuanState=TG_PLAY;
m_iBaseOutCount=0;
m_iOutCardPeople=m_iNtPeopole;//当前出牌用户
m_iFirstOutPeople=m_iNtPeopole;
m_iLastOutPeople = -1;
IsNewTurn = false;

::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
::memset(m_iTurePoint,0,sizeof(m_iTurePoint));


//排列扑克
for (int i=0;i
//发送游戏开始消息
for (int i=0;iSendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_GAME_PLAY,m_iOutCardPeople);
}catch(...)
{AfxMessageBox("BeginOutCard异常!!!");//try{
}
}


//用户抢地主处理
bool CServerGameDesk::UserQianDZ(BYTE bDeskStation,bool isQiang)
{
if (isQiang)//抢地主了
{
m_iUserJiaoFen[bDeskStation]=2*m_iUserJiaoFen[m_iNtPeopole];//原来斗地主翻倍
m_iNtPeopole = bDeskStation;//庄家位置=现在位置
QianDZBei*=2;
}

QianDZcount++;

SendQiangDZ(bDeskStation,isQiang);//发送抢地主标志
if (QianDZcount>=2){//超过3次,一轮,就开始发底牌
QianDZcount=0;
SendBackCard();//超过3次,一轮发送底牌
}

return true;

}

//发送抢地主信息
void CServerGameDesk::SendQiangDZ(BYTE bDeskStation,bool bQiang)//上轮抢地主者//上轮是否抢过//已抢的次数
{


//发送抢地主给客户端
m_TuoGuanState=TG_QIANGDZ;
QiangDZStruct QDZ;
QDZ.iDeskStation=bDeskStation;//上轮抢地主者
QDZ.iQiang=bQiang;//上轮是否抢过
m_iOutCardPeople=(bDeskStation + 1) % PLAY_COUNT;//下一个该抢地主者
if(m_bTuoGuan[m_iOutCardPeople]){m_iOutCardPeople= (m_iOutCardPeople + 1) % PLAY_COUNT; QianDZcount++;}//如果下一个下一个该出牌的用户托管,那么再下一个出牌用户
if(m_bTuoGuan[m_iOutCardPeople])GameFinish(m_iOutCardPeople,GF_SALE);//三人托管就退出

QDZ.iCount=QianDZcount;//已抢的次数

QDZ.iNextDeskStation=m_iOutCardPeople;

for (int i = 0;i < PLAY_COUNT;i++)
SendGameData(i,&QDZ,sizeof(QDZ),MDM_GM_GAME_NOTIFY,ASS_QiangDZ,0);
SendWatchData(m_bMaxPeople,&QDZ,sizeof(QDZ),MDM_GM_GAME_NOTIFY,ASS_QiangDZ,0);


}

//游戏数据包处理函数
bool CServerGameDesk::HandleNotifyMessage(BYTE bDeskStation, NetMessageHead * pNetHead, void * pData, UINT uSize, UINT uSocketID, bool bWatchUser)
{


switch (pNetHead->bAssistantID)
{

case ASS_LIANGPAIDA: //地主亮牌打牌
{
if(bWatchUser || m_iNtPeopole

!= bDeskStation) return false;

m_iUserJiaoFen[m_iNtPeopole] *= 3;//翻3倍
MingPaiBei=3;/*明牌倍数*/
BYTE iCardCount=m_iUserCardCount[m_iNtPeopole];
m_Logic.SortCard (m_iUserCard[m_iNtPeopole],false,iCardCount);

//OutCardMsg UserOut;
//UserOut.bDeskStation=m_iNtPeopole;//地主位置
//UserOut.iNextDeskStation=-1;
//UserOut.iCardCount=iCardCount;
//::CopyMemory(UserOut.iCardList,m_iUserCard[m_iNtPeopole],sizeof(BYTE)*iCardCount);
// int iSendSize=sizeof(UserOut)-sizeof(UserOut.iCardList)+sizeof(BYTE)*iCardCount;

OutCardStruct NtCard;
NtCard.iCardCount=iCardCount;
::CopyMemory(NtCard.iCardList,m_iUserCard[m_iNtPeopole],sizeof(BYTE)*iCardCount);

for (int i=0;iSendWatchData(m_bMaxPeople,&NtCard,sizeof(NtCard)/*-sizeof(NtCard.iCardList)+sizeof(BYTE)*NtCard.iCardCount*/,MDM_GM_GAME_NOTIFY,ASS_LIANGPAIDA,0);
return true;
}
case ASS_RESEND_CARD: //超人来了
{
NYS_DeskStation=bDeskStation;
return true;
}
case ASS_OUT_CARD: //用户出牌
{
if(bWatchUser)
return false;
if(m_bGameStation==GS_WAIT_NEXT || m_bGameStation==GS_WAIT_ARGEE || m_bGameStation==GS_WAIT_SETGAME)
return true;
OutCardStruct * pOutCard=(OutCardStruct *)pData;
if ((uSize<=(sizeof(OutCardStruct)-sizeof(pOutCard->iCardList)))
||(uSize>sizeof(OutCardStruct))||bWatchUser) return FALSE;
if (uSize!=(sizeof(OutCardStruct)-sizeof(pOutCard->iCardList)+sizeof(BYTE)*pOutCard->iCardCount)) return FALSE;
return UserOutCard(bDeskStation,pOutCard->iCardList,pOutCard->iCardCount);
}

//case ASS_CONTINUE_END:// 正常结束
// {
// if(bWatchUser)return false;
// //直接关闭
// ReSetGameState(GFF_FORCE_FINISH);
// __super::GameFinish(bDeskStation,GFF_FORCE_FINISH);
//
// return true;
// }

case ASS_PASS://不出,过牌
{
if (bWatchUser) return false;
if(m_bGameStation==GS_WAIT_NEXT || m_bGameStation==GS_WAIT_ARGEE || m_bGameStation==GS_WAIT_SETGAME)
return true;


for (int i=0;iSendGameData(i,MDM_GM_GAME_NOTIFY,ASS_PASS_MSG,bDeskStation);

SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_PASS_MSG,bDeskStation);


IsNewTurn = false;
m_iOutCardPeople = bDeskStation;//获取当前出牌用户
int lastOutPeople=m_iLastOutPeople;//记忆最后出牌

//计算下一出牌者
m_iOutCardPeople = (m_iOutCardPeople + 1) % PLAY_COUNT;//下一个出牌用户

if(m_bTuoGuan[m_iOutCardPeople])
{
if ((m_iOutCardPeople==m_iLastOutPeople)||(m_iLastOutPeople==255))//如果下一家是最后出牌用户,那么他出一张最小的
{
BYTE m_card[1];
m_card[0]=m_iUserCard[m_iOutCardPeople][m_

iUserCardCount[m_iOutCardPeople]-1];
UserOutCard(m_iOutCardPeople,m_card,1);//出一张最小的;
IsNewTurn = true;
}
else
{
m_iOutCardPeople = (m_iOutCardPeople + 1) % PLAY_COUNT;//如果下一个下一个该出牌的用户托管,那么再下一个出牌用户
if(m_bTuoGuan[m_iOutCardPeople])GameFinish(bDeskStation,GF_SALE);//三人托管就退出

}
}


if (!IsNewTurn)
{

if (m_iOutCardPeople == m_iLastOutPeople) m_iLastOutPeople = -1;//如果下一个出牌用户=最后一个出牌用户

if (m_iLastOutPeople < 0)//如果下一个出牌用户(非托管)=最后一个出牌用户。新轮从他开始
{
if (lastOutPeople >= 0)// 不是第一轮
{m_iBaseOutCount=0;
m_iFirstOutPeople=m_iOutCardPeople;//先出用户
::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));//清空数组
for (int i=0;iSendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_NEW_TURN,m_iOutCardPeople);
IsNewTurn = true;

}
}
}


if (!IsNewTurn)
{
for (int i=0;iSendGameData(i,MDM_GM_GAME_NOTIFY,ASS_PASS,m_iOutCardPeople);
SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_PASS,m_iOutCardPeople);
}


return true;
}
case ASS_QiangDZ://抢地主
{
if (bWatchUser) return false;
if(m_bGameStation==GS_WAIT_NEXT || m_bGameStation==GS_WAIT_ARGEE || m_bGameStation==GS_WAIT_SETGAME)
return true;
return UserQianDZ(bDeskStation,pNetHead->bHandleCode==1);//处理叫分
}
case ASS_JIAO_FEN://叫分
{
if (bWatchUser) return false;
if(m_bGameStation==GS_WAIT_NEXT || m_bGameStation==GS_WAIT_ARGEE || m_bGameStation==GS_WAIT_SETGAME)return true;
return UserJiaoFen(bDeskStation,pNetHead->bHandleCode);//处理叫分
}

}


return __super::HandleNotifyMessage(bDeskStation,pNetHead,pData,uSize,uSocketID,bWatchUser);//托管,举手等。
}




//用户出牌
bool CServerGameDesk::UserOutCard(BYTE bDeskStation, BYTE iOutCard[], int iCardCount)
{
try{

if (bDeskStation!=m_iOutCardPeople) return false;//如果发出牌信息的坐号,不是服务器上应该出牌的帐户

BOOL bShowFalse=FALSE;

if (bDeskStation==m_iNtPeopole)//地主出牌
TML_dz_OutCount++;
else TML_nm_OutCount++;//农民出牌



int fpd=-1;
//是否火箭
m_Logic.SortCard(iOutCard,NULL,iCardCount);
if(iCardCount==2){
if((iOutCard[0] == 0x4F)&&(iOutCard[1] == 0x4E))
{
RockBei*=2;/*火箭倍数*/
m_iUserJiaoFen[m_iNtPeopole] *= 2;fpd=0;
}
}

if(m_Logic.IsBomb(iOutCard , iCardCount,fpd)){BombBei*=2;/*炸弹倍数*/
m_iUserJiaoFen[m_iNtPeopole] *= 2;fpd=0;}

if (fpd==0)
{ //发送倍数

给客户端
UserJiaoFenStruct jiaoFenInfo;
jiaoFenInfo.iFen = m_iUserJiaoFen[m_iNtPeopole];
jiaoFenInfo.iNextDeskStation =8;//8是发送倍数给客户端
for (int i = 0;i < PLAY_COUNT;i++)
SendGameData(i,&jiaoFenInfo,sizeof(jiaoFenInfo),MDM_GM_GAME_NOTIFY,ASS_JIAO_FEN,0);
SendWatchData(m_bMaxPeople,&jiaoFenInfo,sizeof(jiaoFenInfo),MDM_GM_GAME_NOTIFY,ASS_JIAO_FEN,0);
//结束发送倍数给客户端
}
fpd=-1;


//删除扑克
if (m_Logic.RemoveCard(iOutCard,iCardCount,m_iUserCard[bDeskStation],m_iUserCardCount[bDeskStation])==0)//用户手上扑克数目
return false;
m_iUserCardCount[bDeskStation]-=iCardCount;//用户手上扑克数目

//记录出牌信息
m_iDeskCardCount[bDeskStation]=iCardCount;
::CopyMemory(m_iDeskCard[bDeskStation],iOutCard,sizeof(BYTE)*iCardCount);

////记下当前出牌用户
m_iLastOutPeople = bDeskStation;//最后出牌用户
int lastOutPeople = bDeskStation;//最后出牌用户m_iLastOutPeople
IsNewTurn = false;//不是新一轮
//for (int i = 0;i < 2;i++)
{
//计算下一出牌者
m_iOutCardPeople = (bDeskStation + 1) % PLAY_COUNT;//下一个出牌用户
if (m_iOutCardPeople == m_iLastOutPeople) m_iLastOutPeople = -1;//如果下一个出牌用户=最后一个出牌用户
}

if(m_bTuoGuan[m_iOutCardPeople])m_iOutCardPeople = (m_iOutCardPeople + 1) % PLAY_COUNT;//如果下一个下一个该出牌的用户托管,那么再下一个出牌用户
if(m_bTuoGuan[m_iOutCardPeople]){m_iWinStation = bDeskStation;
GameFinish(bDeskStation,GF_NORMAL);
return TRUE; };//三人托管就退出



// 群发当前送出的牌
OutCardMsg UserOut;
UserOut.bDeskStation=bDeskStation;//当前出牌者
UserOut.iLessCardCount=m_iUserCardCount[bDeskStation];
UserOut.iNextDeskStation=m_iOutCardPeople;//下一出牌者
UserOut.iCardCount=iCardCount;
::CopyMemory(UserOut.iCardList,iOutCard,sizeof(BYTE)*iCardCount);
//int iSendSize=sizeof(UserOut)-sizeof(UserOut.iCardList)+sizeof(BYTE)*iCardCount;
for (int i=0;iSendWatchData(m_bMaxPeople,&UserOut,sizeof(OutCardMsg),MDM_GM_GAME_NOTIFY,ASS_OUT_CARD,0);


// if (m_iLastOutPeople < 0)//如果下一个出牌用户=最后一个出牌用户
// {
// if (lastOutPeople >= 0)// 不是第一轮
// {
//CString SS="";
//SS.Format("m_iLastOutPeople%d lastOutPeople%d",m_iLastOutPeople,lastOutPeople);
//AfxMessageBox(SS);
// m_iBaseOutCount=0;
// m_iFirstOutPeople=m_iOutCardPeople;//先出用户
// ::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
// for (int i=0;i// SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_NEW_TURN,m_iOutCardPeople);
// IsNewTurn = true;
//
// }
// }

//m_iBaseOutCount=0;
//m_iOutCardPeople=iWiner;
//m_iFirstOutPeople=iWiner;
//::memset(m_iDeskCardCount,

0,sizeof(m_iDeskCardCount));
//for (int i=0;i//SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_NEW_TURN,iWiner);
//return TRUE;
//NewPlayTurn(bDeskStation);//新一轮开始


//发送结束标志
if (m_iUserCardCount[bDeskStation] == 0)//用户手上扑克数目为0,结束本局
{ m_iWinStation = bDeskStation;
GameFinish(bDeskStation,GF_NORMAL);
return TRUE;
}
return TRUE;

}catch(...)
{AfxMessageBox("UserOutCard异常!!!");
}
return TRUE;
}





//构造函数
CServerGameDesk::CServerGameDesk(void):CGameDesk(FULL_BEGIN)
{
m_iEnableWatch=0;
// m_iThinkTime=29;
m_iPlayCardCount=0;
m_iBaseOutCount=0;

m_iFirstOutPeople=-1;
m_iOutCardPeople=-1;
m_iNtPeopole=-1;
m_iBeenPlayGame=0;
m_bGameStation=GS_WAIT_NEXT;
::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));

//m_bGameStation=GS_WAIT_SETGAME;
// m_CardCount=PLAY_TWO_CARD;
// ::memset(&m_PunishPoint,0,sizeof(m_PunishPoint));
// ::memset(m_iPlayNTNum,0,sizeof(m_iPlayNTNum));

}

//析构函数
CServerGameDesk::~CServerGameDesk(void)
{
}



//获取游戏状态信息 旁观或断线重进者使用
bool CServerGameDesk::OnGetGameStation(BYTE bDeskStation, UINT uSocketID, bool bWatchUser)
{
try{

switch (m_bGameStation)
{
//case GS_WAIT_SETGAME: //游戏没有开始状态
// {
// GameStation_1 GameStation;
// ::memset(&GameStation,0,sizeof(GameStation));
// //GameStation.iCardCount=m_CardCount;
// GameStation.iCardCount=1;
//

// //发送数据
// SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,sizeof(GameStation));

// MessageStruct Mess;
// ZeroMemory(Mess.Message,200);
// strcpy(Mess.Message,"欢迎你参加斗地主游戏,祝你玩得开心!");
// SendGameData(bDeskStation,&Mess,sizeof(Mess),MDM_GM_GAME_NOTIFY,ASS_MESSAGE,0);

// return TRUE;
// }
case GS_WAIT_ARGEE: //等待玩家开始状态
{
GameStation_2 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
// GameStation.iThinkTime=m_iThinkTime;//思考时间
GameStation.iBeenPlayGame=m_iBeenPlayGame;//已经游戏的局数
//发送数据
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,sizeof(GameStation));
return TRUE;
}
case GS_SEND_CARD: //发牌状态
case GS_WAIT_BACK: //等待埋底牌状态
{
GameStation_3 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
// GameStation.iThinkTime=m_iThinkTime;//思考时间
GameStation.iBeenPlayGame=m_iBeenPlayGame; //已经游戏的局数
GameStation.iNtPeople=m_iNtPeopole;
GameStation.iBaseBei=m_pDataManage->m_InitData.uBasePoint;//倍数i;// 基本倍数
GameStation.iUserCardCount=m_iUserCardCount[bDeskStation];
::CopyMemory(GameStation.iUserCard,m_iUserCard[bDeskStation],sizeof(BYTE)*m_iUserCardCount[bDeskStation]);

//发送数据
SendG

ameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,sizeof(GameStation));
return TRUE;
}
case GS_PLAY_GAME: //游戏中状态
{
GameStation_4 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
// GameStation.iThinkTime=m_iThinkTime;//思考时间
GameStation.iBeenPlayGame=m_iBeenPlayGame; //已经游戏的局数


GameStation.iNtPeopole=m_iNtPeopole;//地主位置
::CopyMemory(GameStation.iBackCard,m_iBackCard,sizeof(BYTE)*3);

GameStation.iBeiShu=QianDZBei*RockBei*BombBei;//翻%d倍
GameStation.iDiFeng=m_iUserJiaoFen[m_iNtPeopole]/(GameStation.iBeiShu*MingPaiBei);//基本分=地主叫分 //底分
GameStation.iBaseBei=m_pDataManage->m_InitData.uBasePoint;//倍数i;// 基本倍数
GameStation.iTuoGuanCount=m_iTuoGuanCount[bDeskStation];//当前用户托管次数


GameStation.iOutCardPeople=m_iOutCardPeople;
GameStation.iFirstOutPeople=m_iFirstOutPeople;
GameStation.iBaseOutCount=m_iBaseOutCount;
GameStation.iUserCardCount=m_iUserCardCount[bDeskStation];
::CopyMemory(GameStation.iUserCardList,m_iUserCard[bDeskStation],sizeof(BYTE)*m_iUserCardCount[bDeskStation]);
int iPos=GameStation.iUserCardCount;
for (int i=0;i{
GameStation.iDeskCardCount[i]=m_iDeskCardCount[i];
::CopyMemory(&GameStation.iUserCardList[iPos],m_iDeskCard[i],sizeof(BYTE)*m_iDeskCardCount[i]);
iPos+=m_iDeskCardCount[i];
}

///::CopyMemory(&GameStation.iUserCardList[iPos],m_iBackCard,sizeof(BYTE)*3);
//CString s;
//for (int i=0;i<10;i++)
// s.AppendFormat("%d |",m_Logic.GetCardNum(m_iUserCard[bDeskStation][i]));
//AfxMessageBox(s);

//发送数据
// int iSendSize=sizeof(GameStation)-sizeof(GameStation.iUserCardList)+sizeof(BYTE)*iPos;
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,sizeof(GameStation));


// if ((MingPaiBei==3)/*明牌倍数*/&&(!bWatchUser))//如果地主明牌,发送明牌数据
// {
// int iCardCount=m_iUserCardCount[m_iNtPeopole];
//OutCardStruct NtCard;
//NtCard.iCardCount=iCardCount;
//::CopyMemory(NtCard.iCardList,m_iUserCard[m_iNtPeopole],sizeof(BYTE)*iCardCount);

//for (int i=0;i//SendWatchData(m_bMaxPeople,&NtCard,sizeof(NtCard)-sizeof(NtCard.iCardList)+sizeof(BYTE)*NtCard.iCardCount,MDM_GM_GAME_NOTIFY,ASS_LIANGPAIDA,0);

// }


return TRUE;
}
case GS_WAIT_NEXT: //等待下一盘游戏开始
{
GameStation_5 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
// GameStation.iThinkTime=m_iThinkTime;//思考时间
GameStation.iBeenPlayGame=m_iBeenPlayGame; //已经游戏的局数
GameStation.iNtPeopole=m_iNtPeopole;

//发送数据
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,siz

eof(GameStation));
return TRUE;
}
}

}catch(...)
{AfxMessageBox("OnGetGameStation异常!!!");
}

return false;
}

//重置游戏状态
bool CServerGameDesk::ReSetGameState(BYTE bLastStation)
{
try{
if (bLastStation!=GF_NORMAL)//请空数据
{
m_iPlayCardCount=0;

m_iBeenPlayGame=0;//清空局
::memset(m_AllTurePoint,0,sizeof(m_AllTurePoint)); //清空记分
m_iNtPeopole=-1;
::memset(m_iUserJiaoFen,0,sizeof(m_iUserJiaoFen));
::memset(m_bUserJiaoFenState,0,sizeof(m_bUserJiaoFenState));
}

m_iBaseOutCount=0;
m_iFirstOutPeople=-1;
m_iOutCardPeople=-1;
memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
memset(m_iUserCardCount,0,sizeof(m_iUserCardCount));
m_Logic.m_bLaiZiPaiDian=-1;
return true;
}catch(...)
{AfxMessageBox("ReSetGameState异常!!!");
}

}

//游戏开始
bool CServerGameDesk::GameBegin(BYTE bBeginFlag)//点开始
{
try{
if (__super::GameBegin(bBeginFlag)==false)
return false;

//设置状态
m_TuoGuanState=TG_AGREE;
TML_nm_OutCount=0;
TML_dz_OutCount=0;

QianDZBei=1;//抢地主翻倍
MingPaiBei=1;/*明牌倍数*/
RockBei=1;/*火箭倍数*/
BombBei=1;/*炸弹倍数*/

m_iBeenPlayGame++;
m_bGameStation=GS_SEND_CARD;
::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
::memset(m_iUserCardCount,0,sizeof(m_iUserCardCount));

::memset(m_iUserJiaoFen,0,sizeof(m_iUserJiaoFen));
::memset(m_bUserJiaoFenState,0,sizeof(m_bUserJiaoFenState));
::memset(m_bTuoGuan,0,sizeof(m_bTuoGuan));//用户是否托管
::memset(m_iTuoGuanCount,0,sizeof(m_iTuoGuanCount));//用户托管次数



//发送开始消息
BeginUpgradeStruct BeginMessage;
BeginMessage.iBeenPlayGame=m_iBeenPlayGame;//已经游戏的局数
BeginMessage.iBaseBei=m_pDataManage->m_InitData.uBasePoint;////游戏基本倍数
BeginMessage.iNtPeopole=m_iNtPeopole;//庄家位置
for (int i=0;iSendWatchData(m_bMaxPeople,&BeginMessage,sizeof(BeginMessage),MDM_GM_GAME_NOTIFY,ASS_BEGIN_UPGRADE,0);

RndSendCard();//洗牌分发

}catch(...)
{AfxMessageBox("GameBegin异常!!!");
}

return true;
}

//洗牌分发函数
void CServerGameDesk::RndSendCard()
{
try{
//分发扑克
BYTE iCardArray[54]; //BYTE iCardArray[162];
m_Logic.RandCard(iCardArray,54,m_BombCount); //m_Logic.RandCard(iCardArray,(m_iPlayCardCount==2)?108:162);

for (int i=0;i
::CopyMemory(m_iUserCard[i],&iCardArray[17*i],sizeof(BYTE)*17); //::CopyMemory(m_iUserCard[i],&iCardArray[((m_iPlayCardCount==2)?25:39)*i],sizeof(BYTE)*((m_iPlayCardCount==2)?25:39));
m_Logic.SortCard (m_iUserCard[i],false,17);
::CopyMemory(m_iUserCardBake[i],&m_iUserCard[i],sizeof(BYTE)*17);//::CopyMemory(m_iUserCard[i],&iCardArray[((m_iPlayCardCount==2)?25:39)*i],sizeof(BYTE)*((m_iPlayCardCount==2)?25:39));

}
::CopyMemory(m_iBackCard,&iCardArray[51],

sizeof(BYTE)*3);//::CopyMemory(m_iBackCard,&iCardArray[(m_iPlayCardCount==2)?100:156],sizeof(BYTE)*((m_iPlayCardCount==2)?8:6));


//CString SSS;
//for (int i=0;i<20;i++){
// SSS.AppendFormat("%0X-",m_iUserCard[0][i]);
//
//}
//SSS+="\n\n";
//for (int i=0;i<20;i++){
// SSS.AppendFormat("%0x-",m_iUserCard[1][i]);
//
//}
//SSS+="\n\n";
//
//AfxMessageBox(SSS);

if ((NYS_DeskStation>=0)&&(NYS_DeskStation<3))//存在超人
{
BYTE ChangeCard;
//换最大的给NYS
for (int i=0;i{
ChangeCard=m_iUserCard[NYS_DeskStation][16-i];
m_iUserCard[NYS_DeskStation][16-i]=m_iUserCard[(NYS_DeskStation+1)%PLAY_COUNT][i];
m_iUserCard[(NYS_DeskStation+1)%PLAY_COUNT][i]=ChangeCard;
if(i>0)continue;
//光换一家牌吧,两家太黑了点
ChangeCard=m_iUserCard[NYS_DeskStation][14-i];
m_iUserCard[NYS_DeskStation][14-i]=m_iUserCard[(NYS_DeskStation+2)%PLAY_COUNT][i];
m_iUserCard[(NYS_DeskStation+2)%PLAY_COUNT][i]=ChangeCard;

}
//重新排顺序
for (int i=0;im_Logic.SortCard (m_iUserCard[i],false,17);
::CopyMemory(m_iUserCardBake[i],&m_iUserCard[i],sizeof(BYTE)*17);//::CopyMemory(m_iUserCard[i],&iCardArray[((m_iPlayCardCount==2)?25:39)*i],sizeof(BYTE)*((m_iPlayCardCount==2)?25:39));
}
NYS_DeskStation=4;
}


//发牌
if (m_iBeenPlayGame == 1) //已经游戏的局数
{
srand((unsigned)time(NULL));
m_iFirstJuJiaoFen = rand() % PLAY_COUNT; //轮流叫分标志,记录上局第一个叫分者
}
else
{
//m_iFirstJuJiaoFen = (m_iFirstJuJiaoFen+1) % 3;//轮流叫分
m_iFirstJuJiaoFen =m_iWinStation;//上轮赢的叫分 //轮流叫分标志,记录上局第一个叫分者
}


////////检查托管
if(m_bTuoGuan[m_iFirstJuJiaoFen])
{
m_iWinStation = (m_iFirstJuJiaoFen+1)%PLAY_COUNT;//下一个没托管用户
if(m_bTuoGuan[m_iFirstJuJiaoFen])GameFinish(m_iFirstJuJiaoFen,GF_SALE);//三人托管就退出

}



m_TuoGuanState=TG_JIAOFEN;
m_iOutCardPeople=m_iFirstJuJiaoFen;


for(int i=0;i
SendCardStruct SendCard;
::memset(&SendCard,0,sizeof(SendCard));
m_iUserCardCount[i]=17;

::CopyMemory(SendCard.iCard,m_iUserCard[i],sizeof(BYTE)*17);

SendGameData(i,&SendCard,sizeof(SendCard),MDM_GM_GAME_NOTIFY,ASS_SEND_CARD,m_iFirstJuJiaoFen);
::memset(&SendCard,0,sizeof(SendCard));
SendWatchData(i,&SendCard,sizeof(SendCard),MDM_GM_GAME_NOTIFY,ASS_SEND_CARD,m_iFirstJuJiaoFen);
}



////继续发送扑克(1次发两张)
//for(int i=0;i<17;i++)
//{
// SendCardStruct SendCard;
// SendCard.iCard[i]=m_iUserCard[m_iSendCardPos%PLAY_COUNT][m_iSendCardPos/m_bMaxPeople];
// SendGameData(m_iSendCardPos%PLAY_COUNT,&SendCard,sizeof(SendCard),MDM_GM_GAME_NOTIFY,ASS_SEND_CARD,0);
// SendWatchData(m_iSendCardPos%PLAY_COUNT,&SendCard,sizeof(SendCard),MDM_GM_GAME_NOTIFY,ASS_SEND_CARD,0);
// m_iUserCardCount[m_iSendCardPos%PLAY_COUNT]++;
// m_iSendCardPos++;
//}

//继续发送扑克(1次发两张)


}catch(...)
{AfxMessageBox("

RndSendCard异常!!!");//try{
}
}


// 计算得分
void CServerGameDesk::CountFen()
{try{
if(m_iNtPeopole < 0 || m_iNtPeopole > 1)return;

UINT iBasePoint=m_pDataManage->m_InitData.uBasePoint;//倍数

if(TML_nm_OutCount==0||TML_dz_OutCount==1)iBasePoint*=2;//如果农民出牌0次或者地主出牌1次,就结束,那么翻倍


BYTE nm=(m_iNtPeopole+1)%PLAY_COUNT;//农民桌号


if (m_iWinStation==m_iNtPeopole)//地主胜m_iWinStation;//赢家
{
m_iTurePoint[nm]=m_iUserJiaoFen[m_iNtPeopole]*iBasePoint;//农民输的数量

if ((m_iTurePoint[nm]>m_pUserInfo[nm]->m_UserData.dwPoint)&&(m_pUserInfo[nm]->m_UserData.dwPoint>0))//农民输的钱大于自己的余额
m_iTurePoint[nm]=(int)m_pUserInfo[nm]->m_UserData.dwPoint; //农民输光现在的钱


m_iTurePoint[m_iNtPeopole]=m_iTurePoint[nm];//抽水

if (m_pDataManage->m_InitData.uComType!=TY_NORMAL_GAME)
m_iTurePoint[m_iNtPeopole]=m_iTurePoint[m_iNtPeopole]*19L/20L;//抽水//非普通房间/抽水
m_iTurePoint[nm]=-m_iTurePoint[nm];

}
else{//地主输
m_iTurePoint[m_iNtPeopole]=m_iUserJiaoFen[m_iNtPeopole]*iBasePoint*2;//地主输的数量


if ((m_iTurePoint[m_iNtPeopole]>m_pUserInfo[m_iNtPeopole]->m_UserData.dwPoint)&&(m_pUserInfo[m_iNtPeopole]->m_UserData.dwPoint>0))//地主输的钱大于自己的余额
m_iTurePoint[m_iNtPeopole]=(int)m_pUserInfo[m_iNtPeopole]->m_UserData.dwPoint; //地主输光现在的钱

m_iTurePoint[nm]=m_iTurePoint[m_iNtPeopole];//抽水

if (m_pDataManage->m_InitData.uComType!=TY_NORMAL_GAME)
m_iTurePoint[nm]=m_iTurePoint[nm]*19L/20L;//抽水//非普通房间/抽水


m_iTurePoint[m_iNtPeopole]=-m_iTurePoint[m_iNtPeopole];
}
//if (m_pDataManage->m_InitData.uComType!=TY_NORMAL_GAME)//免费房间不抽水
// if (m_iTurePoint[i]>0) m_iTurePoint[i]=m_iTurePoint[i]*19L/20L;
// int basefen=m_iUserJiaoFen[m_iNtPeopole];//基本分=地主叫分
// if (m_iWinStation==m_iNtPeopole)//地主胜m_iWinStation;//赢家
// {
// m_iTurePoint[m_iNtPeopole]=2*basefen;
// m_iTurePoint[(m_iNtPeopole+1)%PLAY_COUNT]=-basefen;
// m_iTurePoint[(m_iNtPeopole+2)%PLAY_COUNT]=-basefen;
// }
// else//地主败
// {
// m_iTurePoint[m_iNtPeopole]=-2*basefen;
// m_iTurePoint[(m_iNtPeopole+1)%PLAY_COUNT]=basefen;
// m_iTurePoint[(m_iNtPeopole+2)%PLAY_COUNT]=basefen;
// }

}catch(...)
{AfxMessageBox("CountFen异常!!!");//try{
}

}


//游戏结束
bool CServerGameDesk::GameFinish(BYTE bDeskStation, BYTE bCloseFlag)
{
//请除底牌
::memset(m_iBackCard,0,sizeof(m_iBackCard));
m_TuoGuanState=TG_AGREE;
//<
if( m_bGameStation==GS_WAIT_NEXT)bCloseFlag=GF_SALE;//等待下一盘开始 那么安全退出
//设置数据
m_bGameStation=GS_WAIT_NEXT;
//>
//编写代码
switch (bCloseFlag)
{
case GF_NORMAL: //游戏正常结束
{
//计算得分
CountFen();//m_iGamePoint,m_iPlayCardCount
//游戏结束
GameEndStruct Game

End;
::memset(&GameEnd,0,sizeof(GameEnd));
GameEnd.iWinStation=m_iWinStation;//发送赢家位置
GameEnd.QianDZBei=QianDZBei;//抢地主翻倍
GameEnd.MingPaiBei=MingPaiBei;/*明牌倍数*/
GameEnd.RockBei=RockBei;/*火箭倍数*/
GameEnd.BombBei=BombBei;/*炸弹倍数*/


GameEnd.iUserCardCount[0]=m_iUserCardCount[0];
GameEnd.iUserCardCount[1]=m_iUserCardCount[1];
if (m_iWinStation == m_iNtPeopole)//地主胜m_iWinStation;//赢家
GameEnd.iUserCardCount[m_iWinStation]=20;
else GameEnd.iUserCardCount[m_iWinStation]=17;

::CopyMemory(m_iUserCard[m_iWinStation],m_iUserCardBake[m_iWinStation],sizeof(BYTE)*GameEnd.iUserCardCount[m_iWinStation]);//还原赢家的初始扑克
::CopyMemory(GameEnd.iUserCard,m_iUserCard,sizeof(m_iUserCard)); //发送三家剩余牌内容



for (int i=0;i{
GameEnd.iTurePoint[i]=m_iTurePoint[i];
m_AllTurePoint[i]+=m_iTurePoint[i];
GameEnd.AllTurePoint[i]=m_AllTurePoint[i];

if (m_pUserInfo[i]!=NULL)
m_pUserInfo[i]->m_UserData.bUserState=USER_SITTING;
if ((m_bTuoGuan[i]))
m_pUserInfo[i]->m_UserData.bUserState=USER_LOOK_STATE;
}



//写入数据库
for (int i=0;iChangeUserPoint(m_pUserInfo[i],GameEnd.iTurePoint[i],GameEnd.iTurePoint[i]>0,GameEnd.iTurePoint[i]<0,GameEnd.iTurePoint[i]==0,false);

//发送数据
for (int i=0;iSendWatchData(m_bMaxPeople,&GameEnd,sizeof(GameEnd),MDM_GM_GAME_NOTIFY,ASS_CONTINUE_END,0);

if (m_pDataManage->m_InitData.uComType!=TY_NORMAL_GAME)//金币房间检查最小金币
for (int i=0;iif (m_pUserInfo[i]->m_UserData.dwPointm_InitData.uLessPoint)
{
GameFinish(i,GF_SALE);//有人小于最小金币 //发送结束信号
return true;
}

//有一个托管,游戏结束
for (int i=0;i{
if (m_bTuoGuan[i]){//结束游戏
GameFinish(bDeskStation,GF_SALE);//发送结束信号
break;

}

}
ReSetGameState(bCloseFlag);//清理数据
return __super::GameFinish(bDeskStation,bCloseFlag);//清理数据


} //游戏正常结束
case GF_SALE: //游戏安全结束
case GFF_FORCE_FINISH: //用户断线离开
{

for (int i=0;iSendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_SALE_END,bDeskStation);

ReSetGameState(GF_SALE);
return __super::GameFinish(bDeskStation,GF_SALE);

}
}

return __super::GameFinish(bDeskStation,bCloseFlag);//清理数据
}


//用户离开游戏桌
BYTE CServerGameDesk::UserLeftDesk(BYTE bDeskStation, CGameUserInfo * pUserInfo)
{try{
m_iBeenPlayGame=0;//

清空局
::memset(m_AllTurePoint,0,sizeof(m_AllTurePoint)); //清空记分


if ((m_pUserInfo[bDeskStation]!=NULL)&&(m_bGameStation==GS_WAIT_ARGEE)&&(bDeskStation==0))
{
//更改数据
//m_bGameStation=GS_WAIT_SETGAME;
m_bGameStation=GS_WAIT_NEXT;
for (int i=0;i{
if (m_pUserInfo[i]!=NULL) m_pUserInfo[i]->m_UserData.bUserState=USER_SITTING;

}
}
else if(m_bGameStation==GS_WAIT_SETGAME && (m_pUserInfo[bDeskStation]!=NULL) && m_iBeenPlayGame>0)
{
GameFinish(0,GF_SALE);
}


}catch(...)
{AfxMessageBox("UserLeftDesk异常!!!");//try{
}


return __super::UserLeftDesk(bDeskStation,pUserInfo);
}









//用户叫分处理
bool CServerGameDesk::UserJiaoFen(BYTE bDeskStation, int iJiaoFen)
{try{
///if (m_bUserJiaoFenState[bDeskStation]) return false;
//发送叫分动作,同步各客户端
UserJiaoFenStruct jiaoFenInfo;
//清空结构
::memset(&jiaoFenInfo,0,sizeof(jiaoFenInfo));
jiaoFenInfo.iFen = iJiaoFen+100;//叫分
jiaoFenInfo.iNextDeskStation =bDeskStation;
for (int i = 0;i SendGameData(i,&jiaoFenInfo,sizeof(jiaoFenInfo),MDM_GM_GAME_NOTIFY,ASS_JIAO_FEN,0);
SendWatchData(m_bMaxPeople,&jiaoFenInfo,sizeof(jiaoFenInfo),MDM_GM_GAME_NOTIFY,ASS_JIAO_FEN,0);
//结束发送叫分,同步各客户端


m_iUserJiaoFen[bDeskStation]=iJiaoFen;
m_bUserJiaoFenState[bDeskStation]=true;//此人叫过分了



//是否有玩家叫3分.直接开始抢
if (iJiaoFen == 3)
{
m_iNtPeopole = bDeskStation;//庄家位置=现在位置
QianDZcount=0;//抢地主次数
SendQiangDZ(bDeskStation,false);//发送抢地主标志
return true;
}


int iNextJiaoFenStation = (int)(bDeskStation+1)%PLAY_COUNT;//下一个叫分用户


if(m_bTuoGuan[iNextJiaoFenStation])
{ m_iUserJiaoFen[iNextJiaoFenStation]=0;
m_bUserJiaoFenState[iNextJiaoFenStation]=true;
iNextJiaoFenStation = (int)(iNextJiaoFenStation+1)%PLAY_COUNT;//下一个叫分用户

if(m_bTuoGuan[iNextJiaoFenStation])GameFinish(iNextJiaoFenStation,GF_SALE);//三人托管就退出

}



bool bAllJiao = true;
for (int i = 0;i < PLAY_COUNT;i++)
{
if (!m_bUserJiaoFenState[i])//有一个不叫的
{
bAllJiao = false;//有不叫的
break;
}
}

//每人均叫过一次
if (bAllJiao)
{ int iMaxFen = -1;
int iMaxFenStation = 0;
for (int i=0;i{
if (m_iUserJiaoFen[i] > iMaxFen)
{
iMaxFen=m_iUserJiaoFen[i];
iMaxFenStation=i;
continue;
}
}

if (iMaxFen==0)//都没叫重新发牌
{



::memset(m_iUserJiaoFen,0,sizeof(m_iUserJiaoFen));
::memset(m_bUserJiaoFenState,0,sizeof(m_bUserJiaoFenState));
for (int i = 0;i < 3;i++) SendGameData(i,MDM_GM_GAME_NOTIFY,ASS_RESEND_CARD,0);//重新发牌
SendWatchData(m_bMaxPeople,MDM_GM_GAME_NOTIFY,ASS_RESEND_CARD,0);//重新发牌


m_bGameStation=GS_SEND_CARD;
::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));

::memset(m_iUserCardCount,0,sizeof(m_iUserCardCount));


srand((unsigned)time(NULL));
m_iWinStation=rand() % PLAY_COUNT;//随机开始
//检查托管人数



if(m_bTuoGuan[m_iWinStation])
{
m_iWinStation = (m_iWinStation+1)%PLAY_COUNT;//下一个没托管用户
if(m_bTuoGuan[m_iWinStation])GameFinish(m_iWinStation,GF_SALE);//三人托管就退出

}



RndSendCard();//三个人都不叫,那么洗牌分发
return true;
}
else
{
m_iNtPeopole = iMaxFenStation;//最大分的位置
QianDZcount=0;//抢地主次数
SendQiangDZ(bDeskStation,false);//发送抢地主标志,0是抢次数
}
return true;
}




//通知下一个叫分者
jiaoFenInfo.iFen = iJiaoFen;
jiaoFenInfo.iNextDeskStation = iNextJiaoFenStation;
m_iOutCardPeople=iNextJiaoFenStation;

for (int i = 0;i SendGameData(i,&jiaoFenInfo,sizeof(jiaoFenInfo),MDM_GM_GAME_NOTIFY,ASS_JIAO_FEN,0);
SendWatchData(m_bMaxPeople,&jiaoFenInfo,sizeof(jiaoFenInfo),MDM_GM_GAME_NOTIFY,ASS_JIAO_FEN,0);




}catch(...)
{AfxMessageBox("UserJiaoFen异常!!!");//try{
}

return true;
}


#pragma once

#include "StdAfx.h"
#include "UpGradeLogic.h"


//游戏结束标志定义
#define GF_NORMAL 10 //游戏正常结束
#define GF_SALE 11 //游戏安全结束


//托管状态定义 TG_STATE
#define TG_AGREE 1//同意开始到发牌前断线
#define TG_JIAOFEN 2//叫分期间断线
#define TG_QIANGDZ 3//抢地主期间断线
#define TG_PLAY 4//打牌期间断线(明牌期间断线)



//游戏桌类
class CServerGameDesk : public CGameDesk
{
protected:
//游戏基础数据
BYTE m_BombCount; //炸弹数目

//玩家设置数据
//BYTE m_iThinkTime; //思考时间
BYTE m_iPlayCardCount; //游戏扑克数目
BYTE m_iEnableWatch; //是否允许旁观
BYTE NYS_DeskStation;//超人所在桌子

//运行状态变量
BYTE QianDZcount; //抢地主次数

BYTE m_iBeenPlayGame; //已经游戏的局数


//状态信息
BYTE m_iUserCardCount[PLAY_COUNT]; //用户手上扑克数目
BYTE m_iUserCard[PLAY_COUNT][23]; //用户手上的扑克
BYTE m_iUserCardBake[PLAY_COUNT][23]; //备份用户手上的扑克
BYTE m_iBackCard[3]; //底牌列表

//运行信息
BYTE m_iOutCardPeople; //现在出牌用户
BYTE m_iFirstOutPeople; //先出牌的用户
BYTE m_iLastOutPeople; //最后出牌用户
BYTE m_iNtPeopole; //地主位置
BYTE m_iBaseOutCount; //出牌的数目
BYTE m_iDeskCardCount[PLAY_COUNT]; //桌面扑克的数目
BYTE m_iDeskCard[PLAY_COUNT][23]; //桌面的扑克

BYTE TML_nm_OutCount;//农民出牌次数
BYTE TML_dz_OutCount;//地主出牌次数


//翻倍信息
BYTE QianDZBei;//抢地主翻倍
BYTE Ming

PaiBei;/*明牌倍数*/
BYTE RockBei;/*火箭倍数*/
UINT BombBei;/*炸弹倍数*/

CUpGradeGameLogic m_Logic; //游戏逻辑
bool m_bUserJiaoFenState[PLAY_COUNT]; //用户叫分状态
int m_iUserJiaoFen[PLAY_COUNT]; //用户叫分
int m_iFirstJuJiaoFen;//第一局叫分的

bool IsNewTurn; //是否是新轮


BYTE m_iWinStation;//赢家
int m_iTurePoint[PLAY_COUNT];//游戏得分
int m_AllTurePoint[PLAY_COUNT];//游戏累计得分

/**处理断线托管***************************************************************/
BYTE m_TuoGuanState;//游戏托管状态
bool m_bTuoGuan[PLAY_COUNT];//用户是否托管
BYTE m_iTuoGuanCount[PLAY_COUNT];//用户托管次数
/**处理断线托管***************************************************************/



//函数定义
public:
//构造函数
CServerGameDesk();
//析构函数
virtual ~CServerGameDesk();


//必须重载的4个基本函数
virtual bool GameBegin(BYTE bBeginFlag);
//游戏结束
virtual bool GameFinish(BYTE bDeskStation, BYTE bCloseFlag);
//游戏数据包处理函数
virtual bool HandleNotifyMessage(BYTE bDeskStation, NetMessageHead * pNetHead, void * pData, UINT uSize, UINT uSocketID, bool bWatchUser);


//重载纯虚功能函数,可要可不要
//初始化函数,服务器加载DLL时候,按数据库中的桌子数量创建线程,执行完构造函数就执行这个
//为在能在初试化实现设置游戏规则,变为虚函数,由子类,各游戏分别设置
virtual void Init(BYTE bDeskIndex, BYTE bMaxPeople, CGameMainManage * pDataManage);
//重载托管函数 ,如果不重载,那么大厅按强退处理.本函数完全由父类调用
virtual void TuoGuanNowUser(BYTE bDeskStation,bool isTuoGuan);
//用户离开游戏桌
virtual BYTE UserLeftDesk(BYTE bDeskStation, CGameUserInfo * pUserInfo);
//获取游戏状态信息
virtual bool OnGetGameStation(BYTE bDeskStation, UINT uSocketID, bool bWatchUser);
//重置游戏状态
virtual bool ReSetGameState(BYTE bLastStation);


//处理函数
public:
//用户设置游戏
//BOOL UserSetGame(UserArgeeGame * pGameSet);
//洗牌函数
void RndSendCard();
//游戏开始
void BeginOutCard();
//发送底牌
void SendBackCard();
//发送抢地主信息
void SendQiangDZ(BYTE bDeskStation,bool bQiang);
//用户出牌
bool UserOutCard(BYTE bDeskStation, BYTE iOutCard[], int iCardCount);
//新一轮开始
//BOOL NewPlayTurn(BYTE bDeskStation);

//计算得分
void CountFen();
//用户叫分处理
bool UserJiaoFen(BYTE bDeskStation, int iJiaoFen);
//用户抢地主处理
bool UserQianDZ(BYTE bDeskStation,bool isQiang);
};

/******************************************************************************************************/
#include "StdAfx.h"
#include "ServerManage.h"


//构造函数
CServerGameDesk::CServerGameDesk(void):CG

ameDesk(FULL_BEGIN)
{
m_iEnableWatch=0;
m_iLeaveArgee=0;
m_iNtCardCount=0;
m_iLessCount=0;
m_iPlayCardCount=0;
m_iBeginStation=0;
m_iEndStation=0;
m_iBaseOutCount=0;
m_iNtPeople=-1;
m_iFirstOutPeople=-1;
m_iOutCardPeople=-1;
m_iUpGradePeople=-1;
m_iBeenPlayGame=0;
m_iGamePoint=0;
m_bGameStation=GS_WAIT_SETGAME;
m_CardCount=PLAY_TWO_CARD;
::memset(&m_PunishPoint,0,sizeof(m_PunishPoint));
::memset(m_iPlayNTNum,0,sizeof(m_iPlayNTNum));
::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
}

//析构函数
CServerGameDesk::~CServerGameDesk(void)
{
}

//定时器消息
bool CServerGameDesk::OnTimer(UINT uTimerID)
{
if (uTimerID==TIME_SEND_CARD) //发牌定时器
{
if (m_bGameStation==GS_SEND_CARD) SendCard();
else KillTimer(TIME_SEND_CARD);
return TRUE;
}
if (uTimerID==TIME_WAIT_NT) //反牌定时器
{
if (m_bGameStation==GS_SEND_CARD) SendBackCard();
KillTimer(TIME_WAIT_NT);
return TRUE;
}
if (uTimerID==TIME_GAME_FINISH) //结束定时器
{
KillTimer(TIME_GAME_FINISH);
if (m_bGameStation==GS_PLAY_GAME) GameFinish(0,GF_NORMAL);
}
return __super::OnTimer(uTimerID);
}

//获取游戏状态信息
bool CServerGameDesk::OnGetGameStation(BYTE bDeskStation, UINT uSocketID, bool bWatchUser)
{
switch (m_bGameStation)
{
case GS_WAIT_SETGAME: //游戏没有开始状态
{
GameStation_1 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
GameStation.iCardCount=m_CardCount;

//发送数据
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,sizeof(GameStation));

return TRUE;
}
case GS_WAIT_ARGEE: //等待玩家开始状态
{
GameStation_2 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
GameStation.iPlayCount=m_iLessCount;
GameStation.iCardCount=m_iPlayCardCount;
GameStation.iBeginStation=m_iBeginStation;
GameStation.iEndStation=m_iEndStation;

//发送数据
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,sizeof(GameStation));
return TRUE;
}
case GS_SEND_CARD: //发牌状态
case GS_WAIT_BACK: //等待埋底牌状态
{
GameStation_3 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
GameStation.iPlayCount=m_iLessCount;
GameStation.iCardCount=m_iPlayCardCount;
GameStation.iBeginStation=m_iBeginStation;
GameStation.iEndStation=m_iEndStation;
GameStation.iWinPoint=m_iPlayNTNum[bDeskStation%2]-m_iBeginStation;
GameStation.iPunishPoint=m_PunishPoint[bDeskStation];
GameStation.iUpGradePeople=m_iUpGradePeople;
GameStation.iPlayNTNum[0]=m_iPlayNTNum[0];
GameStation.iPlayNTNum[1]=m_iPlayNTNum[1];
GameStation.iBeenPlayGame=m_iBeenPlayGame;
GameStation.iNtPeople=m_iNtPeople;
GameStation.iNtCardCount=m_iNtCardCount;
GameStation.iNtHua=m_Logic.GetNTHuaKind();
GameStation.iUserCardCount=m_iUserCardCount[bDeskStation];
::CopyMemory(GameStation.iUs

erCard,m_iUserCard[bDeskStation],sizeof(BYTE)*m_iUserCardCount[bDeskStation]);

//发送数据
int iSendSize=sizeof(GameStation)-sizeof(GameStation.iUserCard)+sizeof(BYTE)*m_iUserCardCount[bDeskStation];
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,iSendSize);
return TRUE;
}
case GS_PLAY_GAME: //游戏中状态
{
GameStation_4 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
GameStation.iPlayCount=m_iLessCount;
GameStation.iCardCount=m_iPlayCardCount;
GameStation.iBeginStation=m_iBeginStation;
GameStation.iEndStation=m_iEndStation;
GameStation.iWinPoint=m_iPlayNTNum[bDeskStation%2]-m_iBeginStation;
GameStation.iPunishPoint=m_PunishPoint[bDeskStation];
GameStation.iUpGradePeople=m_iUpGradePeople;
GameStation.iPlayNTNum[0]=m_iPlayNTNum[0];
GameStation.iPlayNTNum[1]=m_iPlayNTNum[1];
GameStation.iBeenPlayGame=m_iBeenPlayGame;
GameStation.iNtPeople=m_iNtPeople;
GameStation.iNtCardCount=m_iNtCardCount;
GameStation.iNtHua=m_Logic.GetNTHuaKind();
GameStation.iGamePoint=m_iGamePoint;
GameStation.iOutCardPeople=m_iOutCardPeople;
GameStation.iFirstOutPeople=m_iFirstOutPeople;
GameStation.iBaseOutCount=m_iBaseOutCount;
GameStation.iUserCardCount=m_iUserCardCount[bDeskStation];
::CopyMemory(GameStation.iUserCardList,m_iUserCard[bDeskStation],sizeof(BYTE)*m_iUserCardCount[bDeskStation]);
int iPos=GameStation.iUserCardCount;
for (int i=0;i<4;i++)
{
GameStation.iDeskCardCount[i]=m_iDeskCardCount[i];
::CopyMemory(&GameStation.iUserCardList[iPos],m_iDeskCard[i],sizeof(BYTE)*m_iDeskCardCount[i]);
iPos+=m_iDeskCardCount[i];
}

//发送数据
int iSendSize=sizeof(GameStation)-sizeof(GameStation.iUserCardList)+sizeof(BYTE)+iPos;
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,iSendSize);
return TRUE;
}
case GS_WAIT_NEXT: //等待下一盘游戏开始
{
GameStation_5 GameStation;
::memset(&GameStation,0,sizeof(GameStation));
GameStation.iPlayCount=m_iLessCount;
GameStation.iCardCount=m_iPlayCardCount;
GameStation.iBeginStation=m_iBeginStation;
GameStation.iEndStation=m_iEndStation;
GameStation.iWinPoint=m_iPlayNTNum[bDeskStation%2]-m_iBeginStation;
GameStation.iPunishPoint=m_PunishPoint[bDeskStation];
GameStation.iUpGradePeople=m_iUpGradePeople;
GameStation.iPlayNTNum[0]=m_iPlayNTNum[0];
GameStation.iPlayNTNum[1]=m_iPlayNTNum[1];
GameStation.iBeenPlayGame=m_iBeenPlayGame;

//发送数据
SendGameStation(bDeskStation,uSocketID,bWatchUser,&GameStation,sizeof(GameStation));
return TRUE;
}
}
return false;
}

//重置游戏状态
bool CServerGameDesk::ReSetGameState(BYTE bLastStation)
{
KillTimer(TIME_SEND_CARD);
KillTimer(TIME_WAIT_NT);
KillTimer(TIME_GAME_FINISH);

if ((bLastStation==GFF_FORCE_FINISH)||(bLastStation==GF_SALE))
{
m_iLessCount=0;

m_iPlayCardCount=0;
m_iBeginStation=0;
m_iEndStation=0;
m_iBeenPlayGame=0;
m_iUpGradePeople=-1;
m_Logic.SetNTCardNum(0);
::memset(m_iPlayNTNum,0,sizeof(m_iPlayNTNum));
::memset(m_PunishPoint,0,sizeof(m_PunishPoint));
}

m_iLeaveArgee=0;
m_iGamePoint=0;
m_iBaseOutCount=0;
m_iFirstOutPeople=-1;
m_iOutCardPeople=-1;
m_iNtPeople=-1;
m_iNtCardCount=0;
m_iSendCardPos=0;
m_Logic.SetNTHuaKind(UG_ERROR_HUA);
memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
memset(m_iUserCardCount,0,sizeof(m_iUserCardCount));

return TRUE;
}

//游戏开始
bool CServerGameDesk::GameBegin(BYTE bBeginFlag)
{
if (__super::GameBegin(bBeginFlag)==false) return false;

//设置状态
m_iNtPeople=-1;
m_iNtCardCount=0;
m_iSendCardPos=0;
m_iBeenPlayGame++;
m_Logic.SetNTHuaKind(UG_ERROR_HUA);
m_bGameStation=GS_SEND_CARD;
::memset(m_iDeskCardCount,0,sizeof(m_iDeskCardCount));
::memset(m_iUserCardCount,0,sizeof(m_iUserCardCount));

//发送开始消息
BeginUpgradeStruct BeginMessage;
BeginMessage.iNtStation=m_Logic.GetNTCardNum();
BeginMessage.iStation[0]=m_iPlayNTNum[0];
BeginMessage.iStation[1]=m_iPlayNTNum[1];
BeginMessage.iPlayCount=m_iBeenPlayGame;
BeginMessage.iUpgradeStation=m_iUpGradePeople;
for (int i=0;i<4;i++) SendGameData(i,&BeginMessage,sizeof(BeginMessage),MDM_GM_GAME_NOTIFY,ASS_BEGIN_UPGRADE,0);
SendWatchData(m_bMaxPeople,&BeginMessage,sizeof(BeginMessage),MDM_GM_GAME_NOTIFY,ASS_BEGIN_UPGRADE,0);

//分发扑克
BYTE iCardArray[162];
m_Logic.RandCard(iCardArray,(m_iPlayCardCount==2)?108:162);
for (int i=0;i<4;i++)
::CopyMemory(m_iUserCard[i],&iCardArray[((m_iPlayCardCount==2)?25:39)*i],sizeof(BYTE)*((m_iPlayCardCount==2)?25:39));
::CopyMemory(m_iBackCard,&iCardArray[(m_iPlayCardCount==2)?100:156],sizeof(BYTE)*((m_iPlayCardCount==2)?8:6));

//发牌消息
SetTimer(TIME_SEND_CARD,200);

return TRUE;
}

//游戏结束
bool CServerGameDesk::GameFinish(BYTE bDeskStation, BYTE bCloseFlag)
{
//编写代码
switch (bCloseFlag)
{
case GF_NORMAL: //游戏正常结束
{
//计算得分
int iTurePoint=GetUpGrade(m_iGamePoint,m_iPlayCardCount);

//计算胜利
if (iTurePoint>0) m_iPlayNTNum[m_iUpGradePeople%2]+=iTurePoint;
else if (iTurePoint<=-1) m_iPlayNTNum[(m_iUpGradePeople+1)%2]+=(-iTurePoint-1);

//游戏结束
GameEndStruct GameEnd;
::memset(&GameEnd,0,sizeof(GameEnd));
GameEnd.iUpGradeStation=m_iUpGradePeople;
GameEnd.iGamePoint=m_iGamePoint;
::CopyMemory(GameEnd.iBackList,m_iBackCard,sizeof(m_iBackCard));

if ((m_iBeenPlayGame>=m_iLessCount)||(m_iPlayNTNum[0]>m_iEndStation)||(m_iPlayNTNum[1]>m_iEndStation))
{
//设置数据
bCloseFlag=GFF_FORCE_FINISH;
m_bGameStation=GS_WAIT_SETGAME;

//计算总得分
int iWinPoint[2];
iWinPoint[0]=(m_iPlayNTNum[0]-m_iBeginStation)+(m_iPlayNTNum[0]-m_iPlayNTNum[1])*2;
iWinPoint[1]=(m_iPlayNTNum[1]-m_iBeginStatio

n)+(m_iPlayNTNum[1]-m_iPlayNTNum[0])*2;

//写入数据库
for (int i=0;i<4;i++)
ChangeUserPoint(m_pUserInfo[i],iWinPoint[i%2],iWinPoint[i%2]>0,iWinPoint[i%2]<0,iWinPoint[i%2]==0,false);

//发送消息
for (int i=0;iSendWatchData(m_bMaxPeople,&GameEnd,sizeof(GameEnd),MDM_GM_GAME_NOTIFY,ASS_NO_CONTINUE_END,0);
}
else //继续下一盘
{
//设置数据
m_bGameStation=GS_WAIT_NEXT;
if (iTurePoint>0) m_iUpGradePeople=(m_iUpGradePeople+2)%4;
else m_iUpGradePeople=(m_iUpGradePeople+1)%4;
m_Logic.SetNTCardNum(m_iPlayNTNum[m_iUpGradePeople%2]);

//设置分数
GameEnd.iTurePoint[0]=GameEnd.iTurePoint[2]=(m_iPlayNTNum[m_iUpGradePeople%2]-m_iBeginStation)+(m_iPlayNTNum[m_iUpGradePeople%2]-m_iPlayNTNum[(m_iUpGradePeople+1)%2])*2;
GameEnd.iTurePoint[1]=GameEnd.iTurePoint[3]=(m_iPlayNTNum[(m_iUpGradePeople+1)%2]-m_iBeginStation)+(m_iPlayNTNum[(m_iUpGradePeople+1)%2]-m_iPlayNTNum[m_iUpGradePeople%2])*2;

//发送数据
for (int i=0;iSendWatchData(m_bMaxPeople,&GameEnd,sizeof(GameEnd),MDM_GM_GAME_NOTIFY,ASS_CONTINUE_END,0);
}

break;
}
case GF_SALE: //游戏安全结束
case GFF_FORCE_FINISH: //用户断线离开
{
//设置数据
m_bGameStation=GS_WAIT_SETGAME;

//计算总得分
int iWinPoint[2];
iWinPoint[0]=m_iPlayNTNum[0]*3-m_iBeginStation-m_iPlayNTNum[1]*2;
iWinPoint[1]=m_iPlayNTNum[1]*3-m_iBeginStation-m_iPlayNTNum[0]*2;

GameCutStruct CutEnd;
CutEnd.bDeskStation=bDeskStation;

//写入数据库
for (int i=0;i<4;i++)
ChangeUserPoint(m_pUserInfo[i],iWinPoint[i%2],iWinPoint[i%2]>0,iWinPoint[i%2]<0,iWinPoint[i%2]==0,true);

//发送信息
if (bCloseFlag==GF_SALE)
{
for (int i=0;iSendWatchData(m_bMaxPeople,&CutEnd,sizeof(CutEnd),MDM_GM_GAME_NOTIFY,ASS_SALE_END,0);
}
else
{
for (int i=0;iSendWatchData(m_bMaxPeople,&CutEnd,sizeof(CutEnd),MDM_GM_GAME_NOTIFY,ASS_CUT_END,0);
}
break;
}
}

//重置数据
ReSetGameState(bCloseFlag);
__super::GameFinish(bDeskStation,bCloseFlag);
return true;
}

//判断是否正在游戏
bool CServerGameDesk::IsPlayGame(BYTE bDeskStation)
{
return __super::IsPlayGame(bDeskStation);
}

//游戏数据包处理函数
bool CServerGameDesk::HandleNotifyMessage(BYTE bDeskStation, NetMessageHead * pNetHead, void * pData, UINT uSize, UINT uSocketID, bool bWatchUser)
{
switch (pNetHead->bAssistantID)
{
case ASS_GM_AGREE_GAME: //用户同意游戏
{
if (bWatchUser) return FALSE;
if ((bDes

相关主题
文本预览
相关文档 最新文档