代码改变世界

团队项目

2016-05-20 12:09  萝卜占坑一蹲一坑  阅读(14078)  评论(0编辑  收藏  举报

网络连连看

程序设计与编码

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

所属项目:        基于网络的连连看游戏             

文件类别:         程序设计与编码                  

编 写 者:         李玉纯,刘振华,张庭飞                        

小    组:          一个萝卜一个坑                   

 

 

 

目录

 

 

 

 

 

 

 

1.开发平台与工具

 

   1.1 Microsoft Visual C++ 6.0

 

   1.2 MFC

 

2.程序设计源码说明

 

   2.1 目录划分

 

   2.2 程序构架

 

3.程序设计

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1开发平台与工具

 

    1.1 Microsoft Visual C++ 6.0

 

 

 

Visual C++ 6.0,简称VC或者VC6.0,是微软推出的一款C++编译器,将高级语言翻译为机器语言(低级语言)的程序。Visual C++是一个功能强大的可视化软件开发工具。自1993Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。虽然微软公司推出了 Visual C++.NET(Visual C++7.0),但它的应用有很大的局限性,只适用于Windows 2000Windows XPWindows NT4.0。所以实际中,更多的是以Visual C++6.0为平台。

 

Visual C++6.0Microsoft开发, 它不仅是一个C++ 编译器,而且是一个基于Windows操作系统的可视化集成开发环境integrated development environmentIDE)。Visual C++6.0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导Class Wizard等开发工具。 这些组件通过一个名为Developer Studio的组件集成为和谐的开发环境。Microsoft的主力软件产品。Visual C++是一个功能强大的可视化软件开发工具。自1993Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。虽然微软公司推出了Visual C++.NET(Visual C++7.0),但它的应用的很大的局限性,只适用于Windows 2000,Windows XPWindows NT4.0。所以实际中,更多的是以Visual C++6.0为平台。

 

Visual C++6.0以拥有语法高亮,自动编译功能以及高级除错功能而著称。比如,它允许用户进行远程调试,单步执行等。还有允许用户在调试期间重新编译被修改的代码,而不必重新启动正在调试的程序。其编译及创建预编译头文件(stdafx.h)、最小重建功能及累加连结(link)著称。这些特征明显缩短程序编辑、编译及连结的时间花费,在大型软件计划上尤其显著。

 

 

 

    1.2 MFC

 

     

 

     MFCMFC是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数,VC++是微软公司开发的c/c++的集成开发环境

 

     从理论上来讲,MFC也不是专用于Visual C++Borland C++C++BuilderSymantec C++同样可以处理MFC。同时,用Visual C++编写代码也并不意味着一定要用MFC,只要愿意,用Visual C++来编写SDK程序,或者使用STLATL,一样没有限制。不过,Visual C++本来就是为MFC打造的,Visual C++中的许多特征和语言扩展也是为MFC而设计的,所以用Visual C++而不用MFC就等于抛弃了Visual C++中很大的一部分功能。但是,Visual C++也不等于MFC

 

 

 

 

 

2 程序设计源码说明

 

2.1 目录划分

 

         

 

Server 服务端项目主要代码

 

Client 客户端项目主要代码

 

LLK 连连看游戏项目代码

 

Basic 封装的基础类。如:完成端口类,打包用的输入输出流类,ADO数据库类,CMySocket类等。

 

Common 项目共用的类代码。如:用户类,用户管理类,桌子类,桌子管理类,游戏类等。

 

ServerBin 服务端可执行程序输出目录

 

ClientBin 客户端可执行程序输出目录,对战平台里游戏放在此目录下。

 

 

 

 

 

 

 

2.2 程序构架

 

 

 

1. 服务器端

 

网络层:

 

网络IO模型使用完成端口,具体实现是使用自行封装的CIOCP类,此类对完成端口的线程和对各种网络事件的处理进行了封装。

 

封包的封装使用CPacket对封包进行打包和解包。

 

数据层:

 

CAdoConnection类和CAdoRecordSet类对ADO的基本对象进行了封装,并由CDataLayer类来访问数据库。

 

业务逻辑层:

 

主要由三个管理类:CUserMan, CTableMan 和 CLLKGameMan。分别对用户、桌子和连连看游戏。

 

2. 客户端

 

网络层:

 

使用异步选择事件模型,Socket使用自己封装的CMySocket进行方便的异步绑定。

 

业务逻辑层:

 

使用CClientNetMan类对服务器发送来的信息进行统一处理,再通知界面显示。对桌子的管理采用由服务器发送桌子信息,客户端显示。

 

与游戏程序的通讯层:

 

自行封装了一个CWMLink类,使用WM_COPYDATA窗口消息实现进程间的通信,并使用派生的CClientWMLink类对游戏程序的通讯统一管理。

 

3. 游戏端

 

通讯层:

 

由CWMLink派生的CGameWMLink类与客户大厅程序通信及统一处理消息。

 

业务逻辑层:

 

由CLLK类进行连连看游戏算法的管理。使用CLLKGameMan来接收其它玩家信息

 

界面层:

 

对话框窗口,为了使界面不受Windows窗口的限制,全部使用自绘方式。封装了一个CVirtualButton类来显示所需要的按钮。

3.程序设计

3.1 Server:服务端项目主要代码

// CLLK.cpp: implementation of the CLLK class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "CLLK.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLK::CLLK()

{

m_nBoxXCount = BOX_X_COUNT;

m_nBoxYCount = BOX_Y_COUNT;

 

Init();

}

 

CLLK::~CLLK()

{

}

 

int CLLK::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(CLLK) + sizeof(int));

int dataSize = sizeof(CLLK);

cos << dataSize;

cos.Write((char *)this, dataSize);

cos.CopyTo(pData);

 

return cos.GetSize();

}

 

int CLLK::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

if (dataSize != sizeof(CLLK))

{

TRACE("C CLLK::UnPack dataSize[%d] != sizeof(CLLK)[%d]\n", dataSize, sizeof(CLLK));

}

cis.Read((char *)this, sizeof(CLLK));

return cis.GetSize();

}

 

void CLLK::Init()

{

// 初始数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

// 初始化选择

m_nSelBox = 0;

m_ptSelBox[0] = CPoint(0, 0);

m_ptSelBox[1] = CPoint(0, 0);

 

// 初始化连线

m_nLinkLine = 0;

ZeroMemory(m_ptLinkLine, sizeof(m_ptLinkLine));

 

// 初始化将要删除的

m_bHasWillBeNullBox = FALSE;

m_typeWillBeNullBox[0] = 0;

m_typeWillBeNullBox[1] = 0;

m_ptWillBeNullBox[0] = CPoint(-1, -1);

m_ptWillBeNullBox[1] = CPoint(-1, -1);

 

// 初始化连击数

m_nCurLianji = 0;

m_nMaxLianji = 0;

m_dwLastLianjiTime = 0;

 

m_nLeaveBoxCount = 0;

}

 

//////////////////////////////////////////////////////////////////////////

// //判断两坐标是否在同一线上 并且中间无阻碍

BOOL CLLK::IsPairInlineValid(CPoint pt1, CPoint pt2)

{

//同一点判断

if (pt1 == pt2)

{

return FALSE;

}

 

//同一行类型

typedef enum _INLINE_TYPE

{

IT_NULL = 0, //不同行

IT_X = 1, //X同行

IT_Y = 2 //Y同行

} INLINE_TYPE;

 

INLINE_TYPE it;

 

if (pt1.x == pt2.x)

{

it = IT_X;

//计算出两者之大小

int x = pt1.x;

int minY, maxY;

if (pt1.y > pt2.y)

{

minY = pt2.y;

maxY = pt1.y;

}

else

{

minY = pt1.y;

maxY = pt2.y;

}

//紧挨着

if (maxY - minY == 1)

{

return TRUE;

}

//其它情况

for (int i = minY + 1; i < maxY; i++)

{

if (m_nArrType[x][i] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else if (pt1.y == pt2.y)

{

it = IT_Y;

//计算出两者之大小

int y = pt1.y;

int minX, maxX;

if (pt1.x > pt2.x)

{

minX = pt2.x;

maxX = pt1.x;

}

else

{

minX = pt1.x;

maxX = pt2.x;

}

//紧挨着

if (maxX - minX == 1)

{

return TRUE;

}

//其它情况

for (int i = minX + 1; i < maxX; i++)

{

if (m_nArrType[i][y] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else

{

it = IT_NULL;

return FALSE;

}

return FALSE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 判断两点是否可消除 完成后集成在LLK类中

BOOL CLLK::IsPairCanLink(CPoint pt1,

 CPoint pt2,

 int *pnResultPtCount /*= NULL*/,

 CPoint *pPtResult /*= NULL*/)

{

// 结果保存

BOOL bRet = FALSE;

int count = 0;

CPoint point[4];

 

// 重复点情况

if (pt1 == pt2)

{

return FALSE;

}

 

// 图标是否相同

if (m_nArrType[pt1.x][pt1.y] != m_nArrType[pt2.x][pt2.y])

{

return FALSE;

}

 

// 判断流程

do

{

// 1.同一线情况

if (IsPairInlineValid(pt1, pt2))

{

count = 2;

point[0] = pt1;

point[1] = pt2;

bRet = TRUE;

break;

}

 

// 2.一拐点情况

{

CPoint t1, t2;

 

// 两点组成的矩形另外两个顶点

t1.x = pt1.x;

t1.y = pt2.y;

 

t2.x = pt2.x;

t2.y = pt1.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t1) &&

IsPairInlineValid(t1,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t1;

point[2] = pt2;

bRet = TRUE;

break;

}

 

if (m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t2;

point[2] = pt2;

bRet = TRUE;

break;

}

}

 

// 3.两拐点情况

// 先横向检测

{

//另外的两个拐点

CPoint t1, t2;

 

//X向左检测

for (int x = pt1.x - 1; x >= 0; x--)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

//X向右检测 可以使路线变短

for (x = pt1.x + 1; x < BOX_X_COUNT; x++)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向上检测

for (int y = pt1.y - 1; y >= 0; y--)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向下检测

for (y = pt1.y + 1; y < BOX_Y_COUNT; y++)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

}

break;

}

while (1);

 

if (pnResultPtCount != NULL)

{

*pnResultPtCount = count;

if (pPtResult != NULL)

{

for (int i = 0; i < count; i++)

{

pPtResult[i] = point[i];

}

}

}

return bRet;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 执行消除响应

BOOL CLLK::DoXiaoChu()

{

if (m_nSelBox != 2)

{

return FALSE;

}

 

if (m_ptSelBox[0] == m_ptSelBox[1])

{

m_nSelBox = 0;

return FALSE;

}

if (IsPairCanLink(m_ptSelBox[0], m_ptSelBox[1], &m_nLinkLine, m_ptLinkLine))

{

// 将要删除的方块情况维护

m_bHasWillBeNullBox = TRUE;

m_ptWillBeNullBox[0] = m_ptSelBox[0];

m_ptWillBeNullBox[1] = m_ptSelBox[1];

 

m_typeWillBeNullBox[0] = m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y];

m_typeWillBeNullBox[1] = m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y];

 

// 游戏方块状态维护

m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y] = 0;

m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y] = 0;

 

// 连击情况维护

if (m_dwLastLianjiTime == 0)

{

m_dwLastLianjiTime = GetTickCount();

}

DWORD nowTime = GetTickCount();

if (nowTime - m_dwLastLianjiTime <= GAME_LIANJI_TIMEOUT)

{

m_nCurLianji++;

m_dwLastLianjiTime = nowTime;

}

else

{

m_nCurLianji = 1;

m_dwLastLianjiTime = nowTime;

}

if (m_nMaxLianji < m_nCurLianji)

{

m_nMaxLianji = m_nCurLianji;

}

 

 

// 选择情况维护

m_nSelBox = 0;

m_nLeaveBoxCount -= 2;

 

return TRUE;

//AAAASetTimer(GAME_DRAW_LINK_LINE_TIMER_ID, GAME_DRAW_LINK_LINE_TIME, NULL);

}

else

{

m_ptSelBox[0] = m_ptSelBox[1];

m_nSelBox = 1;

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

void CLLK::ResetBoxState()

{

int arrTempState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

CPoint arrPointState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

int nNotNullCount = 0;

 

//将状态和坐标放到一维数组里

for (int x = 0; x < BOX_X_COUNT; x++)

{

for (int y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

arrTempState[nNotNullCount] = m_nArrType[x][y];

arrPointState[nNotNullCount].x = x;

arrPointState[nNotNullCount].y = y;

nNotNullCount++;

}

}

}

 

//为了验证 将状态清空

ZeroMemory(m_nArrType, sizeof(m_nArrType));

 

//随机

srand(GetTickCount());

int index = 0;

int max = nNotNullCount;

for (int i = 0; i < nNotNullCount; i++)

{

index = rand() % max;

m_nArrType[arrPointState[i].x][arrPointState[i].y] = arrTempState[index];

arrTempState[index] = arrTempState[max - 1] ;

max--;

}

 

if (!IsCanXiaoChu())

{

ResetBoxState();

}

//AAAA Invalidate(FALSE);

}

 

BOOL CLLK::IsCanXiaoChu()

{

CPoint *pPt = new CPoint[m_nLeaveBoxCount];

BOOL bRet = FALSE;

int x, y;

int i = 0;

for (x = 0; x < BOX_X_COUNT; x++)

{

for (y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

pPt[i].x = x;

pPt[i].y = y;

i++;

}

}

}

 

for (i = 0; i < m_nLeaveBoxCount; i++)

{

for (int j = i + 1; j < m_nLeaveBoxCount; j++)

{

if (IsPairCanLink(pPt[i], pPt[j]))

{

bRet = TRUE;

break;

}

}

if (bRet == TRUE)

{

break;

}

}

 

delete[] pPt;

return bRet;

}

 

VOID CLLK::InitGameData(int mode /*= 0*/)

{

// 初始游戏数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

int x, y;

int n = 0;

for (x = 1; x < BOX_X_COUNT - 1; x++)

{

for (y = 1; y < BOX_Y_COUNT - 1; y++)

{

m_nArrType[x][y] = n % BOX_TYPE_SIZE + 1;

n++;

}

}

 

m_nLeaveBoxCount = (BOX_X_COUNT - 2) * (BOX_Y_COUNT - 2);

 

ResetBoxState();

}

 

//////////////////////////////////////////////////////////////////////////

 

 

// DataLayer.cpp: implementation of the CDataLayer class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Server.h"

#include "DataLayer.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//在线状态的字符串显示

char *USER_STATE_TEXT[] ={"离线", "在线", "游戏中", "旁观"};

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 构造与析构

CDataLayer::CDataLayer()

{

}

 

CDataLayer::~CDataLayer()

{

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 创建(初始化)

// 返回:暂时没用到

BOOL CDataLayer::Create()

{

m_adoCon.Create();

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 连接数据库

// 参数:

// 返回:连接成功返回TRUE

BOOL CDataLayer::ConnectDB( CString szDBFileName )

{

CString openStr;

openStr.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"%s\"", szDBFileName.GetBuffer(0));

m_adoCon.Open(openStr);

if (m_adoCon.State())

{

return TRUE;

}

else

{

TRACE("D DB connect fail!!\n");

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到一个用户信息

// 参数:adoSet 从哪个Set里获取信息, user_info 将信息存到哪

// 返回:获取成功返回TRUE

BOOL CDataLayer::GetOneUser(CAdoRecordSet &adoSet, CUser &user)

{

if (adoSet.IsEmpty())

{

return FALSE;

}

int intVal = 0;

char strVal[50] ={0};

//ID

 

GetVTValue(adoSet.GetCollect("user.user_id"), &intVal);

user.ID(intVal);

 

GetVTValue(adoSet.GetCollect("user_name"), strVal);

user.Name(strVal);

 

GetVTValue(adoSet.GetCollect("user_nickname"), strVal);

user.Nickname(strVal);

 

GetVTValue(adoSet.GetCollect("user_password"), strVal);

user.Password(strVal);

 

GetVTValue(adoSet.GetCollect("user_sex"), &intVal);

user.Sex(intVal);

 

GetVTValue(adoSet.GetCollect("user_birthday"), strVal);

user.Birthday(strVal);

 

GetVTValue(adoSet.GetCollect("user_phone"), strVal);

user.Phone(strVal);

 

GetVTValue(adoSet.GetCollect("user_state"), &intVal);

user.State(intVal);

 

GetVTValue(adoSet.GetCollect("user_faceid"), &intVal);

user.FaceID(intVal);

 

GetVTValue(adoSet.GetCollect("score_val"), &intVal);

user.LLKScore(intVal);

 

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// _variant_t类型里得到数据

// 参数:vt 类型, value 数据写入的指针

VOID CDataLayer::GetVTValue(const _variant_t &vt, void *value)

{

switch (vt.vt)

{

case VT_EMPTY:

case VT_NULL:

break;

case VT_I2:

*(short *) value = vt.iVal;

break;

case VT_I4:

case VT_INT:

*(int *) value = vt.intVal;

break;

case VT_R4:

*(float *) value = vt.fltVal;

break;

case VT_R8:

*(double *) value = vt.dblVal;

break;

case VT_BSTR:

strcpy((char *) value, (LPTSTR) (_bstr_t) vt);

break;

case VT_BOOL:

*(BOOL *) value = vt.boolVal;

break;

case VT_VARIANT:

*(VARIANT *) value = vt;

break;

case VT_I1:

*(char *) value = vt.bVal;

break;

// case VT_I8:

// *(INT64*)value = vt.llVal;

// break;

case VT_UI1:

*(UCHAR *) value = vt.bVal;

break;

case VT_UI2:

case VT_UI4:

*(USHORT *) value = vt.uiVal;

break;

// case VT_UI8:

// *(ULONG64*)value = vt.ullVal;

// break;

case VT_UINT:

*(UINT *) value = vt.uintVal;

break;

case VT_VOID:

value = NULL;

break;

case VT_HRESULT:

*(HRESULT *) value = vt.lVal;

break;

case VT_PTR:

(void *) value = vt.plVal;

break;

case VT_LPSTR:

strcpy((char *) value, vt.pcVal);

break;

// case VT_LPWSTR:

// StrCpyW(value, vt.)

default:

TRACE("D DataLayer::GetVTValue:No type for change!!\n");

}

return ;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 登录之数据库操作

// 参数:loginInfo 登录信息

// 返回:成功登录返回0 失败返回错误码

INT CDataLayer::Login( const LOGIN_INFO &loginInfo )

{

//用户名测试

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("select * from [user] where user_id = %s",

loginInfo.userid);

EasyExcute(sql, adoSet);

 

if (adoSet.IsEmpty())

{

return EC_LOGIN_USER_NOT_EXIST;

}

}

//密码测试

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("select * from [user] where user_id = %s and user_password = '%s'",

loginInfo.userid,

   loginInfo.password);

EasyExcute(sql, adoSet);

 

if (adoSet.IsEmpty())

{

return EC_LOGIN_PASS_ERROR;

}

}

 

SetUserState((char *) loginInfo.userid, CUser::STATE_ONLINE);

return 0;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到当前最大用户ID 用于注册新用户

// 返回:当前最大的用户ID

int CDataLayer::GetMaxUserID()

{

CAdoRecordSet adoSet;

adoSet.Create();

CString sql;

sql = "select max(user_id) from [user] ";

adoSet.Open(sql, m_adoCon);

if (adoSet.IsEmpty())

{

//结果为空

return 100000;

}

int maxNum;

 

GetVTValue(adoSet.GetCollect((long) 0), &maxNum);

if (maxNum < 100000)

{

maxNum = 100000;

}

return maxNum;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 注册之数据库操作

// 参数:userInfo 要注册的用户信息

// 返回:注册所得的号码 范围>100000

int CDataLayer::Reg(const CUser &user)

{

CAdoRecordSet adoSet;

CString sql;

int userNum = GetMaxUserID() + 1;

sql.Format("INSERT INTO [user] VALUES(%d,'%s','%s','%s',%d,'%s','%s',%d,%d)",

   userNum,

   user.Name().GetBuffer(0),

   user.Nickname().GetBuffer(0),

   user.Password().GetBuffer(0),

   user.Sex(),

   user.Birthday().GetBuffer(0),

   user.Phone().GetBuffer(0),

   CUser::STATE_OFFLINE,

   user.FaceID());

 

EasyExcute(sql, adoSet);

return userNum;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 设置用户状态

// 参数:userId 用户ID, state 用户状态

void CDataLayer::SetUserState(int userId, int state)

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("update [user] set user_state=%d where user_id=%d",

   state,

   userId);

EasyExcute(sql, adoSet);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 设置用户状态

// 参数:userIdString 用户ID字符串, state 用户状态

void CDataLayer::SetUserState(char userIdString[], int state)

{

int userId = atoi(userIdString);

SetUserState(userId, state);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 更简易的SQL语句执行

// 参数:sql sql字符串, adoSet返回结果用的Set引用

void CDataLayer::EasyExcute(CString sql, CAdoRecordSet &adoSet)

{

adoSet.Create();

adoSet.Open(sql, m_adoCon);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 将所有用户状态设为离线 服务器刚开启时用

// 参数:

void CDataLayer::SetAllUserOffline()

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("update [user] set user_state=%d", CUser::STATE_OFFLINE);

EasyExcute(sql, adoSet);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 通过ID得到用户信息

BOOL CDataLayer::GetUser(int UID, CUser &user)

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("select * from [user],[score] where [user].user_id = %d AND [score].user_id = %d", UID, UID);

EasyExcute(sql, adoSet);

if (adoSet.IsEmpty())

{

return FALSE;

}

GetOneUser(adoSet, user);

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到积分

int CDataLayer::GetScore( int UID, int GameID /*= 1000*/ )

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("SELECT score_val FROM [score] where user_id = %d and game_id = %d", UID, GameID);

 

EasyExcute(sql, adoSet);

 

if (adoSet.IsEmpty())

{

return 0;

}

int score = 0;

score = (long)adoSet.GetCollect("score_val");

 

return score;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到积分前10

CScoreList CDataLayer::GetTop10Score()

{

CScoreList scoreList;

SCORE_INFO scoreInfo;

CAdoRecordSet adoSet;

CString sql;

sql = "SELECT TOP 10 * FROM [score]  ORDER BY score_val DESC";

EasyExcute(sql, adoSet);

 

if (adoSet.IsEmpty())

{

return scoreList;

}

while(!adoSet.adoEOF())

{

scoreInfo.GameID = (long)adoSet.GetCollect("game_id");

scoreInfo.UID = (long)adoSet.GetCollect("user_id");

scoreInfo.Score = (long)adoSet.GetCollect("score_val");

{

CUser user;

if (GetUser(scoreInfo.UID, user))

{

strcpy(scoreInfo.NickName, user.Nickname().GetBuffer(0));

}

}

scoreList.Add(scoreInfo);

adoSet.MoveNext();

}

 

return scoreList;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 添加积分 用户新建时用

void CDataLayer::NewScore( int UID, int initScore, int GameID /*= 1000*/ )

{

 

{

// 先判断是不是已经存在

CAdoRecordSet adoSet;

CString sql;

sql.Format("SELECT score_val FROM [score] where user_id = %d and game_id = %d", UID, GameID);

 

EasyExcute(sql, adoSet);

 

if (!adoSet.IsEmpty())

{

return;

}

}

{

//不存在前新建

CAdoRecordSet adoSet;

CString sql;

sql.Format("INSERT INTO [score] (game_id,user_id,score_val) VALUES(%d,%d,%d) ",GameID, UID, initScore);

EasyExcute(sql, adoSet);

}

 

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 设置积分 不常用

void CDataLayer::SetScore( int UID, int score, int GameID /*= 1000*/ )

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("UPDATE [score] SET score_val = %d WHERE game_id = %d AND user_id  = %d ", score, GameID, UID);

EasyExcute(sql, adoSet);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 加积分

void CDataLayer::AddScore( int UID, int score, int GameID /*= 1000*/ )

{

CAdoRecordSet adoSet;

CString sql;

sql.Format("UPDATE [score] SET score_val = score_val+%d WHERE game_id = %d AND user_id  = %d ", score, GameID, UID);

EasyExcute(sql, adoSet);

}

//////////////////////////////////////////////////////////////////////////

 

 

// Game.cpp: implementation of the CGame class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Game.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CGame::CGame()

{

}

 

CGame::~CGame()

{

}

 

////////////////////////////////////////////////

 

 

// GameMan.cpp: implementation of the CGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "GameMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CGameMan::CGameMan()

{

}

 

CGameMan::~CGameMan()

{

}

 

 

// LLKGameMan.cpp: implementation of the CLLKGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "LLKGameMan.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#include "../Common/User.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLKGameMan::CLLKGameMan()

{

m_state = GAME_NULL;

ZeroMemory(m_UID, sizeof(m_UID));

}

 

CLLKGameMan::~CLLKGameMan()

{

}

 

int CLLKGameMan::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(int) + sizeof(CLLKGameMan));

int dataSize = sizeof(CLLKGameMan);

cos << dataSize;

cos.Write(this, dataSize);

// cos.Write((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// char * pBuf = cos.GetCurPtr();

// int len = m_llk[i].Pack(pBuf);

// cos.MoveCurPtr(len);

// }

// }

// dataSize = cos.GetSize() - sizeof(int);

// *(int*)cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CLLKGameMan::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

cis.Read(this, sizeof(CLLKGameMan));

// cis.Read((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// const char * pBuf = cis.GetCurPtr();

// int len = m_llk[i].UnPack(pBuf);

// cis.MoveCurPtr(len);

// }

// }

return cis.GetSize();

}

 

BOOL CLLKGameMan::AddUser( int UID, char * nickName, int score, int tid, int sid )

{

if (m_UID[sid] == 0)

{

m_UID[sid] = UID;

strcpy(m_NickName[sid], nickName);

m_Score[sid] = score;

}

return TRUE;

}

 

BOOL CLLKGameMan::DelUser( int UID )

{

 

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_UID[i] = 0;

strcpy(m_NickName[i], "");

m_Score[i] = 0;

m_userState[i] = GAME_NULL;

if (GetUserCount() == 0)

{

m_state = GAME_NULL;

}

return TRUE;

}

}

 

return FALSE;

}

 

void CLLKGameMan::InitGame()

{

for (int i = 0; i < 6; i++)

{

m_llk[i].Init();

}

m_llk[0].InitGameData();

// m_llk[0].m_nArrType[1][1] = 1;

// m_llk[0].m_nArrType[1][5] = 1;

// m_llk[0].m_nLeaveBoxCount = 2;

for (i = 1; i < 6; i++)

{

m_llk[i] = m_llk[0];

}

}

 

void CLLKGameMan::SetUserState( int UID, int state )

{

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_userState[i] = state;

return;

}

}

}

 

int CLLKGameMan::CheckGame()

{

if (m_state == GAME_NULL)

{

int userCount = GetUserCount();

if (GetUserCount() == 0)

{

return 0;

}

int readyUserCount = GetReadyUserCount();

if (userCount == readyUserCount && userCount >= MINI_USER_TO_PLAY)

{

return CGR_TOBEGIN;

}

}

else if (m_state == GAME_PLAYING)

{

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_llk[i].m_nLeaveBoxCount == 0)

{

return CGR_TOEND;

}

}

}

 

return CGR_NULL;

}

 

int CLLKGameMan::GetUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

count++;

}

}

return count;

}

 

int CLLKGameMan::GetReadyUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_userState[i] == CUser::GAME_STATE_READY)

{

count++;

}

}

return count;

}

 

BOOL CLLKGameMan::StartGame( int nGameID /*= 1*/ )

{

m_state = GAME_PLAYING;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_PLAYING;

}

}

InitGame();

return TRUE;

}

 

CScoreList CLLKGameMan::EndGame( int nGameID /*= 1*/ )

{

CScoreList  sl;

//游戏结束前计算分数

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

SCORE_INFO si;

si.UID = m_UID[i];

strcpy(si.NickName, m_NickName[i]);

si.GameID = 1000;

si.Score = m_llk[i].m_nLeaveBoxCount;

sl.Add(si);

}

}

CalcScore(sl);

 

//清除各种状态

m_state = GAME_NULL;

for (i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_NULL;

}

}

 

return sl;

}

 

int CLLKGameMan::CalcScore( CScoreList &sl )

{

sl.Sort();

switch (sl.GetCount())

{

case 0:

TRACE("CalcScore not item in scoreList.. \n");

break;

case 1:

sl.GetScoreByIndex(0).Score = 1;

break;

case 2:

sl.GetScoreByIndex(0).Score = 2;

sl.GetScoreByIndex(1).Score = 0;

 

break;

case 3:

sl.GetScoreByIndex(0).Score = 3;

sl.GetScoreByIndex(1).Score = 1;

sl.GetScoreByIndex(2).Score = -1;

break;

case 4:

sl.GetScoreByIndex(0).Score = 4;

sl.GetScoreByIndex(1).Score = 2;

sl.GetScoreByIndex(2).Score = 0;

sl.GetScoreByIndex(3).Score = -1;

break;

case 5:

sl.GetScoreByIndex(0).Score = 5;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

break;

case 6:

sl.GetScoreByIndex(0).Score = 6;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

sl.GetScoreByIndex(5).Score = -2;

break;

}

return sl.GetCount();

}

 

 

// MyIOCP.cpp: implementation of the CMyIOCP class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Server.h"

#include "MyIOCP.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 构造析构

CMyIOCP::CMyIOCP()

{

CTable table;

table.Create(1);

m_tableMan.AddTable(table);

}

 

CMyIOCP::~CMyIOCP()

{

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 方便发送函数

// 参数:msg 要发送的msg的引用,s 从哪个SOCKET发送, addr 发送目的地地址的引用

// 返回:成功返回TRUE

int CMyIOCP::EasySentPacTo( CPacket &pac, SOCKET s, const sockaddr &addr )

{

IO_DATA *pIODataToClient = NewIOData();

 

pIODataToClient->m_sock = s;

pIODataToClient->m_from = addr;

pIODataToClient->m_type = IT_SENDTO;

 

int len = pac.Pack(pIODataToClient->m_data);

pIODataToClient->m_wsaBuf.len = len;

int sendRet = WSASendTo(pIODataToClient->m_sock,

&pIODataToClient->m_wsaBuf,

1,

&pIODataToClient->m_numberOfBytes,

pIODataToClient->m_flag,

&pIODataToClient->m_from,

pIODataToClient->m_fromLen,

(LPWSAOVERLAPPED) pIODataToClient,

NULL);

 

if (sendRet == SOCKET_ERROR)

{

int err = GetLastError();

if (err == WSA_IO_PENDING)

{

TRACE("N WSASendTo : IO pending......\n");

}

else

{

TRACE("N WSASendTo err = %d\n", err);

return FALSE;

}

}

return TRUE;

}

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 方便发送消息的函数

// 参数:nType 类型 dataSize 数据大小 pData 数据指针, s 从哪个SOCKET发送, addr 发送目的地地址的引用

// 返回:成功返回TRUE

int CMyIOCP::EasySentTo( int nType, int dataSize, void * pData, SOCKET s, const sockaddr &addr )

{

CPacket pac;

pac.Make(nType, 0, dataSize, pData);

return EasySentPacTo(pac, s, addr);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// RecvFrom事件的重写

void CMyIOCP::OnRecvFrom(IO_DATA *pIOData)

{

//TODO:

//TRACE("CMyIOCP::OnRecvFrom\n");

CPacket pac;

pac.UnPack(pIOData->m_data);

switch (pac.m_nType)

{

case PTC_LOGIN_ENTER:

TRACE("C Login enter... \n");

DoLogin(pIOData);

break;

case PTC_REG_ENTER:

TRACE("C Reg enter... \n");

 

DoReg(pIOData);

break;

case PTC_SEAT_DOWN:

TRACE("C Seat down... \n");

 

DoSeatDown(pIOData);

break;

case PTC_LOOK_ON:

TRACE("C Look on... \n");

 

DoLookOn(pIOData);

break;

case PTCS_GET_TABLE_INFO:

TRACE("C Get table ... \n");

 

SendTableInfo(pIOData);

break;

case PTCS_GET_LOGIN_USER_INFO:

TRACE("C Get login user info... \n");

DoGetLoginUserInfo(pIOData);

break;

case PTCS_EXIT:

TRACE("C Exit... \n");

 

DoExit(pIOData);

break;

case PTC_STAND_UP:

TRACE("C Stand up... \n");

 

DoStandUp(pIOData);

break;

case PTCS_GET_USER_LIST:

TRACE("C Get user list... \n");

 

SendUserList(pIOData);

break;

case PTCS_CHECK_ONLINE:

TRACE("C Check online... \n");

 

DoCheckOnline(pIOData);

break;

case PTC_SEND_GAMEINFO:

TRACE("C Send the game info...  \n");

DoSendGameInfo(pIOData);

break;

case PTCS_GET_GAMEINFO:

TRACE("C Get game info... \n");

DoGetGameInfo(pIOData);

break;

case PTCS_GET_SCORE_TOP10:

TRACE("C Get top10...   \n");

DoGetScoreTop10(pIOData);

break;

case PTC_GAME_READY:

TRACE("C someone ready...   \n");

DoGameReady(pIOData);

break;

}

CIOCP::OnRecvFrom(pIOData);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 错误处理

void CMyIOCP::OnError(int err, IO_DATA *pIOData)

{

if (err == WSAECONNRESET || err == 1234)

{

int UID = m_userMan.GetUserID(pIOData->m_from);

if (UID != 0)

{

m_userMan.DelUser(UID);

m_tableMan.DelUser(UID);

SendUserListToAllRoomUser(pIOData->m_sock);

SendTableInfoToAllRoomUser(pIOData->m_sock);

}

}

CIOCP::OnError(err, pIOData);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 事件处理之:登陆事件

// 参数:IO_DATA的数据

void CMyIOCP::DoLogin(IO_DATA *pIOData)

{

CPacket pac;

pac.UnPack(pIOData->m_data);

 

CInStream cis;

cis.Create(pac.m_pData);

 

LOGIN_INFO li;

cis.Read((char *) &li, pac.m_nDataLen);

 

INT loginRet = 0;

//TODO:判断用户名和密码

loginRet = g_dataLayer.Login(li);

 

//向客户端返回结果

 

CPacket pacToClient;

if (loginRet == 0)

{

// 成功登录先将用户信息添加到CUserMan

CUser user;

BOOL bRet = g_dataLayer.GetUser(atoi(li.userid), user);

user.Addr(pIOData->m_from);

if (bRet)

{

if (m_userMan.AddUser(user))

{

pacToClient.Make(PTS_LOGIN_SUCC, 0, 0, NULL);

}

else

{

int errCode = EC_LOGIN_USER_LOGINED;

pacToClient.Make(PTS_LOGIN_FAIL, 0, sizeof(errCode), &errCode);

}

}

// 再向客户端发送成功消息

}

else

{

pacToClient.Make(PTS_LOGIN_FAIL, 0, sizeof(loginRet), &loginRet);

}

EasySentPacTo(pacToClient, pIOData->m_sock, pIOData->m_from);

 

SendUserListToAllRoomUser(pIOData->m_sock);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 注册事件处理

VOID CMyIOCP::DoReg(IO_DATA *pIOData)

{

CPacket pac;

pac.UnPack(pIOData->m_data);

 

CUser user;

user.UnPack(pac.m_pData);

 

int newUserNum = 0;

//TODO:向数据据提交

{

newUserNum = g_dataLayer.Reg(user);

}

 

//向客户端返回结果

CPacket pacToCLient;

pacToCLient.Make(PTS_REG_SUCC, 0, sizeof(int), &newUserNum);

EasySentPacTo(pacToCLient, pIOData->m_sock, pIOData->m_from);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 坐位置处理

void CMyIOCP::DoSeatDown(IO_DATA *pIOData)

{

int retSeatDown = 0;

CPacket pac;

pac.UnPack(pIOData->m_data);

 

CInStream cis;

cis.Create(pac.m_pData);

int seatIndex = 0;

 

int uid = 0;

int tid = 0;

int sid = 0;

cis >> uid >> tid >> sid;

 

// 判断用户是否存在

if (m_userMan.HasUser(uid))

{

if (m_tableMan.HasUser(uid))

{

m_tableMan.DelUser(uid);

}

// 向桌子管理提交坐下请求

if (m_tableMan.AddUser(uid, tid, sid))

{

// 成功则把标志设为1

retSeatDown = 1;

}

}

 

if (retSeatDown == 0)

{

//失败时操作

CPacket pacToClient;

pacToClient.Make(PTS_SEAT_DOWN_FAIL, 0, 0, NULL);

EasySentPacTo(pacToClient, pIOData->m_sock, pIOData->m_from);

}

else

{

CUser * pUser = m_userMan.GetUser(uid);

if (pUser != NULL)

{

pUser->TableID(tid);

pUser->SeatID(sid);

}

// 向游戏管理提交坐下请求

if (m_llkGameMan.AddUser(uid, pUser->Nickname().GetBuffer(0), pUser->LLKScore(), tid, sid))

{

TRACE("T m_llkGameMan AddUser.Success....\n");

}

else

{

TRACE("T m_llkGameMan AddUser. Fail.....\n");

}

//成功时操作

CPacket pacToClient;

pacToClient.Make(PTS_SEAT_DOWN_SUCC, 0, 0, NULL);

EasySentPacTo(pacToClient, pIOData->m_sock, pIOData->m_from);

}

SendTableInfoToAllRoomUser(pIOData->m_sock);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 旁观事件

void CMyIOCP::DoLookOn(IO_DATA *pIOData)

{

int retLookOn = 0;

CPacket pac;

pac.UnPack(pIOData->m_data);

 

CInStream cis;

cis.Create(pac.m_pData);

int seatIndex = 0;

 

int uid = 0;

int tid = 0;

int sid = 0;

cis >> uid >> tid >> sid;

 

// 判断用户是否存在

if (m_userMan.HasUser(uid))

{

// 找到要查看的用户id

CTable * pTable = m_tableMan.GetTable(tid);

if (pTable != NULL)

{

retLookOn = pTable->GetSeat(sid).m_nUID;

}

}

// 结果处理

if (retLookOn != 0)

{

// 成功处理

TRACE("C Look on checked success... \n");

CPacket pacToClient;

pacToClient.Make(PTS_LOOK_ON_SUCC, 0, sizeof(retLookOn), &retLookOn);

EasySentPacTo(pacToClient, pIOData->m_sock, pIOData->m_from);

}

else

{

// 失败处理

TRACE("C Look on checked fail... \n");

CPacket pacToClient;

pacToClient.Make(PTS_LOOK_ON_FAIL, 0, 0, NULL);

EasySentPacTo(pacToClient, pIOData->m_sock, pIOData->m_from);

}

 

 

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 处理退出

void CMyIOCP::DoExit(IO_DATA *pIOData)

{

int UID = m_userMan.GetUserID(pIOData->m_from);

DoStandUp(pIOData);

if (UID != 0)

{

m_userMan.DelUser(UID);

}

 

SendTableInfoToAllRoomUser(pIOData->m_sock);

SendUserListToAllRoomUser(pIOData->m_sock);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到在线用户

// 返回:用户列表

CUserList CMyIOCP::GetOnlineUser()

{

return m_userMan.GetUserList();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送桌子信息

void CMyIOCP::SendTableInfo(IO_DATA *pIOData)

{

SendTableInfo(pIOData->m_sock, pIOData->m_from);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送桌子到客户端

// 参数:sock 用哪个sock发送, addr 发送到哪个地址

void CMyIOCP::SendTableInfo(SOCKET sock, sockaddr &addr)

{

CPacket pac;

char buf[1024];

int len = m_tableMan.Pack(buf);

pac.Make(PTCS_GET_TABLE_INFO, 0, len, buf);

EasySentPacTo(pac, sock, addr);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

//将桌子信息发送到房间里的所有用户

//因为目前没房间的概念 就发送到 所有用户

void CMyIOCP::SendTableInfoToAllRoomUser(SOCKET sock)

{

TRACE("S Send table info to all room user...\n");

for (int i = 0; i < m_userMan.GetUserCount(); i++)

{

SendTableInfo(sock, (sockaddr &) m_userMan.GetUserByIndex(i)->Addr());

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送用户列表到客户端

void CMyIOCP::SendUserList(IO_DATA *pIOData)

{

SendUserList(pIOData->m_sock, pIOData->m_from);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送用户列表到客户端

void CMyIOCP::SendUserList(SOCKET sock, sockaddr &addr)

{

char buf[2048] ={0};

 

int len = m_userMan.Pack(buf);

EasySentTo(PTCS_GET_USER_LIST, len, buf, sock, addr);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送用户列表到客户端

void CMyIOCP::SendUserListToAllRoomUser(SOCKET sock)

{

TRACE("S Send user list to all room user........\n");

for (int i = 0; i < m_userMan.GetUserCount(); i++)

{

SendUserList(sock, (sockaddr &) m_userMan.GetUserByIndex(i)->Addr());

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 处理用户登录后得到用户信息

void CMyIOCP::DoGetLoginUserInfo(IO_DATA *pIOData)

{

int UID = m_userMan.GetUserID(pIOData->m_from);

if (UID != 0)

{

CUser user;

user = *m_userMan.GetUser(UID);

 

char buf[512];

int len = user.Pack(buf);

EasySentTo(PTCS_GET_LOGIN_USER_INFO, len, buf, pIOData->m_sock, pIOData->m_from);

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 用户离开座位

void CMyIOCP::DoStandUp(IO_DATA *pIOData)

{

int uid = m_userMan.GetUserID(pIOData->m_from);

 

m_tableMan.DelUser(uid);

m_llkGameMan.DelUser(uid);

 

SendTableInfoToAllRoomUser(pIOData->m_sock);

if (m_tableMan.GetTable(1)->TableState() == GAME_PLAYING)

{

SendLLKGameInfoToAllTableUser(pIOData->m_sock);

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 检测在线状况的处理

void CMyIOCP::DoCheckOnline(IO_DATA *pIOData)

{

//TODO:

//好像不需要做什么

//如果采用客户端发送心跳的话再处理

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 检测在线

void CMyIOCP::CheckOnline(SOCKET sock)

{

CPacket pac;

pac.Make(PTCS_CHECK_ONLINE, 0, 0, NULL);

SendPacToAllUser(sock, pac);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 将某个包发送到所有用户

void CMyIOCP::SendPacToAllUser(SOCKET sock, CPacket &pac)

{

for (int i = 0; i < m_userMan.GetUserCount(); i++)

{

EasySentPacTo(pac, sock, (sockaddr &) m_userMan.GetUserByIndex(i)->Addr());

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 处理用户发送LLK游戏信息

void CMyIOCP::DoSendGameInfo( IO_DATA *pIOData )

{

CUser * pUser = m_userMan.GetUserByAddr(pIOData->m_from);

if (pUser == NULL)

{

return;

}

int uid = pUser->ID();

int tid = pUser->TableID();

int sid = pUser->SeatID();

 

CPacket pac;

pac.UnPack(pIOData->m_data);

CLLK llk;

llk.UnPack(pac.m_pData);

 

m_llkGameMan.m_llk[sid] = llk;

SendLLKGameInfoToAllTableUser(pIOData->m_sock);

 

DoCheckGame(pIOData);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送游戏信息到桌子上的所有人

void CMyIOCP::SendLLKGameInfoToAllTableUser( SOCKET sock )

{

char *pBuf = new char[sizeof(CLLKGameMan)+sizeof(int)];

int len = m_llkGameMan.Pack(pBuf);

CPacket pac;

pac.Make(PTCS_GET_GAMEINFO, 0, len, pBuf);

SendPacToAllUser(sock, pac);

 

delete [] pBuf;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 处理客户请求llk数据

void CMyIOCP::DoGetGameInfo( IO_DATA *pIOData )

{

char *pBuf = new char[sizeof(CLLKGameMan)+sizeof(int)];

int len = m_llkGameMan.Pack(pBuf);

EasySentTo(PTCS_GET_GAMEINFO, len, pBuf, pIOData->m_sock, pIOData->m_from);

delete [] pBuf;

 

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 处理客户对积分排行的请求

void CMyIOCP::DoGetScoreTop10( IO_DATA *pIOData )

{

CScoreList scoreListTop10;

scoreListTop10 = g_dataLayer.GetTop10Score();

int bufLen = scoreListTop10.GetCount()*sizeof(SCORE_INFO)+sizeof(int)*2;

char * pBuf = new char[bufLen];

int len = scoreListTop10.Pack(pBuf);

EasySentTo(PTCS_GET_SCORE_TOP10, len, pBuf, pIOData->m_sock, pIOData->m_from);

delete [] pBuf;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 处理客户准备

void CMyIOCP::DoGameReady( IO_DATA *pIOData )

{

CUser * pUser = m_userMan.GetUserByAddr(pIOData->m_from);

if (pUser != NULL)

{

pUser->GameState(CUser::GAME_STATE_READY);

m_tableMan.SetUserState(pUser->ID(), pUser->GameState());

m_llkGameMan.SetUserState(pUser->ID(), pUser->GameState());

}

SendTableInfoToAllRoomUser(pIOData->m_sock);

 

DoCheckGame(pIOData);

}

 

void CMyIOCP::DoStartGame( IO_DATA *pIOData )

{

m_tableMan.StartGame();

m_llkGameMan.StartGame();

char *pBuf = new char[sizeof(CLLKGameMan)+sizeof(int)];

int len = m_llkGameMan.Pack(pBuf);

 

SendTableInfoToAllRoomUser(pIOData->m_sock);

CPacket pac;

pac.Make(PTS_GAME_BEGIN, 0, len, pBuf);

SendPacToAllUser(pIOData->m_sock, pac);

delete [] pBuf;

}

 

void CMyIOCP::DoEndGame( IO_DATA *pIOData )

{

TRACE("S Do end game...  \n");

m_tableMan.EndGame();

 

SendLLKGameInfoToAllTableUser(pIOData->m_sock);

SendTableInfoToAllRoomUser(pIOData->m_sock);

 

CScoreList sl = m_llkGameMan.EndGame();

{

for (int i=0;i<sl.GetCount();i++)

{

SCORE_INFO * pScore = &sl.GetScoreByIndex(i);

g_dataLayer.AddScore(pScore->UID, pScore->Score);

m_userMan.AddScore(pScore->UID, pScore->Score);

SendUserInfoToClient(pScore->UID, pIOData->m_sock);

}

}

char *pBuf = new char[sizeof(SCORE_INFO)*6+sizeof(int)*2];

int len = sl.Pack(pBuf);

CPacket pac;

pac.Make(PTS_GAME_END, 0, len, pBuf);

SendPacToAllUser(pIOData->m_sock, pac);

delete [] pBuf;

}

 

void CMyIOCP::DoCheckGame( IO_DATA *pIOData )

{

int checkRet = m_llkGameMan.CheckGame();

TRACE("S DoCheckGame ret = %d \n", checkRet);

switch(checkRet)

{

case CGR_NULL:

break;

case CGR_TOBEGIN:

DoStartGame(pIOData);

break;

case CGR_TOEND:

DoEndGame(pIOData);

break;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送用户的信息到客户端

void CMyIOCP::SendUserInfoToClient( int UID, SOCKET sock )

{

if (UID != 0)

{

CUser user;

user = *m_userMan.GetUser(UID);

 

char buf[512];

int len = user.Pack(buf);

EasySentTo(PTCS_GET_LOGIN_USER_INFO, len, buf, sock, user.Addr());

}

}

//////////////////////////////////////////////////////////////////////////

 

 

// Room.cpp: implementation of the CRoom class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Room.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CRoom::CRoom()

{

}

 

CRoom::~CRoom()

{

}

 

 

// RoomList.cpp: implementation of the CRoomList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "RoomList.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CRoomList::CRoomList()

{

}

 

CRoomList::~CRoomList()

{

}

 

 

// RoomMan.cpp: implementation of the CRoomMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "RoomMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CRoomMan::CRoomMan()

{

}

 

CRoomMan::~CRoomMan()

{

}

 

 

// ScoreList.cpp: implementation of the CScoreList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "ScoreList.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CScoreList::CScoreList()

{

 

}

 

CScoreList::~CScoreList()

{

 

}

 

int CScoreList::Pack( void * pData )

{

COutStream cos;

int dataSize = 0;

int count = GetCount();

cos.Create(count*sizeof(SCORE_INFO)+sizeof(int)*2);

 

cos<<dataSize;

cos<<count;

for (int i=0;i<count;i++)

{

cos.Write(&m_vecScore.at(i), sizeof(SCORE_INFO));

}

dataSize = cos.GetSize() - sizeof(int);

*(int*)cos.GetHead() = dataSize;

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CScoreList::UnPack( const void * pData )

{

m_vecScore.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

int count = 0;

cis>>dataSize>>count;

SCORE_INFO scoreInfo;

for (int i=0;i<count;i++)

{

cis.Read(&scoreInfo, sizeof(SCORE_INFO));

m_vecScore.push_back(scoreInfo);

}

return cis.GetSize();

}

 

void CScoreList::Add( SCORE_INFO& scoreInfo )

{

m_vecScore.push_back(scoreInfo);

}

 

BOOL CScoreList::Del( int uid, int gid )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

for (;begit != endit; ++begit)

{

if (begit->GameID == gid && begit->UID == uid)

{

m_vecScore.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

int CScoreList::GetCount()

{

return m_vecScore.size();

}

 

SCORE_INFO &CScoreList::GetScoreByIndex( int index )

{

return m_vecScore[index];

}

 

void CScoreList::Sort( int mode /*= 0*/ )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

VEC_SCORE_INFO::iterator tmpit = begit+1;

SCORE_INFO tsi;

int swapCount = 0;

do

{

swapCount = 0;

for (;begit != endit - 1; ++begit)

{

tmpit = begit+1;

if (begit->Score > tmpit->Score)

{

tsi = *begit;

*begit = *tmpit;

*tmpit = tsi;

swapCount++;

}

}

} while (swapCount != 0);

}

 

 

// Server.cpp : Defines the class behaviors for the application.

//

 

#include "stdafx.h"

#include "Server.h"

#include "ServerDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

CDataLayer g_dataLayer;

 

/////////////////////////////////////////////////////////////////////////////

// CServerApp

 

BEGIN_MESSAGE_MAP(CServerApp, CWinApp)

//{{AFX_MSG_MAP(CServerApp)

// NOTE - the ClassWizard will add and remove mapping macros here.

//    DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG

ON_COMMAND(ID_HELP, CWinApp::OnHelp)

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CServerApp construction

 

CServerApp::CServerApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}

 

/////////////////////////////////////////////////////////////////////////////

// The one and only CServerApp object

 

CServerApp theApp;

 

/////////////////////////////////////////////////////////////////////////////

// CServerApp initialization

 

BOOL CServerApp::InitInstance()

{

::CoInitialize(NULL);

 

AfxEnableControlContainer();

 

// Standard initialization

// If you are not using these features and wish to reduce the size

//  of your final executable, you should remove from the following

//  the specific initialization routines you do not need.

 

#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif

 

if (!CMySocket::StartUp())

{

TRACE("N CMySocket::StartUp error!\n");

return 0;

}

CString szDBFileName;

GetAppPath(szDBFileName.GetBuffer(MAX_PATH+1));

szDBFileName.ReleaseBuffer();

szDBFileName += "game.mdb";

 

g_dataLayer.Create();

if (!g_dataLayer.ConnectDB(szDBFileName))

{

TRACE("D g_dataLayer.ConnectDB() error!\n");

return 0;

}

 

CServerDlg dlg;

m_pMainWnd = &dlg;

int nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with OK

}

else if (nResponse == IDCANCEL)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with Cancel

}

 

WSACleanup();

::CoUninitialize();

// Since the dialog has been closed, return FALSE so that we exit the

//  application, rather than start the application's message pump.

return FALSE;

}

 

 

// ServerDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Server.h"

#include "ServerDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

#define REFRESH_TIMER_ID 100

#define REFRESH_TIME_OUT 1000

 

#define AUTO_CHECK_ONLINE_TIMER_ID 101

 

/////////////////////////////////////////////////////////////////////////////

// CAboutDlg dialog used for App About

 

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

 

// Dialog Data

//{{AFX_DATA(CAboutDlg)

enum { IDD = IDD_ABOUTBOX };

//}}AFX_DATA

 

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

//{{AFX_MSG(CAboutDlg)

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

 

}

 

void CAboutDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

 

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CServerDlg dialog

 

CServerDlg::CServerDlg(CWnd *pParent /*=NULL*/) : CDialog(CServerDlg::IDD,

  pParent)

{

//{{AFX_DATA_INIT(CServerDlg)

m_bAutoRefresh = FALSE;

m_bCheckOnline = FALSE;

m_nChectOlineTimeOut = 300;

//}}AFX_DATA_INIT

// Note that LoadIcon does not require a subsequent DestroyIcon in Win32

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

 

void CServerDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CServerDlg)

DDX_Control(pDX, IDC_LIST_ONLINE_USER, m_listOnlineUser);

DDX_Check(pDX, IDC_CHECK_AUTO_REFREASH, m_bAutoRefresh);

DDX_Check(pDX, IDC_CHECK_AUTO_CHECK_ONLINE, m_bCheckOnline);

DDX_Text(pDX, IDC_EDIT_CHECT_TIMEOUT, m_nChectOlineTimeOut);

DDV_MinMaxUInt(pDX, m_nChectOlineTimeOut, 0, 3000);

//}}AFX_DATA_MAP

 

}

 

BEGIN_MESSAGE_MAP(CServerDlg, CDialog)

//{{AFX_MSG_MAP(CServerDlg)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_BN_CLICKED(IDC_BTN_START, OnBtnStart)

ON_BN_CLICKED(IDC_BTN_STOP, OnBtnStop)

ON_BN_CLICKED(IDC_BTN_REFRESH_ONLINE_USER, OnBtnRefreshOnlineUser)

ON_BN_CLICKED(IDC_CHECK_AUTO_REFREASH, OnCheckAutoRefreash)

ON_WM_TIMER()

ON_BN_CLICKED(IDC_BTN_TEST, OnBtnTest)

ON_BN_CLICKED(IDC_BTN_CHECK_ONLINE, OnBtnCheckOnline)

ON_BN_CLICKED(IDC_CHECK_AUTO_CHECK_ONLINE, OnCheckAutoCheckOnline)

ON_MESSAGE(DM_GETDEFID, OnGetDefID)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CServerDlg message handlers

 

BOOL CServerDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// Add "About..." menu item to system menu.

 

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

 

CMenu *pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

 

// Set the icon for this dialog.  The framework does this automatically

//  when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set small icon

 

// TODO: Add extra initialization here

if (!m_iocp.Create())

{

MessageBox("IOCP creat fail!!\n");

return FALSE;

}

 

GetDlgItem(IDC_BTN_START)->EnableWindow(TRUE);

GetDlgItem(IDC_BTN_STOP)->EnableWindow(FALSE);

 

m_listOnlineUser.SetExtendedStyle(m_listOnlineUser.GetExtendedStyle() |

  LVS_EX_FULLROWSELECT |

  LVS_EX_GRIDLINES);

 

m_listOnlineUser.InsertColumn(0, "用户ID", LVCFMT_CENTER, 120);

m_listOnlineUser.InsertColumn(1, "用户昵称", LVCFMT_CENTER, 150);

m_listOnlineUser.InsertColumn(2, "玩家状态", LVCFMT_CENTER, 100);

 

return TRUE;  // return TRUE  unless you set the focus to a control

}

 

void CServerDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

 

// If you add a minimize button to your dialog, you will need the code below

//  to draw the icon.  For MFC applications using the document/view model,

//  this is automatically done for you by the framework.

LRESULT CServerDlg::OnGetDefID( WPARAM wParam, LPARAM lParam )

{

return MAKELONG(0, DC_HASDEFID);

}

 

void CServerDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc (this); // device context for painting

 

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

 

// Center icon in client rectangle

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

 

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

// The system calls this to obtain the cursor to display while the user drags

//  the minimized window.

HCURSOR CServerDlg::OnQueryDragIcon()

{

return (HCURSOR) m_hIcon;

}

 

void CServerDlg::OnBtnStart()

{

// TODO: Add your control notification handler code here

g_dataLayer.SetAllUserOffline();

 

m_sockServer = socket(AF_INET, SOCK_DGRAM, 0);

if (m_sockServer == NULL)

{

MessageBox("Server create error!");

}

 

sockaddr_in local;

ZeroMemory(&local, sizeof(sockaddr_in));

local.sin_family = AF_INET;

local.sin_port = htons(8888);

local.sin_addr.S_un.S_addr = INADDR_ANY;

 

int ret = bind(m_sockServer, (sockaddr *) &local, sizeof(sockaddr));

if (ret == SOCKET_ERROR)

{

closesocket(m_sockServer);

MessageBox("端口绑定失败!可能是另一程序占用了!", "提示");

return;

}

 

if (!m_iocp.Bind(m_sockServer))

{

MessageBox("Bind fail!!!");

}

 

m_iocp.Start();

 

GetDlgItem(IDC_BTN_START)->EnableWindow(FALSE);

GetDlgItem(IDC_BTN_STOP)->EnableWindow(TRUE);

 

m_iocp.StartRecvFrom(m_sockServer);

}

 

void CServerDlg::OnBtnStop()

{

// TODO: Add your control notification handler code here

shutdown(m_sockServer, SD_BOTH);

closesocket(m_sockServer);

 

m_iocp.Stop();

 

GetDlgItem(IDC_BTN_START)->EnableWindow(TRUE);

GetDlgItem(IDC_BTN_STOP)->EnableWindow(FALSE);

}

 

 

void CServerDlg::OnBtnRefreshOnlineUser()

{

// TODO: Add your control notification handler code here

m_listOnlineUser.DeleteAllItems();

 

CUserList userList = m_iocp.GetOnlineUser();

if (userList.GetUserCount() == 0)

{

return;

}

CString str;

for (int i = 0; i < userList.GetUserCount(); i++)

{

CUser *pUser = userList.GetUserByIndex(i);

if (pUser == NULL)

{

continue;

}

str.Format("%d", pUser->ID());

m_listOnlineUser.InsertItem(i, str);

 

//str.Format("%s", pUser);

m_listOnlineUser.SetItemText(i, 1, pUser->Nickname());

 

str.Format("%s", USER_STATE_TEXT[pUser->State()]);

m_listOnlineUser.SetItemText(i, 2, str);

}

}

 

void CServerDlg::OnCheckAutoRefreash()

{

// TODO: Add your control notification handler code here

UpdateData();

if (m_bAutoRefresh)

{

SetTimer(REFRESH_TIMER_ID, REFRESH_TIME_OUT, NULL);

}

else

{

KillTimer(REFRESH_TIMER_ID);

}

}

 

void CServerDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

if (nIDEvent == REFRESH_TIMER_ID)

{

OnBtnRefreshOnlineUser();

}

if (nIDEvent == AUTO_CHECK_ONLINE_TIMER_ID)

{

OnBtnCheckOnline();

}

CDialog::OnTimer(nIDEvent);

}

 

void CServerDlg::OnBtnTest()

{

// TODO: Add your control notification handler code here

//m_iocp.m_userMan.

}

 

void CServerDlg::OnBtnCheckOnline()

{

// TODO: Add your control notification handler code here

m_iocp.CheckOnline(m_sockServer);

}

 

void CServerDlg::OnCheckAutoCheckOnline()

{

// TODO: Add your control notification handler code here

UpdateData();

if (m_bCheckOnline == TRUE)

{

SetTimer(AUTO_CHECK_ONLINE_TIMER_ID, m_nChectOlineTimeOut * 1000, NULL);

GetDlgItem(IDC_EDIT_CHECT_TIMEOUT)->EnableWindow(FALSE);

}

else

{

KillTimer(AUTO_CHECK_ONLINE_TIMER_ID);

GetDlgItem(IDC_EDIT_CHECT_TIMEOUT)->EnableWindow(TRUE);

}

}

 

 

// stdafx.cpp : source file that includes just the standard includes

// Server.pch will be the pre-compiled header

// stdafx.obj will contain the pre-compiled type information

 

#include "stdafx.h"

 

 

// Table.cpp: implementation of the CTable class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Table.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

#include "LLKGameMan.h"

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTable::CTable()

{

m_nTableID = 0;

m_nTableState = GAME_NULL;

}

CTable::~CTable()

{

}

 

VOID CTable::Create(int nTableID, int nSeatCount /*= 6*/)

{

m_nTableID = nTableID;

for (int i = 0; i < 6; i++)

{

m_seat[i].Creat(m_nTableID, i);

}

}

 

BOOL CTable::AddUser(int UID, int SeatID)

{

if (m_seat[SeatID].m_nUID == 0)

{

m_seat[SeatID].m_nUID = UID;

return TRUE;

}

return FALSE;

}

 

BOOL CTable::DelUser(int UID)

{

for (int i = 0; i < 6; i++)

{

if (m_seat[i].m_nUID == UID)

{

m_seat[i].m_nUID = UID;

return TRUE;

}

}

return FALSE;

}

 

int CTable::Pack(char *pData)

{

COutStream cos;

cos.Create(512);

int dataSize = 0;

cos << dataSize;

cos << m_nTableID;

cos << m_nTableState;

cos.Write((char *) m_seat, sizeof(CSeat) * 6);

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

cos.CopyTo(pData);

return cos.GetSize();

}

 

int CTable::UnPack(const char *pData)

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

cis >> m_nTableID;

cis >> m_nTableState;

cis.Read((char *) m_seat, sizeof(CSeat) * 6);

return dataSize + sizeof(int);

}

 

CSeat & CTable::GetSeat(int SeatID)

{

return m_seat[SeatID];

}

 

BOOL CTable::StartGame()

{

m_nTableState = GAME_PLAYING;

for (int i=0;i<6;i++)

{

if (m_seat[i].m_nUID != 0)

{

m_seat[i].m_nState = GAME_PLAYING;

}

}

return TRUE;

}

 

BOOL CTable::EndGame()

{

m_nTableState = GAME_NULL;

for (int i=0;i<6;i++)

{

if (m_seat[i].m_nUID != 0)

{

m_seat[i].m_nState = GAME_NULL;

}

}

return TRUE;

}

 

int CTable::GetUserCount()

{

int count = 0;

for (int i=0; i<6; i++)

{

if (m_seat[i].m_nUID != 0)

{

count++;

}

}

return count;

}

CSeat::CSeat()

{

m_nTableID = 0;

m_nSeatID = 0;

m_nUID = 0;

m_nState = 0;

}

 

void CSeat::Creat(int nTableID, int nSeatID)

{

m_nTableID = nTableID;

m_nSeatID = nSeatID;

}

 

 

// TableIDList.cpp: implementation of the CTableIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableIDList.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableIDList::CTableIDList()

{

}

 

CTableIDList::~CTableIDList()

{

}

 

 

// TableList.cpp: implementation of the CTableList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableList.h"

#include "LLKGameMan.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableList::CTableList()

{

}

 

CTableList::~CTableList()

{

}

 

BOOL CTableList::AddUser(int UID, int nTableID, int nSeatID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit->AddUser(UID, nSeatID);

}

}

return FALSE;

}

 

BOOL CTableList::DelUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

// 如果该位置上的id是要删除的id 则删除

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nUID = 0;

// 删除之后 看此桌上的人数是不是为0 没人的话桌面状态初始化

if (begit->GetUserCount() == 0)

{

begit->TableState(GAME_NULL);

}

return TRUE;

}

}

 

}

return FALSE;

}

 

BOOL CTableList::SetUserState(int UID, int nState)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nState = nState;

return TRUE;

}

}

}

return TRUE;

}

 

BOOL CTableList::AddTable(CTable &table)

{

m_vecTable.push_back(table);

return TRUE;

}

 

BOOL CTableList::DelTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

m_vecTable.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

 

CTable * CTableList::GetTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit;

}

}

return NULL;

}

 

int CTableList::Pack(char *pData)

{

COutStream cos;

cos.Create();

int dataSize = 0;

cos << dataSize;

int tableCount = m_vecTable.size();

cos << tableCount;

for (int i = 0; i < tableCount; i++)

{

char buf[512] ={0};

int len = m_vecTable[i].Pack(buf);

cos.Write(buf, len);

}

 

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

 

return dataSize + sizeof(int);

}

 

int CTableList::UnPack(const char *pData)

{

m_vecTable.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

int tableCount = 0;

cis >> tableCount;

for (int i = 0; i < tableCount; i++)

{

CTable table;

const char *p = (const char *)cis.GetCurPtr();

int len = table.UnPack(p);

m_vecTable.push_back(table);

cis.MoveCurPtr(len);

}

return cis.GetSize();

}

 

int CTableList::GetTableCount()

{

return m_vecTable.size();

}

 

BOOL CTableList::HasUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

return TRUE;

}

}

}

return FALSE;

}

 

 

// TableMan.cpp: implementation of the CTableMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableMan::CTableMan()

{

}

 

CTableMan::~CTableMan()

{

}

 

BOOL CTableMan::AddTable(CTable &table)

{

return m_tablelist.AddTable(table);

}

 

BOOL CTableMan::DelTable(int nTableID)

{

return m_tablelist.DelTable(nTableID);

}

 

BOOL CTableMan::AddUser(int UID, int nTableID, int nSeatID)

{

return m_tablelist.AddUser(UID, nTableID, nSeatID);

}

 

BOOL CTableMan::DelUser(int UID)

{

return m_tablelist.DelUser(UID);

}

 

BOOL CTableMan::SetUserState(int UID, int nState)

{

return m_tablelist.SetUserState(UID, nState);

}

 

int CTableMan::Pack(char *pData)

{

return m_tablelist.Pack(pData);

}

 

int CTableMan::UnPack(const char *pData)

{

return m_tablelist.UnPack(pData);

}

 

CTable * CTableMan::GetTable(int nTableID)

{

return m_tablelist.GetTable(nTableID);

}

 

int CTableMan::GetTableCount()

{

return m_tablelist.GetTableCount();

}

 

BOOL CTableMan::HasUser(int UID)

{

return m_tablelist.HasUser(UID);

}

 

BOOL CTableMan::StartGame( int nTableID /*= 1*/ )

{

CTable * pTable = GetTable(nTableID);

pTable->StartGame();

return TRUE;

}

 

BOOL CTableMan::EndGame( int nTableID /*= 1*/ )

{

CTable * pTable = GetTable(nTableID);

pTable->EndGame();

return TRUE;

}

 

 

 

/*/////////////////////////////////////////////////////////////////////////

说明:UCode 文件,一些简单常用功能函数合集。

版本:1.0

创建:[4/5/2009 Dufeng]

修改:

*///////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 预处理

 

#include "StdAfx.h"

#include "UCode.h"

#include <windows.h>

#include <stdio.h>

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 宏定义

//#define BUFFER_SIZE 256

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:OnlyRunOne,只允许运行一个实例。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:TURE为可运行,FALSE为已经在运行

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

BOOL OnlyRunOne(WCHAR *_mutexName)

{

CreateMutexW(NULL, FALSE, _mutexName);

 

if (GetLastError() == ERROR_ALREADY_EXISTS)

{

return FALSE;

}

else

{

return TRUE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,获取上次的错误信息,会自动格式化信息内容。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

 

VOID GetLastErrorMsg(TCHAR *szBuf)

{

LPVOID lpMsgBuf;

DWORD dw = GetLastError();

 

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

  NULL,

  dw,

  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

  (LPTSTR) & lpMsgBuf,

  0,

  NULL);

 

sprintf(szBuf, "错误 %d: %s", dw, lpMsgBuf);

 

LocalFree(lpMsgBuf);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,检测键盘状态。

// 版本:1.0

// 创建:[4/6/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

 

BOOL GetOneKeyState(BYTE _key)

{

BYTE keyState[256];

 

GetKeyboardState((LPBYTE) & keyState);

return (keyState[_key] & 1);

}

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的的路径 不包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppPath(char *szFilePath)

{

char szTempFilePath[BUFFER_SIZE] ={0};

GetModuleFileName(NULL, szTempFilePath, BUFFER_SIZE - 1);

size_t nTemp = strlen(szTempFilePath) -

  strlen(strrchr(szTempFilePath, '\\'));

if (nTemp != -1)

{

szTempFilePath[nTemp + 1] = 0;

}

strcpy(szFilePath, szTempFilePath);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的全路径 包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppFileFullPathName(char *szFileName)

{

GetModuleFileName(NULL, szFileName, BUFFER_SIZE - 1);

}

//////////////////////////////////////////////////////////////////////////

 

 

// User.cpp: implementation of the CUser class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "User.h"

 

#include <winsock2.h>

#include "../Basic/OutStream.h"

#include "../Basic/InStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

int CUser::MAX_PACK_SIZE = sizeof(int) * 10 +

  sizeof(sockaddr) +

  100;

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUser::CUser()

{

m_nID = 0;

m_szName.Empty();

m_szNickname.Empty();

m_szPassword.Empty();

m_nSex = SEX_BAOMI;

m_szBirthday.Empty();

m_szPhone.Empty();

m_nState = STATE_OFFLINE;

m_nFaceID = 0;

// 在线状态的信息

ZeroMemory(&m_addr, sizeof(sockaddr));

m_nGameState = GAME_STATE_NOTHING;

m_nRoomID = 0;

m_nTableID = 0;

m_nSeatID = 0;

 

m_nLLKScore = 0;

}

 

CUser::~CUser()

{

}

 

//////////////////////////////////////////////////////////////////////////

// 用户信息打包

// 参数:pData 存放用户打包信息的地址

// 返回:包的大小

int CUser::Pack(char *pData)

{

// 申请buf

COutStream cos;

cos.Create(MAX_PACK_SIZE);

int dataSize = 0;

// 先写大小 为0 最后修改

cos << dataSize;

// 再写数据

cos << m_nID << m_szName << m_szNickname << m_szPassword << m_nSex

<< m_szBirthday << m_nState << m_nFaceID;

cos.Write(&m_addr, sizeof(sockaddr));

cos << m_nGameState << m_nRoomID << m_nTableID << m_nSeatID << m_nLLKScore;

 

int packSize = cos.GetSize();

// 写入长度

*(int *) cos.GetHead() = packSize - sizeof(int);

 

// 向缓冲写入

cos.CopyTo(pData);

return packSize;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 解包

// 参数:pData 包数据的地址 DataSize 包数据的大小

// 返回:读取包的长度 包括长度变量

int CUser::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int DataSize = 0;

cis >> DataSize;

cis >> m_nID >> m_szName >> m_szNickname >> m_szPassword >> m_nSex

>> m_szBirthday >> m_nState >> m_nFaceID;

cis.Read(&m_addr, sizeof(sockaddr));

cis >> m_nGameState >> m_nRoomID >> m_nTableID >> m_nSeatID >> m_nLLKScore;

 

return DataSize + sizeof(int);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到打包后数据的大小

int CUser::GetPackSize()

{

return sizeof(int) + GetDataSize();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到数据大小

int CUser::GetDataSize()

{

// 先计算数据的大小

int dataSize = 0;

dataSize += sizeof(int); // m_nID

dataSize += sizeof(int) + m_szName.GetLength() + 1;

dataSize += sizeof(int) + m_szNickname.GetLength() + 1;

dataSize += sizeof(int) + m_szPassword.GetLength() + 1;

dataSize += sizeof(int); //m_nSex

dataSize += sizeof(int) + m_szBirthday.GetLength() + 1;

dataSize += sizeof(int) + m_szPhone.GetLength() + 1;

dataSize += sizeof(int); //m_nState;

dataSize += sizeof(int); //m_nFaceID;

 

// 在线状态的信息

dataSize += sizeof(sockaddr); //m_addr;

dataSize += sizeof(int); //m_nGameState;

dataSize += sizeof(int); //m_nRoomID;

dataSize += sizeof(int); //m_nTableID;

dataSize += sizeof(int); //m_nSeatID;

 

//以下是模拟打包返回长度 效率问题不使用

/*

COutStream cos;

cos.Create(1024);

cos << m_nID << m_szName << m_szNickname << m_szPassword << m_nSex

<< m_szBirthday << m_nState << m_nFaceID;

cos.Write(&m_addr, sizeof(sockaddr));

cos << m_nGameState << m_nRoomID << m_nTableID << m_nSeatID;

return cos.GetSize();

 

*/

return dataSize;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 地址的对比函数

// 参数:要比较的两个地址指针

// 返回:同则返回TRUE

BOOL CUser::AddrCmp(const sockaddr *addr1, const sockaddr *addr2)

{

for (int i = 0; i < sizeof(sockaddr); i++)

{

if (*((char *) (addr1) + i) != *((char *) (addr2) + i))

{

return FALSE;

}

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

// UserIDList.cpp: implementation of the CUserIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserIDList.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserIDList::CUserIDList()

{

}

 

CUserIDList::~CUserIDList()

{

}

 

BOOL CUserIDList::AddUser(int UID)

{

VEC_USERID::iterator begit = m_vecUserID.begin();

VEC_USERID::iterator endit = m_vecUserID.end();

 

for (; begit != endit; ++begit)

{

if (*begit == UID)

{

return FALSE;

}

}

m_vecUserID.push_back(UID);

return TRUE;

}

 

BOOL CUserIDList::DelUser(int UID)

{

VEC_USERID::iterator begit = m_vecUserID.begin();

VEC_USERID::iterator endit = m_vecUserID.end();

 

for (; begit != endit; ++begit)

{

if (*begit == UID)

{

m_vecUserID.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

CUser * CUserIDList::GetUser(int index, CUserMan *pUserMan)

{

return pUserMan->GetUser(m_vecUserID[index]);

}

 

 

// UserList.cpp: implementation of the CUserList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserList.h"

#include "../Basic/OutStream.h"

#include "../Basic/InStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserList::CUserList()

{

}

 

CUserList::~CUserList()

{

}

 

BOOL CUserList::AddUser(CUser &user)

{

MAP_USER::_Pairib ret = m_mapUser.insert(MAP_USER::value_type(user.m_nID,

user));

if (ret.second == true)

{

return TRUE;

}

else

{

return FALSE;

}

}

 

BOOL CUserList::DelUser(int UID)

{

int ret = m_mapUser.erase(UID);

if (ret == 1)

{

return TRUE;

}

else

{

return FALSE;

}

}

 

CUser * CUserList::GetUser(int UID)

{

MAP_USER::iterator itRet = m_mapUser.find(UID);

if (itRet == m_mapUser.end())

{

return NULL;

}

else

{

return &itRet->second;

}

}

 

 

CUser * CUserList::GetUserByIndex(int index)

{

if (index < 0 || index >= GetUserCount())

{

return NULL;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

int i = 0;

for (; begiter != enditer; ++begiter)

{

if (i == index)

{

return &begiter->second;

}

i++;

}

 

return NULL;

}

 

int CUserList::GetUserIDByAddr(const sockaddr &addr)

{

MAP_USER::iterator it;

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

if (CUser::AddrCmp(&addr, &it->second.m_addr))

{

return it->first;

}

}

return 0;

}

 

BOOL CUserList::HasUser(int UID)

{

CUser *pUser = GetUser(UID);

if (pUser == NULL)

{

return FALSE;

}

else

{

return TRUE;

}

}

 

int CUserList::GetUserCount()

{

return m_mapUser.size();

}

 

void CUserList::Empty()

{

m_mapUser.clear();

}

 

int CUserList::Pack(char *pData)

{

int userCount = GetUserCount();

COutStream cos;

cos.Create(CUser::MAX_PACK_SIZE * userCount);

int dataSize = 0;

cos << dataSize;

cos << userCount;

 

MAP_USER::iterator it;

char *buf = new char[CUser::MAX_PACK_SIZE];

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

//清空缓冲

ZeroMemory(buf, CUser::MAX_PACK_SIZE);

//打包函数已经把大小写入了 所以无需再写长度了

int len = it->second.Pack(buf);

cos.Write(buf, len);

}

cos.CopyTo(pData);

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

delete[] buf;

return dataSize + sizeof(int) ;

}

 

int CUserList::UnPack(const char *pData)

{

if (pData == NULL)

{

return 0;

}

CInStream cis;

cis.Create(pData);

int DataSize = 0;

cis >> DataSize;

Empty();

 

int userCount = 0;

cis >> userCount;

int packSize = 0;

for (int i = 0; i < userCount; i++)

{

CUser user;

packSize = user.UnPack(cis.GetCurPtr());

cis.MoveCurPtr(packSize);

m_mapUser.insert(MAP_USER::value_type(user.m_nID, user));

}

 

return cis.GetSize();

}

 

int CUserList::GetPackSize()

{

return GetDataSize() + sizeof(int);

}

 

int CUserList::GetDataSize()

{

int DataSize = 0;

DataSize += sizeof(int); //用户个数存放

 

MAP_USER::iterator it;

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

DataSize += it->second.GetPackSize(); //数据包大小 已包含数据大小

}

return DataSize;

}

 

CUser * CUserList::GetUserByAddr( const sockaddr &addr )

{

if (GetUserCount() == 0)

{

return NULL;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

for (; begiter != enditer; ++begiter)

{

if (CUser::AddrCmp(&begiter->second.m_addr, &addr))

{

return &begiter->second;

}

}

 

return NULL;

}

 

void CUserList::AddScore( int UID, int score )

{

if (GetUserCount() == 0)

{

return ;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

for (; begiter != enditer; ++begiter)

{

if (begiter->second.m_nID == UID)

{

begiter->second.m_nLLKScore+=score;

}

}

 

return ;

}

 

 

// UserMan.cpp: implementation of the CUserMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserMan::CUserMan()

{

}

 

CUserMan::~CUserMan()

{

}

 

BOOL CUserMan::AddUser( CUser &user )

{

return m_userlist.AddUser(user);

}

 

BOOL CUserMan::HasUser(int UID)

{

return m_userlist.HasUser(UID);

}

 

BOOL CUserMan::DelUser(int UID)

{

return m_userlist.DelUser(UID);

}

 

BOOL CUserMan::SetUserState(int UID, int state)

{

CUser *pUser = m_userlist.GetUser(UID);

if (pUser == NULL)

{

return FALSE;

}

else

{

pUser->State(state);

}

return TRUE;

}

 

CUser * CUserMan::GetUser(int UID)

{

return m_userlist.GetUser(UID);

}

 

int CUserMan::GetUserID(const sockaddr &addr)

{

return m_userlist.GetUserIDByAddr(addr);

}

 

CUserList CUserMan::GetUserList(int mode /*= 0*/, WPARAM wParam /*= 0*/)

{

return m_userlist;

}

 

BOOL CUserMan::AddUserIDList(CUserIDList *pUserIDList)

{

SET_CUSERIDLIST::_Pairib retPair = m_setUserIDList.insert(SET_CUSERIDLIST::value_type(pUserIDList));

if (retPair.second == false)

{

return FALSE;

}

else

{

return TRUE;

}

}

 

void CUserMan::DelUserIDList(CUserIDList *pUserIDList)

{

SET_CUSERIDLIST::iterator begit = m_setUserIDList.begin();

SET_CUSERIDLIST::iterator endit = m_setUserIDList.end();

 

for (; begit != endit; ++begit)

{

if (*begit == pUserIDList)

{

m_setUserIDList.erase(begit);

break;

}

}

}

 

int CUserMan::Pack(char *pData)

{

return m_userlist.Pack(pData);

}

 

int CUserMan::UnPack(const char *pData)

{

return m_userlist.UnPack(pData);

}

 

int CUserMan::GetUserCount()

{

return m_userlist.GetUserCount();

}

 

// sockaddr CUserMan::GetUserAddr(int UID)

// {

// return m_userlist.GetUser(UID)->Addr();

// }

 

CUser * CUserMan::GetUserByIndex(int index)

{

return m_userlist.GetUserByIndex(index);

}

 

CUser * CUserMan::GetUserByAddr( const sockaddr &addr )

{

return m_userlist.GetUserByAddr(addr);

}

 

void CUserMan::AddScore( int UID, int score )

{

m_userlist.AddScore(UID, score);

}

 

 

 

// DataLayer.h: interface for the CDataLayer class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_DATALAYER_H__B9EEDD30_EA68_433E_AD79_78690B0E1DA8__INCLUDED_)

#define AFX_DATALAYER_H__B9EEDD30_EA68_433E_AD79_78690B0E1DA8__INCLUDED_

 

#include "StdAfx.h"

#include "../Common/ServerDefine.h"

#include "../Common/ScoreList.h"

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

extern char *USER_STATE_TEXT[];

// 数据层类

class CDataLayer

{

public:

CDataLayer();

virtual ~CDataLayer();

// 基本通用操作

BOOL Create(); //初始化

BOOL ConnectDB(CString szDBFileName); //连接数据库

void EasyExcute(CString sql, CAdoRecordSet &adoSet); //执行SQL语句

 

// 业务操作

INT Login(const LOGIN_INFO &loginInfo); //登陆之数据库操作

int Reg(const CUser &user); //注册之数据库操作

 

// 辅助函数

void SetUserState(int userId, int state); //设置某用户的状态

void SetUserState(char userIdString[], int state);

 

void SetAllUserOffline(); //让所有用户离线

BOOL GetUser(int UID, CUser &user);

 

void NewScore(int UID, int initScore, int GameID = 1000);

int GetScore(int UID, int GameID = 1000);

void SetScore(int UID, int score, int GameID = 1000);

void AddScore(int UID, int score, int GameID = 1000);

CScoreList GetTop10Score();

 

private:

BOOL GetOneUser(CAdoRecordSet &adoSet, CUser &user); //得到一个用户信息

VOID GetVTValue(const _variant_t &vt, void *value); //方便得到_variant_t的数据

int GetMaxUserID(); //得到当前最大用户ID

 

private:

CAdoConnection m_adoCon;

CAdoRecordSet m_adoSet;

};

 

#endif // !defined(AFX_DATALAYER_H__B9EEDD30_EA68_433E_AD79_78690B0E1DA8__INCLUDED_)

 

 

// Game.h: interface for the CGame class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_GAME_H__2156043B_DDE0_4B94_8291_2C8C2396DF63__INCLUDED_)

#define AFX_GAME_H__2156043B_DDE0_4B94_8291_2C8C2396DF63__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CGame

{

public:

CGame();

virtual ~CGame();

};

 

#endif // !defined(AFX_GAME_H__2156043B_DDE0_4B94_8291_2C8C2396DF63__INCLUDED_)

 

 

// GameMan.h: interface for the CGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_GAMEMAN_H__92B4DE1C_A491_4CFB_B156_02C5A80A6AC0__INCLUDED_)

#define AFX_GAMEMAN_H__92B4DE1C_A491_4CFB_B156_02C5A80A6AC0__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

// #define GAME_STATE_NULL 0

// #define GAME_STATE_READY 1

// #define GAME_STATE_PLAYING 2

 

class CGameMan

{

public:

CGameMan();

virtual ~CGameMan();

};

 

#endif // !defined(AFX_GAMEMAN_H__92B4DE1C_A491_4CFB_B156_02C5A80A6AC0__INCLUDED_)

 

 

// LLKGameMan.h: interface for the CLLKGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_LLKGAMEMAN_H__F6E46830_2429_4016_913A_8EC2CB188689__INCLUDED_)

#define AFX_LLKGAMEMAN_H__F6E46830_2429_4016_913A_8EC2CB188689__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "GameMan.h"

#include "CLLK.h"

#include "ScoreList.h"

 

#define GAME_NULL 0

#define GAME_READY 1

#define GAME_PLAYING 2

#define GAME_END

 

#define CHECK_GAME_RET

#define CGR_NULL 0

#define CGR_TOBEGIN 1

#define CGR_TOEND 2

 

#define MINI_USER_TO_PLAY 2

class CLLKGameMan : public CGameMan

{

public:

CLLKGameMan();

virtual ~CLLKGameMan();

// 序列化函数

int Pack(char *pData);

int UnPack(const void *pData);

 

// 用户管理

BOOL AddUser(int UID, char *nickName, int score, int tid, int sid);

BOOL DelUser(int UID);

 

int GetUserCount();

int GetReadyUserCount();

 

BOOL StartGame(int nGameID = 1);

CScoreList EndGame(int nGameID = 1);

 

void InitGame();

int CheckGame();

int CalcScore(CScoreList &sl);

 

void SetUserState(int UID, int state);

public:

int m_state;

int m_UID[6];

char m_NickName[6][11];

int m_Score[6];

int m_userState[6];

CLLK m_llk[6];

};

 

#endif // !defined(AFX_LLKGAMEMAN_H__F6E46830_2429_4016_913A_8EC2CB188689__INCLUDED_)

 

 

// MyIOCP.h: interface for the CMyIOCP class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_MYIOCP_H__1DAE986D_4BA4_4097_AE63_C3D123C2935F__INCLUDED_)

#define AFX_MYIOCP_H__1DAE986D_4BA4_4097_AE63_C3D123C2935F__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "StdAfx.h"

#include "DataLayer.h"

#include "../Common/TableMan.h"

#include "../Common/LLKGameMan.h"

 

class CMyIOCP : public CIOCP

{

public:

CMyIOCP();

virtual ~CMyIOCP();

// IOCP框架处理

void OnRecvFrom(IO_DATA *pIOData); //重载RecvFrom的处理

void OnError(int err, IO_DATA *pIOData); //错误处理

int EasySentPacTo(CPacket &pac, SOCKET s, const sockaddr &addr); //方便的发送一个包

int EasySentTo(int nType,

   int dataSize,

   void *pData,

   SOCKET s,

   const sockaddr &addr); //方便的发送一条信息 自动打包

 

// 业务逻辑 响应函数

void DoLogin(IO_DATA *pIOData); //登录

void DoReg(IO_DATA *pIOData); //注册

void DoSeatDown(IO_DATA *pIOData); //坐下

void DoLookOn(IO_DATA *pIOData); //旁观

void DoExit(IO_DATA *pIOData); //退出

 

void DoGetLoginUserInfo(IO_DATA *pIOData); //用户登陆后获取用户信息

void DoStandUp(IO_DATA *pIOData); //离开座位

void DoCheckOnline(IO_DATA *pIOData); //进行在线检测

 

void DoSendGameInfo(IO_DATA *pIOData); //客户发送自己的游戏信息

void DoGetGameInfo(IO_DATA *pIOData); //客户请求游戏信息

 

void DoGetScoreTop10(IO_DATA *pIOData); //客户请求积分TOP10

 

void DoGameReady(IO_DATA *pIOData); //客户准备

 

void DoStartGame(IO_DATA *pIOData);

void DoEndGame(IO_DATA *pIOData);

void DoCheckGame(IO_DATA *pIOData);

 

 

// 执行函数

void CheckOnline(SOCKET sock); //检测在线状态 将不在线的用户从ID中删除

void SendPacToAllUser(SOCKET sock, CPacket &pac); //发送某个数据包到所有用户

void SendTableInfo(IO_DATA *pIOData); //发送桌子信息

void SendTableInfo(SOCKET sock, sockaddr &addr);

void SendTableInfoToAllRoomUser(SOCKET sock);

void SendLLKGameInfoToAllTableUser(SOCKET sock);

 

void SendUserInfoToClient(int UID, SOCKET sock);

 

// 其它功能

CUserList GetOnlineUser(); //得到在线用户

void SendUserList(IO_DATA *pIOData);

void SendUserList(SOCKET sock, sockaddr &addr);

void SendUserListToAllRoomUser(SOCKET sock);

public:

CUserMan m_userMan;

CTableMan m_tableMan;

CLLKGameMan m_llkGameMan;

};

 

#endif // !defined(AFX_MYIOCP_H__1DAE986D_4BA4_4097_AE63_C3D123C2935F__INCLUDED_)

 

 

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by Server.rc

//

#define IDM_ABOUTBOX 0x0010

#define IDD_ABOUTBOX 100

#define IDS_ABOUTBOX 101

#define IDD_SERVER_DIALOG    102

#define IDP_SOCKETS_INIT_FAILED 103

#define IDR_MAINFRAME    128

#define IDC_BTN_START    1000

#define IDC_BTN_STOP 1001

#define IDC_BTN_REFRESH_ONLINE_USER 1002

#define IDC_CHECK_AUTO_REFREASH 1003

#define IDC_LIST_ONLINE_USER 1004

#define IDC_BTN_TEST 1005

#define IDC_BTN_CHECK_ONLINE 1006

#define IDC_CHECK_AUTO_CHECK_ONLINE 1007

#define IDC_EDIT_CHECT_TIMEOUT   1008

 

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE 130

#define _APS_NEXT_COMMAND_VALUE 32771

#define _APS_NEXT_CONTROL_VALUE 1009

#define _APS_NEXT_SYMED_VALUE    101

#endif

#endif

 

 

// Room.h: interface for the CRoom class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_ROOM_H__AA23E442_C8AF_4D89_A280_C576C7137014__INCLUDED_)

#define AFX_ROOM_H__AA23E442_C8AF_4D89_A280_C576C7137014__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CRoom

{

public:

CRoom();

virtual ~CRoom();

BOOL AddUser(int UID);

BOOL DelUser(int UID);

 

private:

int m_nID;

int m_nGameID;

};

 

#endif // !defined(AFX_ROOM_H__AA23E442_C8AF_4D89_A280_C576C7137014__INCLUDED_)

 

 

// RoomList.h: interface for the CRoomList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_ROOMLIST_H__723A5C9B_F1A8_4109_BAD5_94733038166C__INCLUDED_)

#define AFX_ROOMLIST_H__723A5C9B_F1A8_4109_BAD5_94733038166C__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CRoomList

{

public:

CRoomList();

virtual ~CRoomList();

};

 

#endif // !defined(AFX_ROOMLIST_H__723A5C9B_F1A8_4109_BAD5_94733038166C__INCLUDED_)

 

 

// RoomMan.h: interface for the CRoomMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_ROOMMAN_H__3FEFB6D8_B7DC_4B7E_AD0A_8EE5CD2CF164__INCLUDED_)

#define AFX_ROOMMAN_H__3FEFB6D8_B7DC_4B7E_AD0A_8EE5CD2CF164__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CRoomMan

{

public:

CRoomMan();

virtual ~CRoomMan();

};

 

#endif // !defined(AFX_ROOMMAN_H__3FEFB6D8_B7DC_4B7E_AD0A_8EE5CD2CF164__INCLUDED_)

 

 

// ScoreList.h: interface for the CScoreList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_SCORELIST_H__4F23F332_9606_412C_AA2A_18EF83BF75A7__INCLUDED_)

#define AFX_SCORELIST_H__4F23F332_9606_412C_AA2A_18EF83BF75A7__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <vector>

using namespace std;

 

typedef struct _SCORE_INFO

{

int UID;

int GameID;

char NickName[11];

int Score;

}SCORE_INFO;

 

typedef vector<SCORE_INFO> VEC_SCORE_INFO;

 

class CScoreList  

{

public:

CScoreList();

virtual ~CScoreList();

 

int Pack(void * pData);

int UnPack(const void * pData);

 

void Add(SCORE_INFO& scoreInfo);

BOOL Del(int uid, int gid);

 

int GetCount();

SCORE_INFO &GetScoreByIndex(int index);

 

void Sort(int mode = 0);

 

private:

VEC_SCORE_INFO m_vecScore;

 

};

 

#endif // !defined(AFX_SCORELIST_H__4F23F332_9606_412C_AA2A_18EF83BF75A7__INCLUDED_)

 

 

// Server.h : main header file for the SERVER application

//

 

#if !defined(AFX_SERVER_H__1AE6C299_3D93_4ACA_9E09_968049BC0E28__INCLUDED_)

#define AFX_SERVER_H__1AE6C299_3D93_4ACA_9E09_968049BC0E28__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#ifndef __AFXWIN_H__

#error include 'stdafx.h' before including this file for PCH

#endif

 

#include "resource.h" // main symbols

#include "DataLayer.h"

 

extern CDataLayer g_dataLayer;

 

/////////////////////////////////////////////////////////////////////////////

// CServerApp:

// See Server.cpp for the implementation of this class

//

 

class CServerApp : public CWinApp

{

public:

CServerApp();

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CServerApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

 

// Implementation

 

//{{AFX_MSG(CServerApp)

// NOTE - the ClassWizard will add and remove member functions here.

//    DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_SERVER_H__1AE6C299_3D93_4ACA_9E09_968049BC0E28__INCLUDED_)

 

 

#ifndef __SERVER_DEFINE_H_

#define __SERVER_DEFINE_H_

 

 

// 自定义协议类型定义

#define PTCS_NULL 0

#define PTC_LOGIN_ENTER 1

#define PTS_LOGIN_SUCC 2

#define PTS_LOGIN_FAIL 3

#define PTC_REG_ENTER 4

#define PTS_REG_SUCC 5

#define PTS_REG_FAIL 6

#define PTCS_CHECK_ONLINE 7

#define PTCS_GET_LOGIN_USER_INFO 8

 

#define PTC_SEAT_DOWN 9

#define PTS_SEAT_DOWN_SUCC 10

#define PTS_SEAT_DOWN_FAIL 11

 

#define PTC_LOOK_ON 12

#define PTS_LOOK_ON_SUCC 13

#define PTS_LOOK_ON_FAIL 14

 

#define PTCS_GET_TABLE_INFO 15

 

#define PTCS_EXIT 17

#define PTC_STAND_UP 18

 

#define PTCS_GET_USER_LIST 19

#define PTCS_GET_SCORE_TOP10 20

 

#define PTCS_GET_GAMEINFO 51

#define PTC_SEND_GAMEINFO 52

 

#define PTS_GAME_BEGIN 53

#define PTS_GAME_END 54

 

#define PTC_GAME_READY 55

 

//游戏与客户端通信代码

#define PTCS_GET_HWND 100

#define PTS_SHOW_WINDOW 101

 

//////////////////////////////////////////////////////////////////////////

// 错误码定义

#define EC_LOGIN_FAIL_NULL 1

#define EC_LOGIN_USER_NOT_EXIST 2

#define EC_LOGIN_PASS_ERROR 3

#define EC_LOGIN_USER_LOGINED 4

#define EC_REG_FAIL_NULL 5

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 登录信息

typedef struct _LOGIN_INFO

{

char userid[11];

char password[11];

}LOGIN_INFO;

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 客户端配置信息

typedef struct _CLIENT_SETTING

{

CString m_szServerIP;

UINT m_nServerPort;

}CLIENT_SETTING;

//////////////////////////////////////////////////////////////////////////

 

 

#endif //__SERVER_DEFINE_H_

 

 

// ServerDlg.h : header file

//

 

#if !defined(AFX_SERVERDLG_H__76802E18_F3E6_4CF6_B219_9AE09661AC02__INCLUDED_)

#define AFX_SERVERDLG_H__76802E18_F3E6_4CF6_B219_9AE09661AC02__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "MyIOCP.h"

#include "../Basic/Ado.h"

#include "DataLayer.h"

/////////////////////////////////////////////////////////////////////////////

// CServerDlg dialog

 

class CServerDlg : public CDialog

{

// Construction

public:

CServerDlg(CWnd *pParent = NULL); // standard constructor

 

// Dialog Data

//{{AFX_DATA(CServerDlg)

enum { IDD = IDD_SERVER_DIALOG };

CListCtrl m_listOnlineUser;

BOOL m_bAutoRefresh;

BOOL m_bCheckOnline;

UINT m_nChectOlineTimeOut;

//}}AFX_DATA

 

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CServerDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

HICON m_hIcon;

CMyIOCP m_iocp;

SOCKET m_sockServer;

BOOL m_bServerState;

// Generated message map functions

//{{AFX_MSG(CServerDlg)

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

afx_msg void OnBtnStart();

afx_msg void OnBtnStop();

afx_msg void OnBtnRefreshOnlineUser();

afx_msg void OnCheckAutoRefreash();

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnBtnTest();

afx_msg void OnBtnCheckOnline();

afx_msg void OnCheckAutoCheckOnline();

afx_msg LRESULT OnGetDefID( WPARAM wParam, LPARAM lParam );

 

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_SERVERDLG_H__76802E18_F3E6_4CF6_B219_9AE09661AC02__INCLUDED_)

 

 

// stdafx.h : include file for standard system include files,

//  or project specific include files that are used frequently, but

//   are changed infrequently

//

 

#if !defined(AFX_STDAFX_H__896312A9_5F86_46CE_AA19_5477A91513F2__INCLUDED_)

#define AFX_STDAFX_H__896312A9_5F86_46CE_AA19_5477A91513F2__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#pragma warning(disable:4146)

 

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

 

#include <afxwin.h> // MFC core and standard components

#include <afxext.h> // MFC extensions

#include <afxdisp.h> // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h> // MFC support for Windows Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

 

 

#include "../Basic/Ado.h"

#include "../Basic/IOCP.h"

#include "../Basic/MySocket.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#include "../Common/Packet.h"

#include "../Common/UserMan.h"

#include "DataLayer.h"

#include "../Common/ServerDefine.h"

#include "../Basic/UCode.h"

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_STDAFX_H__896312A9_5F86_46CE_AA19_5477A91513F2__INCLUDED_)

 

 

// Table.h: interface for the CTable class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLE_H__646A2362_1C47_41A3_91C4_751748CAB369__INCLUDED_)

#define AFX_TABLE_H__646A2362_1C47_41A3_91C4_751748CAB369__INCLUDED_

 

#include "UserIDList.h"

#include "Packet.h"

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

//#define TABLE_STATE_NOTHING 0

//#define TABLE_STATE_PLAYING 1

 

class CSeat

{

public:

CSeat();

void Creat(int nTableID, int nSeatID);

int m_nSeatID;

int m_nTableID;

int m_nUID;

int m_nState;

};

class CTable

{

public:

CTable();

virtual ~CTable();

 

//创建

VOID Create(int nTableID, int nSeatCount = 6);

 

//用户管理

BOOL AddUser(int UID, int SeatID);

BOOL DelUser(int UID);

 

//序列化函数

int Pack(char *pData);

int UnPack(const char *pData);

 

CSeat &GetSeat(int SeatID);

 

int GetUserCount();

 

BOOL StartGame();

BOOL EndGame();

 

public: //属性访问

int TableID() const

{

return m_nTableID;

}

void TableID(int val)

{

m_nTableID = val;

}

int TableState() const

{

return m_nTableState;

}

void TableState(int val)

{

m_nTableState = val;

}

 

private:

int m_nTableID;

int m_nTableState;

CSeat m_seat[6];

};

 

#endif // !defined(AFX_TABLE_H__646A2362_1C47_41A3_91C4_751748CAB369__INCLUDED_)

 

 

// TableIDList.h: interface for the CTableIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_)

#define AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CTableIDList

{

public:

CTableIDList();

virtual ~CTableIDList();

};

 

#endif // !defined(AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_)

 

 

// TableList.h: interface for the CTableList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLELIST_H__D5FA7A29_967D_43F3_B8AE_583B6C249177__INCLUDED_)

#define AFX_TABLELIST_H__D5FA7A29_967D_43F3_B8AE_583B6C249177__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Table.h"

#include <vector>

using namespace std;

 

typedef vector<CTable> VEC_TABLE;

class CTableList

{

public:

CTableList();

virtual ~CTableList();

BOOL AddTable(CTable &table);

BOOL DelTable(int nTableID);

 

BOOL AddUser(int UID, int nTableID, int nSeatID);

BOOL DelUser(int UID);

BOOL SetUserState(int UID, int nState);

 

BOOL HasUser(int UID);

 

CTable *GetTable(int nTableID);

int GetTableCount();

 

int Pack(char *pData);

int UnPack(const char *pData);

private:

VEC_TABLE m_vecTable;

};

 

#endif // !defined(AFX_TABLELIST_H__D5FA7A29_967D_43F3_B8AE_583B6C249177__INCLUDED_)

 

 

// TableMan.h: interface for the CTableMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLEMAN_H__6E3AD82B_25ED_4A8A_B02E_F05369FAF24D__INCLUDED_)

#define AFX_TABLEMAN_H__6E3AD82B_25ED_4A8A_B02E_F05369FAF24D__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "TableList.h"

 

class CTableMan

{

public:

CTableMan();

virtual ~CTableMan();

BOOL AddTable(CTable &table);

BOOL DelTable(int nTableID);

 

BOOL AddUser(int UID, int nTableID, int nSeatID);

BOOL DelUser(int UID);

 

BOOL HasUser(int UID);

 

BOOL SetUserState(int UID, int nState);

BOOL StartGame(int nTableID = 1);

BOOL EndGame(int nTableID = 1);

 

CTable *GetTable(int nTableID);

int GetTableCount();

int Pack(char *pData);

int UnPack(const char *pData);

public:

CTableList m_tablelist;

};

 

#endif // !defined(AFX_TABLEMAN_H__6E3AD82B_25ED_4A8A_B02E_F05369FAF24D__INCLUDED_)

 

 

 

/*/////////////////////////////////////////////////////////////////////////

说明:UCode 文件,一些简单常用功能函数合集。

版本:1.0

创建:[4/5/2009 Dufeng]

修改:

*///////////////////////////////////////////////////////////////////////////

 

#ifndef __U_CODE_H_

#define __U_CODE_H_

 

//////////////////////////////////////////////////////////////////////////

// 预处理

#include <windows.h>

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 宏定义

#define BUFFER_SIZE 256

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

/*

0x8000二进制值是1000000000000000,两者进行与运算

即如果GetAsyncKeyState(vk_code)最高位是1,则取值1,

即此时KEYDOWN   后者正好相反

函数GetAsyncKeyState确定在调用它时某个按键处于弹起还是按下的,以及此按键是否在上一次调用GetAsyncKeyState之后(“又”)按下过(重复也算按下)。

这句话的完整意思是:预定义了一个KEYDOWN参数为vk_code 他的定义的含义是判断一个键是否被按下(GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0如果按下了就是1,没有按下就是0

然后其它地方用的时候直接用KEYDOWN(vk_code)判断这个键是否按下,相反弹起来是1按下是0

*/

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 只允许运行一个实例。

BOOL OnlyRunOne(WCHAR *_mutexName);

 

// 获取上次的错误信息,会自动格式化信息内容。

VOID GetLastErrorMsg(CHAR *szBuf);

 

// 获取某个键的状态

BOOL GetOneKeyState(BYTE _key);

 

// 获取程序的路径

void GetAppPath(char *szFilePath);

 

// 获取程序文件名

void GetAppFileFullPathName(char *szFileName);

//////////////////////////////////////////////////////////////////////////

 

#endif //__U_CODE_H_

 

 

// User.h: interface for the CUser class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USER_H__49D2C842_4BDA_42CB_8E66_562823E19F5A__INCLUDED_)

#define AFX_USER_H__49D2C842_4BDA_42CB_8E66_562823E19F5A__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <WINSOCK2.H>

class CUser

{

public:

static  int MAX_PACK_SIZE;

public:

enum

{

SEX_BAOMI = 0,

SEX_MALE = 1,

SEX_FAMALE = 2

};

enum

{

STATE_OFFLINE = 0,

STATE_ONLINE = 1

};

enum

{

GAME_STATE_NOTHING = 0,

GAME_STATE_SEATDOWN = 1,

GAME_STATE_READY = 2,

GAME_STATE_PLAY = 3

};

public:

CUser();

virtual ~CUser();

int Pack(char *pData);

int UnPack(const void *pData);

int GetPackSize();

int GetDataSize();

 

 

public:

int ID() const

{

return m_nID;

}

void ID(int val)

{

m_nID = val;

}

CString Name() const

{

return m_szName;

}

void Name(CString val)

{

m_szName = val;

}

CString Nickname() const

{

return m_szNickname;

}

void Nickname(CString val)

{

m_szNickname = val;

}

CString Password() const

{

return m_szPassword;

}

void Password(CString val)

{

m_szPassword = val;

}

int Sex() const

{

return m_nSex;

}

void Sex(int val)

{

m_nSex = val;

}

CString Birthday() const

{

return m_szBirthday;

}

void Birthday(CString val)

{

m_szBirthday = val;

}

CString Phone() const

{

return m_szPhone;

}

void Phone(CString val)

{

m_szPhone = val;

}

int State() const

{

return m_nState;

}

void State(int val)

{

m_nState = val;

}

int FaceID() const

{

return m_nFaceID;

}

void FaceID(int val)

{

m_nFaceID = val;

}

sockaddr Addr() const

{

return m_addr;

}

void Addr(sockaddr val)

{

m_addr = val;

}

int GameState() const

{

return m_nGameState;

}

void GameState(int val)

{

m_nGameState = val;

}

int RoomID() const

{

return m_nRoomID;

}

void RoomID(int val)

{

m_nRoomID = val;

}

int TableID() const

{

return m_nTableID;

}

void TableID(int val)

{

m_nTableID = val;

}

 

int SeatID() const

{

return m_nSeatID;

}

void SeatID(int val)

{

m_nSeatID = val;

}

int LLKScore() const

{

return m_nLLKScore;

}

void LLKScore(int val)

{

m_nLLKScore = val;

}

 

public:

friend class CUserList;

static BOOL AddrCmp(const sockaddr *addr1, const sockaddr *addr2);

private:

// 基本信息

int m_nID;

CString m_szName;

CString m_szNickname;

CString m_szPassword;

int m_nSex;

CString m_szBirthday;

CString m_szPhone;

int m_nState;

int m_nFaceID;

 

// 在线状态的信息

sockaddr m_addr;

int m_nGameState;

int m_nRoomID;

int m_nTableID;

int m_nSeatID;

 

// 游戏积分

int m_nLLKScore;

};

 

#endif // !defined(AFX_USER_H__49D2C842_4BDA_42CB_8E66_562823E19F5A__INCLUDED_)

 

 

// UserIDList.h: interface for the CUserIDList class.

// CUserIDList 是对CUserList的映射 可以保证数据的同一性 无冗余

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USERIDLIST_H__AA2F05ED_5985_4343_A70B_8BF47BAC52BC__INCLUDED_)

#define AFX_USERIDLIST_H__AA2F05ED_5985_4343_A70B_8BF47BAC52BC__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "UserMan.h"

#include <vector>

using namespace std;

 

class CUserMan;

 

typedef vector<int> VEC_USERID;

 

class CUserIDList

{

public:

CUserIDList();

virtual ~CUserIDList();

BOOL AddUser(int UID);

BOOL DelUser(int UID);

CUser *GetUser(int index, CUserMan *pUserMan);

private:

VEC_USERID m_vecUserID;

};

 

#endif // !defined(AFX_USERIDLIST_H__AA2F05ED_5985_4343_A70B_8BF47BAC52BC__INCLUDED_)

 

 

// UserList.h: interface for the CUserList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USERLIST_H__A1C3DB85_079E_4FF6_A61D_4138CD93BCBA__INCLUDED_)

#define AFX_USERLIST_H__A1C3DB85_079E_4FF6_A61D_4138CD93BCBA__INCLUDED_

 

#pragma warning(disable:4786)

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include "User.h"

 

#include <map>

using namespace std;

typedef map<int, CUser> MAP_USER;

class CUserList

{

public:

CUserList();

virtual ~CUserList();

BOOL AddUser(CUser &user); //往列表中添加用户

BOOL DelUser(int UID); //删除用户

CUser *GetUser(int UID); //得到用户信息

CUser *GetUserByIndex(int index); //使用索引得到用户信息

CUser *GetUserByAddr(const sockaddr &addr); //从地址得到用户信息

int GetUserCount(); //得到用户数量

 

int GetUserIDByAddr(const sockaddr &addr); //通过地址得到id

BOOL HasUser(int UID); //判断是否存在某用户

void Empty(); //清空用户信息

 

void AddScore(int UID, int score);

 

//打包相关函数

int Pack(char *pData); //打包

int UnPack(const char *pData); //解包

int GetPackSize(); //得到包大小

int GetDataSize(); //得到数据所占的大小

 

public:

MAP_USER m_mapUser;

};

 

#endif // !defined(AFX_USERLIST_H__A1C3DB85_079E_4FF6_A61D_4138CD93BCBA__INCLUDED_)

 

 

// UserMan.h: interface for the CUserMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USERMAN_H__CCBDF347_5FBC_4D2D_A07C_C72F5A9BEEC5__INCLUDED_)

#define AFX_USERMAN_H__CCBDF347_5FBC_4D2D_A07C_C72F5A9BEEC5__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "UserList.h"

#include "UserIDList.h"

#include <set>

using namespace std;

 

class CUserIDList;

 

typedef set<CUserIDList*> SET_CUSERIDLIST;

 

//////////////////////////////////////////////////////////////////////////

// 用户管理类

class CUserMan

{

public:

CUserMan();

virtual ~CUserMan();

BOOL AddUser(CUser &user); //添加用户 用户登陆后处理

BOOL DelUser(int UID); //删除用户 用户退出

BOOL SetUserState(int UID, int state); //设置状态

BOOL HasUser(int UID); //检测是否存在用户

 

CUser *GetUser(int UID); //得到用户信息的指针

CUser *GetUserByIndex(int index); //通过索引得到用户

CUser *GetUserByAddr(const sockaddr &addr); //通过地址得到用户信息指针

 

int GetUserID(const sockaddr &addr); //通过地址得到用户id

int GetUserCount(); //得到用户数量

// sockaddr GetUserAddr(int UID); //得到用户地址

CUserList GetUserList(int mode = 0, WPARAM wParam = 0); //根据某种条件查找用户 默认返回所有用户

void AddScore(int UID, int score);

 

 

int Pack(char *pData);

int UnPack(const char *pData);

 

// UserIDList的管理

BOOL AddUserIDList(CUserIDList *pUserIDList);

void DelUserIDList(CUserIDList *pUserIDList);

 

public:

CUserList m_userlist;

SET_CUSERIDLIST m_setUserIDList;

};

//////////////////////////////////////////////////////////////////////////

 

#endif // !defined(AFX_USERMAN_H__CCBDF347_5FBC_4D2D_A07C_C72F5A9BEEC5__INCLUDED_)

 

 

 

Client客户端项目主要代码

// Client.cpp : Defines the class behaviors for the application.

//

 

#include "stdafx.h"

#include "Client.h"

#include "ClientDlg.h"

#include "LoginDlg.h"

#include "../Basic/Ini.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

 

//全局变量

CBitmap g_bmpFaceOnline[MAX_BMP_NUMBER];

CBitmap g_bmpFaceOffline[MAX_BMP_NUMBER];

CBitmap g_bmpFaceQQ[MAX_BMP_NUMBER];

 

CUser g_user;

CTableMan g_tableMan;

BOOL g_bTableUpdate = FALSE;

CUserMan g_userMan;

CLLKGameMan g_llkGameMan;

CClientNetMan g_netMan;

CClientWMLink g_clientWMLink;

CScoreList g_scoreTop10List;

 

HWND g_hwndLLKWin = NULL;

 

/////////////////////////////////////////////////////////////////////////////

// CClientApp

 

BEGIN_MESSAGE_MAP(CClientApp, CWinApp)

//{{AFX_MSG_MAP(CClientApp)

// NOTE - the ClassWizard will add and remove mapping macros here.

//    DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG

ON_COMMAND(ID_HELP, CWinApp::OnHelp)

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CClientApp construction

 

CClientApp::CClientApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}

 

/////////////////////////////////////////////////////////////////////////////

// The one and only CClientApp object

 

CClientApp theApp;

 

/////////////////////////////////////////////////////////////////////////////

// CClientApp initialization

 

BOOL CClientApp::InitInstance()

{

AfxEnableControlContainer();

 

// Standard initialization

// If you are not using these features and wish to reduce the size

//  of your final executable, you should remove from the following

//  the specific initialization routines you do not need.

 

#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif

//初始化Socket

CMySocket::StartUp();

if (!g_netMan.Init())

{

::MessageBox(NULL, "网络管理模块初始化失败!", "错误", 0);

return FALSE;

}

 

ReadSetting();

ReadImage();

//登录框

CLoginDlg loginDlg;

int loginRet;

loginRet = loginDlg.DoModal();

if (loginRet == IDCANCEL)

{

return FALSE;

}

 

//大厅

CClientDlg dlg;

m_pMainWnd = &dlg;

int nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with OK

}

else if (nResponse == IDCANCEL)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with Cancel

}

 

// Since the dialog has been closed, return FALSE so that we exit the

//  application, rather than start the application's message pump.

CMySocket::CleanUp();

return FALSE;

}

 

//读取设置文件

void CClientApp::ReadSetting()

{

CString strModleName;

GetModuleFileName(NULL, strModleName.GetBuffer(512), 511);

strModleName.ReleaseBuffer();

strModleName = strModleName.Left(strModleName.ReverseFind('\\') + 1);

 

CString szSettingFileName;

szSettingFileName = strModleName += "Client.ini";

 

g_netMan.m_setting.m_szServerIP = GetIniString("SERVER",

   "ServerIP",

   "127.0.0.1",

   szSettingFileName);

CString str;

str = GetIniString("SERVER", "ServerProt", "8888", szSettingFileName);

g_netMan.m_setting.m_nServerPort = atoi(str.GetBuffer(0));

str.Format("ServerIP=%s, Port=%d",

   g_netMan.m_setting.m_szServerIP.GetBuffer(0),

   g_netMan.m_setting.m_nServerPort);

OutputDebugString(str);

}

 

void CClientApp::ReadImage()

{

CString str;

for (int i = 1; i <= MAX_BMP_NUMBER; i++)

{

str.Format("IMAGE\\GameFace\\%d-1.bmp", i);

g_bmpFaceOnline[i - 1].m_hObject = LoadImage(NULL,

 str.GetBuffer(0),

 IMAGE_BITMAP,

 0,

 0,

 LR_LOADFROMFILE);

if (g_bmpFaceOnline[i - 1].m_hObject == NULL)

{

MessageBox(NULL, str, "Read image error!", MB_OK);

break;

}

 

str.Format("IMAGE\\GameFace\\%d-2.bmp", i);

g_bmpFaceOffline[i - 1].m_hObject = LoadImage(NULL,

  str.GetBuffer(0),

  IMAGE_BITMAP,

  0,

  0,

  LR_LOADFROMFILE);

if (g_bmpFaceOffline[i - 1].m_hObject == NULL)

{

MessageBox(NULL, str, "Read image error!", MB_OK);

break;

}

 

str.Format("IMAGE\\QQFace\\%d.bmp", i);

g_bmpFaceQQ[i - 1].m_hObject = LoadImage(NULL,

 str.GetBuffer(0),

 IMAGE_BITMAP,

 0,

 0,

 LR_LOADFROMFILE);

if (g_bmpFaceQQ[i - 1].m_hObject == NULL)

{

MessageBox(NULL, str, "Read image error!", MB_OK);

break;

}

}

}

 

 

// CClientDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "ClientDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CAboutDlg dialog used for App About

 

int FRAME_WIDTH = 15;

int FRAME_HEIGHT = 14;

 

#define TIMER_CHECK_GAME_ONLINE_ID 11

#define TIMER_CHECK_GAME_TIMEOUT 3000

 

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

 

// Dialog Data

//{{AFX_DATA(CAboutDlg)

enum { IDD = IDD_ABOUTBOX };

//}}AFX_DATA

 

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

//{{AFX_MSG(CAboutDlg)

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

 

}

 

void CAboutDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

 

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CClientDlg dialog

 

CClientDlg::CClientDlg(CWnd *pParent /*=NULL*/) : CDialog(CClientDlg::IDD,

  pParent)

{

//{{AFX_DATA_INIT(CClientDlg)

//}}AFX_DATA_INIT

// Note that LoadIcon does not require a subsequent DestroyIcon in Win32

m_pHallDlg = NULL;

m_pRoomDlg = NULL;

m_gameProcessID = 0;

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

 

void CClientDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CClientDlg)

DDX_Control(pDX, IDC_LAB_SCORE, m_labScore);

DDX_Control(pDX, IDC_BMP_FACE, m_labFace);

DDX_Control(pDX, IDC_LAB_USER_ID, m_labUserID);

DDX_Control(pDX, IDC_LAB_NICKNAME, m_labNickName);

DDX_Control(pDX, IDC_SEPARATOR, m_separator);

DDX_Control(pDX, IDC_TAB_MAIN, m_tabMain);

DDX_Control(pDX, IDC_TREE_SERVER, m_treeServer);

//}}AFX_DATA_MAP

 

}

 

BEGIN_MESSAGE_MAP(CClientDlg, CDialog)

//{{AFX_MSG_MAP(CClientDlg)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_WM_SIZE()

ON_MESSAGE(DM_GETDEFID, OnGetDefID)

ON_WM_MOUSEMOVE()

ON_WM_LBUTTONDOWN()

ON_WM_LBUTTONUP()

ON_WM_SIZING()

ON_NOTIFY(NM_CLICK, IDC_TREE_SERVER, OnClickTreeServer)

ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_SERVER, OnSelchangedTreeServer)

ON_NOTIFY(NM_DBLCLK, IDC_TREE_SERVER, OnDblclkTreeServer)

ON_WM_TIMER()

ON_WM_CLOSE()

ON_WM_COPYDATA()

ON_WM_DESTROY()

ON_MESSAGE(WM_NET_MSG, OnNetMsg)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CClientDlg message handlers

 

BOOL CClientDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// Add "About..." menu item to system menu.

 

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

 

CMenu *pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

 

// Set the icon for this dialog.  The framework does this automatically

//  when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set small icon

 

// TODO: Add extra initialization here

g_clientWMLink.Create(this->m_hWnd, NULL);

 

CBitmap bmpLLK;

bmpLLK.m_hObject = LoadImage(NULL,

 "IMAGE\\LLK.bmp",

 IMAGE_BITMAP,

 0,

 0,

 LR_LOADFROMFILE);

m_imglistTreeImg.Create(16, 16, ILC_COLOR8, 0, 4);

m_imglistTreeImg.Add(&bmpLLK, &bmpLLK);

 

m_treeServer.SetImageList(&m_imglistTreeImg, TVSIL_NORMAL);

 

HTREEITEM htRoot;

HTREEITEM htLLK;

HTREEITEM htLLKRoom;

 

htRoot = m_treeServer.InsertItem("连连看", 0, 0);

m_treeServer.InsertItem("积分排行", 0, 0, htRoot);

htLLK = m_treeServer.InsertItem("连连看 1", 0, 0, htRoot);

htLLKRoom = m_treeServer.InsertItem("普通场", 0, 0, htLLK);

 

m_pHallDlg = new CHallDlg;

m_pHallDlg->Create(CHallDlg::IDD, &m_tabMain);

 

m_tabMain.AddItem(m_pHallDlg, "游戏大厅");

 

m_treeServer.Expand(htRoot, TVE_EXPAND);

 

g_netMan.Start(this);

 

// 请求登录的用户信息

g_netMan.SendGetLoginUserInfo();

return TRUE;  // return TRUE  unless you set the focus to a control

}

 

void CClientDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

 

// If you add a minimize button to your dialog, you will need the code below

//  to draw the icon.  For MFC applications using the document/view model,

//  this is automatically done for you by the framework.

afx_msg LRESULT CClientDlg::OnGetDefID( WPARAM wParam, LPARAM lParam )

{

return MAKELONG(0, DC_HASDEFID);

}

 

void CClientDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc (this); // device context for painting

 

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

 

// Center icon in client rectangle

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

 

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

 

// The system calls this to obtain the cursor to display while the user drags

//  the minimized window.

HCURSOR CClientDlg::OnQueryDragIcon()

{

return (HCURSOR) m_hIcon;

}

 

void CClientDlg::OnSize(UINT nType, int cx, int cy)

{

CDialog::OnSize(nType, cx, cy);

// TODO: Add your message handler code here

//创建对话框时,控件还没有创建,因此不能改变其大小

if (!IsWindowVisible())

{

return;

}

 

CRect sepRect;

CRect winRect;

CRect treeRect;

CRect tabRect;

 

m_separator.GetWindowRect(&sepRect);

this->GetWindowRect(&winRect);

m_treeServer.GetWindowRect(&treeRect);

m_tabMain.GetWindowRect(&tabRect);

m_separator.SetWindowPos(NULL,

 0,

 0,

 sepRect.Width(),

 sepRect.Height() +

 winRect.bottom -

 sepRect.bottom -

 FRAME_HEIGHT,

 SWP_NOMOVE |

 SWP_NOZORDER);

m_treeServer.SetWindowPos(NULL,

  0,

  0,

  treeRect.Width(),

  treeRect.Height() +

  winRect.bottom -

  treeRect.bottom -

  FRAME_HEIGHT,

  SWP_NOMOVE |

  SWP_NOZORDER);

m_tabMain.SetWindowPos(NULL,

   0,

   0,

   tabRect.Width() +

   winRect.right -

   tabRect.right -

   FRAME_WIDTH,

   tabRect.Height() +

   winRect.bottom -

   tabRect.bottom -

   FRAME_HEIGHT,

   SWP_NOMOVE |

   SWP_NOZORDER);

 

m_tabMain.m_pCurWnd->SendMessage(WM_SIZE, 0, 0);

}

 

 

 

void CClientDlg::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

 

CDialog::OnMouseMove(nFlags, point);

}

 

void CClientDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

 

CDialog::OnLButtonDown(nFlags, point);

}

 

void CClientDlg::OnLButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

 

CDialog::OnLButtonUp(nFlags, point);

}

 

void CClientDlg::OnSizing(UINT fwSide, LPRECT pRect)

{

if (pRect->right -

pRect->left <=

MIN_WIDTH_OF_HALL_DLG +

MIN_WIDTH_OF_SERVER_TREE +

2 * FRAME_WIDTH)

{

pRect->right = pRect->left +

   MIN_WIDTH_OF_HALL_DLG +

   MIN_WIDTH_OF_SERVER_TREE +

   2 * FRAME_WIDTH;

}

 

if (pRect->bottom - pRect->top <= 400)

{

pRect->bottom = pRect->top + 400;

}

 

CDialog::OnSizing(fwSide, pRect);

 

// TODO: Add your message handler code here

}

 

void CClientDlg::OnClickTreeServer(NMHDR *pNMHDR, LRESULT *pResult)

{

// TODO: Add your control notification handler code here

*pResult = 0;

}

 

void CClientDlg::OnSelchangedTreeServer(NMHDR *pNMHDR, LRESULT *pResult)

{

// TODO: Add your control notification handler code here

*pResult = 0;

}

 

void CClientDlg::OnDblclkTreeServer(NMHDR *pNMHDR, LRESULT *pResult)

{

// TODO: Add your control notification handler code here

HTREEITEM ht = m_treeServer.GetSelectedItem();

CString strSelect = m_treeServer.GetItemText(ht);

 

if (strSelect == "积分排行")

{

g_netMan.SendGetTop10();

}

if (strSelect == "普通场" && m_pRoomDlg == NULL)

{

m_pRoomDlg = new CRoomDlg;

m_pRoomDlg->Create(CRoomDlg::IDD, &m_tabMain);

 

m_tabMain.AddItem(m_pRoomDlg, strSelect.GetBuffer(0));

m_tabMain.ChangeTo(1);

 

// 请求桌面信息

g_netMan.SendGetTableInfo();

g_netMan.SendGetUserList();

}

else if (strSelect == "普通场")

{

m_tabMain.ChangeTo(1);

}

 

*pResult = 0;

}

 

HRESULT CClientDlg::OnNetMsg(WPARAM wParam, LPARAM lParam)

{

int data;

long ret = g_netMan.OnNetMsg(wParam, lParam, this, &data);

switch (ret)

{

case NETMSG_RET_ERROR_TOCONNECT:

MessageBox("连接服务器出错!请检查网络!", "提示");

break;

case PTS_SEAT_DOWN_SUCC:

StartGame(g_user.ID());

break;

case PTS_SEAT_DOWN_FAIL:

MessageBox("进入游戏失败...", "提示");

break;

case PTCS_GET_LOGIN_USER_INFO:

ShowUserInfo();

break;

case PTCS_GET_GAMEINFO:

g_clientWMLink.SendGameInfo(&g_llkGameMan);

break;

case PTCS_GET_SCORE_TOP10:

{

CScoreTop10Dlg top10dlg;

top10dlg.SetScoreList(g_scoreTop10List);

top10dlg.DoModal();

}

break;

case PTS_GAME_BEGIN:

{

g_clientWMLink.SendBeginMsg(&g_llkGameMan);

}

break;

case PTS_GAME_END:

{

}

break;

case PTS_LOOK_ON_SUCC:

{

TRACE("S look on userid = %d... \n", data);

StartGame(data, TRUE);

}

break;

case PTS_LOOK_ON_FAIL:

TRACE("S Look on fail... \n");

break;

}

 

return 0;

}

 

void CClientDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

if (nIDEvent == WAIT_MSG_FROM_SERVER_TIMER_ID)

{

MessageBox("服务器反馈超时,请检查网络!");

KillTimer(WAIT_MSG_FROM_SERVER_TIMER_ID);

}

if (nIDEvent == TIMER_CHECK_GAME_ONLINE_ID)

{

MessageBox("游戏异常退出!已离开座位!");

OnGameExit();

}

CDialog::OnTimer(nIDEvent);

}

 

//////////////////////////////////////////////////////////////////////////

// 显示用户信息

void CClientDlg::ShowUserInfo()

{

CString str;

str.Format("用户ID: %d", g_user.ID());

m_labUserID.SetWindowText(str.GetBuffer(0));

 

str.Format("昵  称: %s", g_user.Nickname().GetBuffer(0));

m_labNickName.SetWindowText(str.GetBuffer(0));

 

str.Format("积  分: %d", g_user.LLKScore());

m_labScore.SetWindowText(str.GetBuffer(0));

 

m_labFace.SetBitmap(g_bmpFaceQQ[g_user.FaceID()]);

}

//////////////////////////////////////////////////////////////////////////

 

void CClientDlg::OnClose()

{

// TODO: Add your message handler code here and/or call default

if (g_hwndLLKWin != NULL)

{

::SendMessage(g_hwndLLKWin, WM_CLOSE, 0, 0);

}

CDialog::OnClose();

}

 

void CClientDlg::StartGame( int mainUserID, BOOL bIsLookOn /*= FALSE*/ )

{

//设置程序路径

if (g_hwndLLKWin != NULL)

{

g_clientWMLink.Send(PTS_SHOW_WINDOW, 0, 0);

return;

}

char szFilePath[256] ={0};

GetAppPath(szFilePath);

 

strcat(szFilePath, "LLK\\LLK.exe");

 

//进程的特殊结构体

PROCESS_INFORMATION pi;

STARTUPINFO si;

memset(&pi, 0, sizeof(PROCESS_INFORMATION));

memset(&si, 0, sizeof(STARTUPINFO));

si.cb = sizeof(si);

// 将 窗口句柄 和 游戏ID 传给游戏端

si.dwX = (DWORD)this->m_hWnd;

si.dwY = (DWORD)mainUserID;

si.dwXSize = (DWORD)bIsLookOn;

TRACE("G WinHwnd = %d\n", m_hWnd);

 

if (!::CreateProcess(szFilePath, // No module name (use command line).

NULL, // Command line.

NULL, // Process handle not inheritable.

NULL, // Thread handle not inheritable.

NULL, // Set handle inheritance to FALSE.

NULL, // suspended creation flags.

NULL, // Use parent's environment block.

NULL, // Use parent's starting directory.

 & si, // Pointer to STARTUPINFO structure.

 & pi) // Pointer to PROCESS_INFORMATION structure.

   )

{

char szBuf[80];

GetLastErrorMsg(szBuf);

::MessageBox(NULL, szBuf, "错误", MB_OK);

return;

}

}

 

 

void CClientDlg::OnDestroy()

{

CDialog::OnDestroy();

 

// TODO: Add your message handler code here

g_netMan.SendExit();

TRACE("TS ExitMsg\n");

 

if (m_pRoomDlg != NULL)

{

delete m_pRoomDlg;

}

if (m_pHallDlg != NULL)

{

delete m_pHallDlg;

}

}

 

 

BOOL CClientDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)

{

// TODO: Add your message handler code here and/or call default

long ret = g_clientWMLink.OnRecv(pWnd, pCopyDataStruct);

switch(ret)

{

case PTC_STAND_UP:

case PTCS_EXIT:

TRACE("G Game exit do something~~\n");

OnGameExit();

break;

case PTCS_GET_GAMEINFO:

{

g_clientWMLink.SendGameInfo(&g_llkGameMan);

}

break;

case PTC_SEND_GAMEINFO:

{

CLLK llk;

llk.UnPack(pCopyDataStruct->lpData);

g_netMan.SendGameSingleInfo(&llk);

}

break;

case PTCS_CHECK_ONLINE:

TRACE("T Get the check online form game...  \n");

KillTimer(TIMER_CHECK_GAME_ONLINE_ID);

SetTimer(TIMER_CHECK_GAME_ONLINE_ID, TIMER_CHECK_GAME_TIMEOUT, NULL);

break;

case PTCS_GET_HWND:

SetTimer(TIMER_CHECK_GAME_ONLINE_ID, TIMER_CHECK_GAME_TIMEOUT, NULL);

break;

case PTC_GAME_READY:

g_netMan.SendReady();

break;

default:

break;

}

return CDialog::OnCopyData(pWnd, pCopyDataStruct);

}

 

void CClientDlg::OnGameExit()

{

// 游戏退出时的处理

g_hwndLLKWin = NULL;

g_clientWMLink.SetYourHwnd(NULL);

KillTimer(TIMER_CHECK_GAME_ONLINE_ID);

g_netMan.SendStandUp();

}

 

 

// ClientNetMan.cpp: implementation of the CClientNetMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Client.h"

#include "ClientNetMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CClientNetMan::CClientNetMan()

{

m_pWnd = NULL;

m_mode = 0;

}

 

CClientNetMan::~CClientNetMan()

{

}

 

void CClientNetMan::EasySendToServer(int nType,

 int dataSize /*= 0*/,

 const void *pData /*= NULL*/)

{

CPacket pacToServer;

pacToServer.Make(nType, 0, dataSize, pData);

int pacSize = pacToServer.GetPackSize();

char*pBuf = new char[pacSize + 2];

ZeroMemory(pBuf, pacSize + 2);

int len = pacToServer.Pack(pBuf);

int ret = m_mysock.SendTo(pBuf,

len,

m_setting.m_nServerPort,

m_setting.m_szServerIP);

if (ret == SOCKET_ERROR)

{

int err = GetLastError();

CString str;

str.Format("SOCKET_ERROR: code=%d", err);

 

MessageBox(NULL, str, "提示", 0);

return;

}

delete[] pBuf;

}

 

BOOL CClientNetMan::Init()

{

return m_mysock.Create(0, SOCK_DGRAM);

}

 

 

void CClientNetMan::Start(CWnd *pWnd, int mode /*= NETMAN_MODE_NOTEXIT*/)

{

m_pWnd = pWnd;

m_mode = mode;

int ret = m_mysock.AsyncSelect(pWnd->m_hWnd, WM_NET_MSG, FD_READ);

if (ret == SOCKET_ERROR)

{

MessageBox(NULL, "AsyncSelect errr!", "提示", 0);

}

SetTimer(m_pWnd->m_hWnd,

WAIT_MSG_FROM_SERVER_TIMER_ID,

NETMSG_TIMEOUT,

NULL);

}

 

void CClientNetMan::Stop(CWnd *pWnd)

{

Stop(pWnd->m_hWnd);

}

 

void CClientNetMan::Stop(HWND hwnd)

{

m_mysock.AsyncSelect(hwnd, 0, 0);

KillTimer(hwnd, WAIT_MSG_FROM_SERVER_TIMER_ID);

m_pWnd = NULL;

}

void CClientNetMan::SendRegEnter(CUser &user)

{

char buf[512] ={0};

int len = user.Pack(buf);

EasySendToServer(PTC_REG_ENTER, len, buf);

}

 

void CClientNetMan::SendLoginInfo(LOGIN_INFO &loginInfo)

{

//生成登陆消息并发送

EasySendToServer(PTC_LOGIN_ENTER, sizeof(loginInfo), &loginInfo);

}

 

void CClientNetMan::SendSeatDown(int UID, int tid, int sid)

{

char buf[100] ={0};

COutStream cos;

cos.Create();

 

cos << UID << tid << sid;

cos.CopyTo(buf);

 

EasySendToServer(PTC_SEAT_DOWN, cos.GetSize(), buf);

TRACE("TS OnSeatDown...\n");

}

 

void CClientNetMan::SendLookOn(int UID, int tid, int sid)

{

char buf[100] ={0};

COutStream cos;

cos.Create();

 

cos << UID << tid << sid;

cos.CopyTo(buf);

 

EasySendToServer(PTC_LOOK_ON, cos.GetSize(), buf);

TRACE("TS OnLookOn...\n");

}

 

void CClientNetMan::SendGetLoginUserInfo()

{

EasySendToServer(PTCS_GET_LOGIN_USER_INFO);

}

 

void CClientNetMan::SendGetTableInfo()

{

EasySendToServer(PTCS_GET_TABLE_INFO);

}

 

void CClientNetMan::SendGetUserList()

{

EasySendToServer(PTCS_GET_USER_LIST);

}

 

 

void CClientNetMan::SendCheckOnline()

{

EasySendToServer(PTCS_CHECK_ONLINE);

}

 

void CClientNetMan::SendExit()

{

EasySendToServer(PTCS_EXIT);

}

 

void CClientNetMan::SendStandUp()

{

EasySendToServer(PTC_STAND_UP);

}

 

//////////////////////////////////////////////////////////////////////////

// 对网络包的接收处理

// 参数: wParam lParam 消息的两个参数, pWnd 窗口(基本没用), pData 接收数据用

// 返回: 查看NETMSG_RET的定义

HRESULT CClientNetMan::OnNetMsg( WPARAM wParam, LPARAM lParam, CWnd * pWnd /*= NULL*/, void * pData /*= NULL*/ )

{

//处理接收到的信息

long ret = 0;

SOCKET sock = (SOCKET) wParam;

WORD err = WSAGETSELECTERROR(lParam);

WORD event = WSAGETSELECTEVENT(lParam);

if (err != 0)

{

CString str;

str.Format("本地的Socket连接发生了一个错误! 错误码:%d", err);

MessageBox(NULL, str, "提示", 0);

return NETMSG_RET_ERROR;

}

if (event == FD_READ)

{

pWnd->KillTimer(WAIT_MSG_FROM_SERVER_TIMER_ID);

char buf[10240] ={0};

int len = 0;

len = recv(sock, buf, 10240, 0);

 

if (len == SOCKET_ERROR)

{

int errcode = GetLastError();

TRACE("N [%s]_[%d]:OnNetMsg:: recv error!!!...code=%d\n",__FILE__,  __LINE__, errcode);

 

return NETMSG_RET_ERROR_TOCONNECT;

}

CPacket pac;

int readlen = pac.UnPack(buf);

 

//对接收的包处理

ret = pac.m_nType;

switch (ret)

{

case PTS_REG_SUCC:

{

*(int *)pData = *(int *) pac.m_pData;

}

break;

case PTS_REG_FAIL:

{

}

break;

case PTS_LOGIN_SUCC:

{

}

break;

case PTS_LOGIN_FAIL:

{

*(int *)pData = *(int *) pac.m_pData;

}

break;

case PTCS_GET_TABLE_INFO:

{

g_tableMan.UnPack(pac.m_pData);

TRACE("S Get the table info...  \n");

// 得到桌子信息时提示刷新桌面

g_bTableUpdate = TRUE;

}

break;

case PTS_SEAT_DOWN_FAIL:

{

TRACE("S Seat down fail!\n");

}

break;

case PTS_SEAT_DOWN_SUCC:

{

//如果坐下座位成功 则请求桌子信息和开始游戏信息

TRACE("S Seat down succ!\n");

g_netMan.SendGetTableInfo();

}

break;

case PTCS_GET_LOGIN_USER_INFO:

{

TRACE("S Got the login user info ...\n");

g_user.UnPack(pac.m_pData);

}

break;

case PTCS_GET_USER_LIST:

{

TRACE("S Got the user list ...\n");

 

g_userMan.UnPack(pac.m_pData);

}

break;

case PTCS_CHECK_ONLINE:

{

TRACE("S Check online!\n");

g_netMan.SendCheckOnline();

}

break;

case PTCS_EXIT:

{

//服务器发来退出消息

}

break;

case PTCS_GET_GAMEINFO:

{

TRACE("S Got the game info llkMan...\n");

g_llkGameMan.UnPack(pac.m_pData);

}

break;

case PTCS_GET_SCORE_TOP10:

{

TRACE("S Got the tope 10 list ... \n");

g_scoreTop10List.UnPack(pac.m_pData);

}

break;

case PTS_GAME_BEGIN:

{

TRACE("S Got begin game msg... \n");

g_llkGameMan.UnPack(pac.m_pData);

}

break;

case PTS_GAME_END:

{

TRACE("S Got end game msg... \n");

g_clientWMLink.Send(PTS_GAME_END, pac.m_nDataLen, pac.m_pData);

}

break;

case PTS_LOOK_ON_SUCC:

*(int*)pData = *(int *)pac.m_pData;

break;

case PTS_LOOK_ON_FAIL:

//*(int*)pData = *(int *)pac.m_pData;

break;

}

}

return ret;

}

 

void CClientNetMan::SendGameSingleInfo( CLLK * llk )

{

char buf[1024] = {0};

int len = llk->Pack(buf);

EasySendToServer(PTC_SEND_GAMEINFO, len, buf);

}

 

void CClientNetMan::SendGetTop10()

{

EasySendToServer(PTCS_GET_SCORE_TOP10, 0, NULL);

}

 

void CClientNetMan::SendReady()

{

EasySendToServer(PTC_GAME_READY, 0, NULL);

}

 

void CClientNetMan::SendGetGameInfo()

{

EasySendToServer(PTCS_GET_GAMEINFO, 0, NULL);

}

 

 

// ClientWMLink.cpp: implementation of the CClientWMLink class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Client.h"

#include "ClientWMLink.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CClientWMLink::CClientWMLink()

{

 

}

 

CClientWMLink::~CClientWMLink()

{

 

}

 

INT CClientWMLink::OnRecv( CWnd *pWnd, COPYDATASTRUCT *pCopyData )

{

int gmType = pCopyData->dwData;

switch(gmType)

{

case  PTCS_GET_HWND:

{

m_yourHwnd = pWnd->m_hWnd;

g_hwndLLKWin = m_yourHwnd;

g_netMan.SendGetGameInfo();

}

break;

}

return gmType;

}

 

void CClientWMLink::SendGameInfo( CLLKGameMan * llkGM )

{

TRACE("G Send to game : llkman...\n");

char * pBuf = new char[sizeof(CLLKGameMan)+sizeof(int)];

int len = llkGM->Pack(pBuf);

Send(PTCS_GET_GAMEINFO, len, pBuf);

delete [] pBuf;

}

 

void CClientWMLink::SendBeginMsg( CLLKGameMan * pLLKGM )

{

TRACE("G Send to game begin.... \n");

char * pBuf = new char[sizeof(CLLKGameMan)+sizeof(int)];

int len = pLLKGM->Pack(pBuf);

Send(PTS_GAME_BEGIN, len, pBuf);

delete [] pBuf;

}

 

void CClientWMLink::SendEndMsg( CPacket &pac )

{

TRACE("G Send to game end.... \n");

Send(PTS_GAME_END, pac.m_nDataLen, pac.m_pData);

}

 

 

// Ccpp: implementation of the CLLK class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "CLLK.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLK::CLLK()

{

m_nBoxXCount = BOX_X_COUNT;

m_nBoxYCount = BOX_Y_COUNT;

 

Init();

}

 

CLLK::~CLLK()

{

}

 

int CLLK::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(CLLK) + sizeof(int));

int dataSize = sizeof(CLLK);

cos << dataSize;

cos.Write((char *)this, dataSize);

cos.CopyTo(pData);

 

return cos.GetSize();

}

 

int CLLK::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

if (dataSize != sizeof(CLLK))

{

TRACE("C CLLK::UnPack dataSize[%d] != sizeof(CLLK)[%d]\n", dataSize, sizeof(CLLK));

}

cis.Read((char *)this, sizeof(CLLK));

return cis.GetSize();

}

 

void CLLK::Init()

{

// 初始数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

// 初始化选择

m_nSelBox = 0;

m_ptSelBox[0] = CPoint(0, 0);

m_ptSelBox[1] = CPoint(0, 0);

 

// 初始化连线

m_nLinkLine = 0;

ZeroMemory(m_ptLinkLine, sizeof(m_ptLinkLine));

 

// 初始化将要删除的

m_bHasWillBeNullBox = FALSE;

m_typeWillBeNullBox[0] = 0;

m_typeWillBeNullBox[1] = 0;

m_ptWillBeNullBox[0] = CPoint(-1, -1);

m_ptWillBeNullBox[1] = CPoint(-1, -1);

 

// 初始化连击数

m_nCurLianji = 0;

m_nMaxLianji = 0;

m_dwLastLianjiTime = 0;

 

m_nLeaveBoxCount = 0;

}

 

//////////////////////////////////////////////////////////////////////////

// //判断两坐标是否在同一线上 并且中间无阻碍

BOOL CLLK::IsPairInlineValid(CPoint pt1, CPoint pt2)

{

//同一点判断

if (pt1 == pt2)

{

return FALSE;

}

 

//同一行类型

typedef enum _INLINE_TYPE

{

IT_NULL = 0, //不同行

IT_X = 1, //X同行

IT_Y = 2 //Y同行

} INLINE_TYPE;

 

INLINE_TYPE it;

 

if (pt1.x == pt2.x)

{

it = IT_X;

//计算出两者之大小

int x = pt1.x;

int minY, maxY;

if (pt1.y > pt2.y)

{

minY = pt2.y;

maxY = pt1.y;

}

else

{

minY = pt1.y;

maxY = pt2.y;

}

//紧挨着

if (maxY - minY == 1)

{

return TRUE;

}

//其它情况

for (int i = minY + 1; i < maxY; i++)

{

if (m_nArrType[x][i] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else if (pt1.y == pt2.y)

{

it = IT_Y;

//计算出两者之大小

int y = pt1.y;

int minX, maxX;

if (pt1.x > pt2.x)

{

minX = pt2.x;

maxX = pt1.x;

}

else

{

minX = pt1.x;

maxX = pt2.x;

}

//紧挨着

if (maxX - minX == 1)

{

return TRUE;

}

//其它情况

for (int i = minX + 1; i < maxX; i++)

{

if (m_nArrType[i][y] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else

{

it = IT_NULL;

return FALSE;

}

return FALSE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 判断两点是否可消除 完成后集成在LLK类中

BOOL CLLK::IsPairCanLink(CPoint pt1,

 CPoint pt2,

 int *pnResultPtCount /*= NULL*/,

 CPoint *pPtResult /*= NULL*/)

{

// 结果保存

BOOL bRet = FALSE;

int count = 0;

CPoint point[4];

 

// 重复点情况

if (pt1 == pt2)

{

return FALSE;

}

 

// 图标是否相同

if (m_nArrType[pt1.x][pt1.y] != m_nArrType[pt2.x][pt2.y])

{

return FALSE;

}

 

// 判断流程

do

{

// 1.同一线情况

if (IsPairInlineValid(pt1, pt2))

{

count = 2;

point[0] = pt1;

point[1] = pt2;

bRet = TRUE;

break;

}

 

// 2.一拐点情况

{

CPoint t1, t2;

 

// 两点组成的矩形另外两个顶点

t1.x = pt1.x;

t1.y = pt2.y;

 

t2.x = pt2.x;

t2.y = pt1.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t1) &&

IsPairInlineValid(t1,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t1;

point[2] = pt2;

bRet = TRUE;

break;

}

 

if (m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t2;

point[2] = pt2;

bRet = TRUE;

break;

}

}

 

// 3.两拐点情况

// 先横向检测

{

//另外的两个拐点

CPoint t1, t2;

 

//X向左检测

for (int x = pt1.x - 1; x >= 0; x--)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

//X向右检测 可以使路线变短

for (x = pt1.x + 1; x < BOX_X_COUNT; x++)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向上检测

for (int y = pt1.y - 1; y >= 0; y--)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向下检测

for (y = pt1.y + 1; y < BOX_Y_COUNT; y++)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

}

break;

}

while (1);

 

if (pnResultPtCount != NULL)

{

*pnResultPtCount = count;

if (pPtResult != NULL)

{

for (int i = 0; i < count; i++)

{

pPtResult[i] = point[i];

}

}

}

return bRet;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 执行消除响应

BOOL CLLK::DoXiaoChu()

{

if (m_nSelBox != 2)

{

return FALSE;

}

 

if (m_ptSelBox[0] == m_ptSelBox[1])

{

m_nSelBox = 0;

return FALSE;

}

if (IsPairCanLink(m_ptSelBox[0], m_ptSelBox[1], &m_nLinkLine, m_ptLinkLine))

{

// 将要删除的方块情况维护

m_bHasWillBeNullBox = TRUE;

m_ptWillBeNullBox[0] = m_ptSelBox[0];

m_ptWillBeNullBox[1] = m_ptSelBox[1];

 

m_typeWillBeNullBox[0] = m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y];

m_typeWillBeNullBox[1] = m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y];

 

// 游戏方块状态维护

m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y] = 0;

m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y] = 0;

 

// 连击情况维护

if (m_dwLastLianjiTime == 0)

{

m_dwLastLianjiTime = GetTickCount();

}

DWORD nowTime = GetTickCount();

if (nowTime - m_dwLastLianjiTime <= GAME_LIANJI_TIMEOUT)

{

m_nCurLianji++;

m_dwLastLianjiTime = nowTime;

}

else

{

m_nCurLianji = 1;

m_dwLastLianjiTime = nowTime;

}

if (m_nMaxLianji < m_nCurLianji)

{

m_nMaxLianji = m_nCurLianji;

}

 

 

// 选择情况维护

m_nSelBox = 0;

m_nLeaveBoxCount -= 2;

 

return TRUE;

//AAAASetTimer(GAME_DRAW_LINK_LINE_TIMER_ID, GAME_DRAW_LINK_LINE_TIME, NULL);

}

else

{

m_ptSelBox[0] = m_ptSelBox[1];

m_nSelBox = 1;

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

void CLLK::ResetBoxState()

{

int arrTempState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

CPoint arrPointState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

int nNotNullCount = 0;

 

//将状态和坐标放到一维数组里

for (int x = 0; x < BOX_X_COUNT; x++)

{

for (int y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

arrTempState[nNotNullCount] = m_nArrType[x][y];

arrPointState[nNotNullCount].x = x;

arrPointState[nNotNullCount].y = y;

nNotNullCount++;

}

}

}

 

//为了验证 将状态清空

ZeroMemory(m_nArrType, sizeof(m_nArrType));

 

//随机

srand(GetTickCount());

int index = 0;

int max = nNotNullCount;

for (int i = 0; i < nNotNullCount; i++)

{

index = rand() % max;

m_nArrType[arrPointState[i].x][arrPointState[i].y] = arrTempState[index];

arrTempState[index] = arrTempState[max - 1] ;

max--;

}

 

if (!IsCanXiaoChu())

{

ResetBoxState();

}

//AAAA Invalidate(FALSE);

}

 

BOOL CLLK::IsCanXiaoChu()

{

CPoint *pPt = new CPoint[m_nLeaveBoxCount];

BOOL bRet = FALSE;

int x, y;

int i = 0;

for (x = 0; x < BOX_X_COUNT; x++)

{

for (y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

pPt[i].x = x;

pPt[i].y = y;

i++;

}

}

}

 

for (i = 0; i < m_nLeaveBoxCount; i++)

{

for (int j = i + 1; j < m_nLeaveBoxCount; j++)

{

if (IsPairCanLink(pPt[i], pPt[j]))

{

bRet = TRUE;

break;

}

}

if (bRet == TRUE)

{

break;

}

}

 

delete[] pPt;

return bRet;

}

 

VOID CLLK::InitGameData(int mode /*= 0*/)

{

// 初始游戏数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

int x, y;

int n = 0;

for (x = 1; x < BOX_X_COUNT - 1; x++)

{

for (y = 1; y < BOX_Y_COUNT - 1; y++)

{

m_nArrType[x][y] = n % BOX_TYPE_SIZE + 1;

n++;

}

}

 

m_nLeaveBoxCount = (BOX_X_COUNT - 2) * (BOX_Y_COUNT - 2);

 

ResetBoxState();

}

 

//////////////////////////////////////////////////////////////////////////

 

 

// GameMan.cpp: implementation of the CGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "GameMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CGameMan::CGameMan()

{

}

 

CGameMan::~CGameMan()

{

}

 

 

// HallDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "HallDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CHallDlg dialog

 

 

CHallDlg::CHallDlg(CWnd *pParent /*=NULL*/) : CDialog(CHallDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CHallDlg)

// NOTE: the ClassWizard will add member initialization here

//}}AFX_DATA_INIT

m_bFirstShow = TRUE;

}

 

 

void CHallDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CHallDlg)

DDX_Control(pDX, IDC_EDIT_TEXT, m_text);

//}}AFX_DATA_MAP

 

}

 

 

BEGIN_MESSAGE_MAP(CHallDlg, CDialog)

//{{AFX_MSG_MAP(CHallDlg)

ON_WM_CREATE()

ON_WM_CANCELMODE()

ON_WM_SIZE()

ON_WM_PAINT()

ON_MESSAGE(DM_GETDEFID, OnGetDefId)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CHallDlg message handlers

 

 

 

int CHallDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CDialog::OnCreate(lpCreateStruct) == -1)

{

return -1;

}

 

// TODO: Add your specialized creation code here

return 0;

}

 

void CHallDlg::OnCancelMode()

{

CDialog::OnCancelMode();

 

// TODO: Add your message handler code here

}

 

void CHallDlg::OnSize(UINT nType, int cx, int cy)

{

CDialog::OnSize(nType, cx, cy);

 

// TODO: Add your message handler code here

if (!IsWindowVisible())

{

return;

}

CRect parRect;

CRect editRect;

 

GetParent()->GetClientRect(&parRect);

SetWindowPos(NULL,

 0,

 0,

 parRect.Width() - 10,

 parRect.Height() - 35,

 SWP_NOMOVE | SWP_NOOWNERZORDER);

 

m_text.GetParent()->GetClientRect(&editRect);

m_text.SetWindowPos(NULL,

0,

0,

editRect.Width(),

editRect.Height(),

SWP_NOMOVE | SWP_NOOWNERZORDER);

}

 

void CHallDlg::OnPaint()

{

CPaintDC dc (this); // device context for painting

 

// TODO: Add your message handler code here

 

if (m_bFirstShow)

{

SendMessage(WM_SIZE, 0, 0);

}

 

// Do not call CDialog::OnPaint() for painting messages

}

 

HRESULT CHallDlg::OnGetDefId( WPARAM wParam, LPARAM lParam )

{

return MAKELONG(0, DC_HASDEFID);

}

 

 

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 预处理

#include "Ini.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 函数实现

CString GetIniString(CString sec,

 CString key,

 CString str,

 CString sIniFileName)

{

CString sss;

GetPrivateProfileString(sec,

key,

str,

sss.GetBuffer(512),

511,

sIniFileName);

sss.ReleaseBuffer();

return sss;

}

 

BOOL SetIniString(CString sec, CString key, CString str, CString sIniFileName)

{

return WritePrivateProfileString(sec, key, str, sIniFileName);

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

// InStream.cpp: implementation of the CInStream class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "InStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CInStream::CInStream()

{

m_pInBuf = NULL;

m_pCurInPtr = NULL;

m_pMaxInPtr = NULL;

m_nMaxSize = 0;

}

 

CInStream::~CInStream()

{

}

 

BOOL CInStream::Create( const void *pData )

{

int BufMaxSize = -1;

if (pData == NULL)

{

return FALSE;

}

m_nMaxSize = BufMaxSize;

m_pInBuf = pData;

m_pCurInPtr = m_pInBuf;

m_pMaxInPtr = m_pCurInPtr;

return FALSE;

}

 

int CInStream::Read(void *savePtr, int readSize)

{

if (savePtr == NULL || readSize <= 0)

{

TRACE("B CInStream::Read prarm is zero!\n");

return 0;

}

if (m_nMaxSize != -1 && (const char *)m_pCurInPtr + readSize - (const char *)m_pInBuf > m_nMaxSize)

{

TRACE("B CInStread::Read out of range!\n");

return 0;

}

memcpy(savePtr, m_pCurInPtr, readSize);

m_pCurInPtr = (const char *)m_pCurInPtr + readSize;

 

//最大访问指针维护

if (m_pCurInPtr > m_pMaxInPtr)

{

m_pMaxInPtr = m_pCurInPtr;

}

return readSize;

}

 

const void * CInStream::GetHead()

{

return m_pInBuf;

}

 

const void * CInStream::GetCurPtr()

{

return m_pCurInPtr;

}

 

 

//////////////////////////////////////////////////////////////////////////

// 注意:此函数并未严格判定访问是否越界 使用时小心

BOOL CInStream::MoveCurPtr(int offset, int mode /*= MP_CUR*/)

{

if (mode == MP_CUR)

{

m_pCurInPtr = (const char *)m_pCurInPtr + offset;

}

else if (mode == MP_BEG)

{

if (offset < 0)

{

return FALSE;

}

m_pCurInPtr = (const char *)m_pInBuf + offset;

}

else if (mode == MP_END)

{

if (m_nMaxSize == -1)

{

TRACE("B CInStream::MoveCurPtr MP_END mode not support m_nMaxSize = -1\n");

return FALSE;

}

if (offset > 0)

{

return FALSE;

}

  m_pCurInPtr = (const char *)m_pInBuf + offset;

}

if (m_pCurInPtr > m_pMaxInPtr)

{

m_pMaxInPtr = m_pCurInPtr;

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

int CInStream::GetSize()

{

return (const char *)m_pMaxInPtr - (const char *)m_pInBuf;

}

 

int CInStream::GetMaxSize()

{

return m_nMaxSize;

}

 

CInStream & CInStream::operator>>(int &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(char &value)

{

Read((char *) &value, sizeof(char));

return *this;

}

 

CInStream & CInStream::operator>>(char *value)

{

int len = 0;

Read((char *) &len, sizeof(int));

Read(value, len);

return *this;

}

 

CInStream & CInStream::operator>>(CString &value)

{

int len = 0;

Read((char *) &len, sizeof(int));

Read(value.GetBuffer(len), len);

value.ReleaseBuffer();

return *this;

}

 

CInStream & CInStream::operator>>(long &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(UINT &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(ULONG &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(UCHAR &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(float &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(double &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

 

 

// LLKGameMan.cpp: implementation of the CLLKGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "LLKGameMan.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#include "../Common/User.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLKGameMan::CLLKGameMan()

{

m_state = GAME_NULL;

ZeroMemory(m_UID, sizeof(m_UID));

}

 

CLLKGameMan::~CLLKGameMan()

{

}

 

int CLLKGameMan::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(int) + sizeof(CLLKGameMan));

int dataSize = sizeof(CLLKGameMan);

cos << dataSize;

cos.Write(this, dataSize);

// cos.Write((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// char * pBuf = cos.GetCurPtr();

// int len = m_llk[i].Pack(pBuf);

// cos.MoveCurPtr(len);

// }

// }

// dataSize = cos.GetSize() - sizeof(int);

// *(int*)cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CLLKGameMan::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

cis.Read(this, sizeof(CLLKGameMan));

// cis.Read((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// const char * pBuf = cis.GetCurPtr();

// int len = m_llk[i].UnPack(pBuf);

// cis.MoveCurPtr(len);

// }

// }

return cis.GetSize();

}

 

BOOL CLLKGameMan::AddUser( int UID, char * nickName, int score, int tid, int sid )

{

if (m_UID[sid] == 0)

{

m_UID[sid] = UID;

strcpy(m_NickName[sid], nickName);

m_Score[sid] = score;

}

return TRUE;

}

 

BOOL CLLKGameMan::DelUser( int UID )

{

 

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_UID[i] = 0;

strcpy(m_NickName[i], "");

m_Score[i] = 0;

m_userState[i] = GAME_NULL;

if (GetUserCount() == 0)

{

m_state = GAME_NULL;

}

return TRUE;

}

}

 

return FALSE;

}

 

void CLLKGameMan::InitGame()

{

for (int i = 0; i < 6; i++)

{

m_llk[i].Init();

}

m_llk[0].InitGameData();

// m_llk[0].m_nArrType[1][1] = 1;

// m_llk[0].m_nArrType[1][5] = 1;

// m_llk[0].m_nLeaveBoxCount = 2;

for (i = 1; i < 6; i++)

{

m_llk[i] = m_llk[0];

}

}

 

void CLLKGameMan::SetUserState( int UID, int state )

{

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_userState[i] = state;

return;

}

}

}

 

int CLLKGameMan::CheckGame()

{

if (m_state == GAME_NULL)

{

int userCount = GetUserCount();

if (GetUserCount() == 0)

{

return 0;

}

int readyUserCount = GetReadyUserCount();

if (userCount == readyUserCount && userCount >= MINI_USER_TO_PLAY)

{

return CGR_TOBEGIN;

}

}

else if (m_state == GAME_PLAYING)

{

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_llk[i].m_nLeaveBoxCount == 0)

{

return CGR_TOEND;

}

}

}

 

return CGR_NULL;

}

 

int CLLKGameMan::GetUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

count++;

}

}

return count;

}

 

int CLLKGameMan::GetReadyUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_userState[i] == CUser::GAME_STATE_READY)

{

count++;

}

}

return count;

}

 

BOOL CLLKGameMan::StartGame( int nGameID /*= 1*/ )

{

m_state = GAME_PLAYING;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_PLAYING;

}

}

InitGame();

return TRUE;

}

 

CScoreList CLLKGameMan::EndGame( int nGameID /*= 1*/ )

{

CScoreList  sl;

//游戏结束前计算分数

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

SCORE_INFO si;

si.UID = m_UID[i];

strcpy(si.NickName, m_NickName[i]);

si.GameID = 1000;

si.Score = m_llk[i].m_nLeaveBoxCount;

sl.Add(si);

}

}

CalcScore(sl);

 

//清除各种状态

m_state = GAME_NULL;

for (i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_NULL;

}

}

 

return sl;

}

 

int CLLKGameMan::CalcScore( CScoreList &sl )

{

sl.Sort();

switch (sl.GetCount())

{

case 0:

TRACE("CalcScore not item in scoreList.. \n");

break;

case 1:

sl.GetScoreByIndex(0).Score = 1;

break;

case 2:

sl.GetScoreByIndex(0).Score = 2;

sl.GetScoreByIndex(1).Score = 0;

 

break;

case 3:

sl.GetScoreByIndex(0).Score = 3;

sl.GetScoreByIndex(1).Score = 1;

sl.GetScoreByIndex(2).Score = -1;

break;

case 4:

sl.GetScoreByIndex(0).Score = 4;

sl.GetScoreByIndex(1).Score = 2;

sl.GetScoreByIndex(2).Score = 0;

sl.GetScoreByIndex(3).Score = -1;

break;

case 5:

sl.GetScoreByIndex(0).Score = 5;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

break;

case 6:

sl.GetScoreByIndex(0).Score = 6;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

sl.GetScoreByIndex(5).Score = -2;

break;

}

return sl.GetCount();

}

 

 

// LoginDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "LoginDlg.h"

#include "RegDlg.h"

#include "../Basic/MySocket.h"

#include "../Common/Packet.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

 

/////////////////////////////////////////////////////////////////////////////

// CLoginDlg dialog

 

 

CLoginDlg::CLoginDlg(CWnd *pParent /*=NULL*/) : CDialog(CLoginDlg::IDD,

pParent)

{

//{{AFX_DATA_INIT(CLoginDlg)

m_szUsername = _T("");

m_szPassword = _T("");

//}}AFX_DATA_INIT

 

}

 

 

void CLoginDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CLoginDlg)

DDX_Text(pDX, IDC_EDIT_USERNAME, m_szUsername);

DDV_MaxChars(pDX, m_szUsername, 10);

DDX_Text(pDX, IDC_EDIT_PASSWORD, m_szPassword);

DDV_MaxChars(pDX, m_szPassword, 10);

//}}AFX_DATA_MAP

 

}

 

 

BEGIN_MESSAGE_MAP(CLoginDlg, CDialog)

//{{AFX_MSG_MAP(CLoginDlg)

ON_BN_CLICKED(IDC_BTN_EXIT, OnBtnExit)

ON_BN_CLICKED(IDC_BTN_LOGIN, OnBtnLogin)

ON_BN_CLICKED(IDC_BTN_REGSITER, OnBtnRegsiter)

ON_MESSAGE(WM_NET_MSG, OnNetMsg)

ON_WM_TIMER()

ON_WM_CANCELMODE()

ON_MESSAGE(DM_GETDEFID, OnGetDefID)

ON_COMMAND(IDK_ENTER, OnEnter)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CLoginDlg message handlers

BOOL CLoginDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// TODO: Add extra initialization here

m_hAccel = ::LoadAccelerators(AfxGetResourceHandle(),

        MAKEINTRESOURCE(IDR_ACCELERATOR));

    ASSERT(m_hAccel);

 

return TRUE;  // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

 

LRESULT CLoginDlg::OnGetDefID(WPARAM wp, LPARAM lp)

{

return MAKELONG(0, DC_HASDEFID);

}

 

void CLoginDlg::OnBtnLogin()

{

// TODO: Add your control notification handler code here

UpdateData();

 

//判断

if (m_szUsername.IsEmpty())

{

MessageBox("用户ID不能为空。", "提示");

GetDlgItem(IDC_EDIT_USERNAME)->SetFocus();

return;

}

if (m_szUsername.GetLength() < 6 || m_szUsername.GetLength() > 10)

{

MessageBox("用户ID的长度必须是6~10,请重新输入。", "提示");

GetDlgItem(IDC_EDIT_USERNAME)->SetFocus();

return;

}

if (m_szPassword.IsEmpty())

{

MessageBox("密码不能为空。", "提示");

GetDlgItem(IDC_EDIT_PASSWORD)->SetFocus();

return;

}

if (m_szPassword.GetLength() < 6 || m_szPassword.GetLength() > 10)

{

MessageBox("密码的长度必须是6~10,请重新输入。", "提示");

GetDlgItem(IDC_EDIT_PASSWORD)->SetFocus();

return;

}

 

//生成登陆消息并发送

LOGIN_INFO loginInfo;

strcpy(loginInfo.userid, m_szUsername.GetBuffer(0));

strcpy(loginInfo.password, m_szPassword.GetBuffer(0));

 

g_netMan.SendLoginInfo(loginInfo);

 

StartAcceptNetMsg();

}

 

void CLoginDlg::OnBtnExit()

{

// TODO: Add your control notification handler code here

OnCancel();

}

 

void CLoginDlg::OnBtnRegsiter()

{

// TODO: Add your control notification handler code here

CRegDlg regDlg;

regDlg.DoModal();

}

 

HRESULT CLoginDlg::OnNetMsg(WPARAM wParam, LPARAM lParam)

{

int retData = 0;

long ret = g_netMan.OnNetMsg(wParam, lParam, this, &retData);

switch (ret)

{

case NETMSG_RET_ERROR_TOCONNECT:

MessageBox("连接服务器出错!","提示");

break;

case PTS_LOGIN_SUCC:

OnOK();

break;

case PTS_LOGIN_FAIL:

{

CString errText;

switch(retData)

{

case EC_LOGIN_PASS_ERROR:

errText = "对不起,登录未成功! 原因:密码错误!";

break;

case EC_LOGIN_USER_LOGINED:

errText = "对不起,登录未成功! 原因:此用户已在别处登录!";

break;

case EC_LOGIN_USER_NOT_EXIST:

errText = "对不起,登录未成功! 原因:此用户ID不存在!";

break;

}

MessageBox(errText, "提示", MB_OK);

}

break;

}

StopAcceptNetMsg();

return 0;

}

 

void CLoginDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

 

CDialog::OnTimer(nIDEvent);

}

 

void CLoginDlg::OnCancelMode()

{

CDialog::OnCancelMode();

 

// TODO: Add your message handler code here

}

 

void CLoginDlg::StartAcceptNetMsg()

{

g_netMan.Start(this);

 

//暂时禁用登录按钮

GetDlgItem(IDC_BTN_LOGIN)->EnableWindow(FALSE);

}

 

void CLoginDlg::StopAcceptNetMsg()

{

g_netMan.Stop(this);

 

//恢复按钮

GetDlgItem(IDC_BTN_LOGIN)->EnableWindow(TRUE);

}

 

void CLoginDlg::OnEnter()

{

// TODO: Add your command handler code here

CWnd * pCurWnd = GetFocus();

if (pCurWnd->m_hWnd == GetDlgItem(IDC_BTN_LOGIN)->m_hWnd)

{

OnBtnLogin();

return;

}

if (pCurWnd->m_hWnd == GetDlgItem(IDC_BTN_EXIT)->m_hWnd)

{

OnBtnExit();

return;

}

if (pCurWnd->m_hWnd == GetDlgItem(IDC_BTN_REGSITER)->m_hWnd)

{

OnBtnRegsiter();

return;

}

CWnd* pWndNext = GetNextDlgTabItem(GetFocus());

if (pWndNext)

{

pWndNext->SetFocus();

}

}

 

BOOL CLoginDlg::PreTranslateMessage(MSG* pMsg)

{

// TODO: Add your specialized code here and/or call the base class

if (WM_KEYFIRST <= pMsg->message &&

        pMsg->message <= WM_KEYLAST)

    {

        HACCEL hAccel = m_hAccel;

        if (hAccel &&

            ::TranslateAccelerator(m_hWnd, hAccel, pMsg))

            return TRUE;

    }

return CDialog::PreTranslateMessage(pMsg);

}

 

 

// MySocket.cpp: implementation of the CMySocket class.

//

//////////////////////////////////////////////////////////////////////

 

#include "StdAfx.h"

#include "MySocket.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

//////////////////////////////////////////////////////////////////////////

// 构造函数

CMySocket::CMySocket()

{

m_sock = NULL;

m_nPort = 0;

m_nSocketType = 0;

m_szAddr.Empty();

ZeroMemory(&m_sockaddr, sizeof(sockaddr_in));

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 析构函数

CMySocket::~CMySocket()

{

ShutDown();

Close();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 初始化SOCKET环境

BOOL CMySocket::StartUp()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

 

wVersionRequested = MAKEWORD(2, 2);

 

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0)

{

/* Tell the user that we could not find a usable */

/* WinSock DLL.  */

return FALSE;

}

 

/* Confirm that the WinSock DLL supports 2.2.*/

/* Note that if the DLL supports versions greater    */

/* than 2.2 in addition to 2.2, it will still return */

/* 2.2 in wVersion since that is the version we  */

/* requested.     */

 

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

/* Tell the user that we could not find a usable */

/* WinSock DLL.  */

WSACleanup();

return FALSE;

}

 

/* The WinSock DLL is acceptable. Proceed. */

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// SOCKET环境卸载

void CMySocket::CleanUp()

{

WSACleanup();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 创建地址

sockaddr_in CMySocket::MakeSockAddr(UINT nPort, LPCTSTR lpszAddress /*= NULL*/)

{

sockaddr_in addr;

ZeroMemory(&addr, sizeof(sockaddr_in));

addr.sin_family = AF_INET;

addr.sin_port = htons(nPort);

if (lpszAddress == NULL)

{

addr.sin_addr.S_un.S_addr = INADDR_ANY;

}

else

{

addr.sin_addr.S_un.S_addr = inet_addr(lpszAddress);

}

return addr;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 关闭

void CMySocket::Close()

{

closesocket(m_sock);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 关闭读写通道

BOOL CMySocket::ShutDown(int nHow /*= SD_BOTH */)

{

if (shutdown(m_sock, nHow) == 0)

{

return TRUE;

}

else

{

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 创建

BOOL CMySocket::Create(UINT nSocketPort /*= 0*/,

   int nSocketType /*= SOCK_STREAM*/,

   LPCTSTR lpszSocketAddress /*= NULL */)

{

m_nPort = nSocketPort;

m_nSocketType = nSocketType;

m_szAddr = lpszSocketAddress;

 

m_sockaddr.sin_family = AF_INET;

m_sockaddr.sin_port = htons(m_nPort);

if (m_szAddr.IsEmpty())

{

m_sockaddr.sin_addr.S_un.S_addr = INADDR_ANY;

}

else

{

m_sockaddr.sin_addr.S_un.S_addr = inet_addr(m_szAddr.GetBuffer(0));

}

 

m_sock = socket(AF_INET, m_nSocketType, 0);

 

if (m_sock == NULL)

{

return FALSE;

}

else

{

return TRUE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送

int CMySocket::SendTo(const void *lpBuf,

  int nBufLen,

  UINT nHostPort,

  LPCTSTR lpszHostAddress /*= NULL*/,

  int nFlags /*= 0*/)

{

sockaddr_in addr = MakeSockAddr(nHostPort, lpszHostAddress);

return SendTo(lpBuf,

  nBufLen,

  (sockaddr *) &addr,

  sizeof(sockaddr_in),

  nFlags);

}

 

int CMySocket::SendTo(const void *lpBuf,

  int nBufLen,

  const SOCKADDR *lpSockAddr,

  int nSockAddrLen,

  int nFlags /*= 0*/)

{

return sendto(m_sock,

  (char *) lpBuf,

  nBufLen,

  nFlags,

  lpSockAddr,

  nSockAddrLen);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 异步选择

BOOL CMySocket::AsyncSelect(HWND hWnd, UINT wMsg, long lEvent)

{

int ret = WSAAsyncSelect(m_sock, hWnd, wMsg, lEvent);

if (ret == 0)

{

return TRUE;

}

else

{

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

 

// MyTab.cpp : implementation file

//

 

#include "stdafx.h"

#include "..\Client\Client.h"

#include "MyTab.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CMyTab

 

CMyTab::CMyTab()

{

m_nItemCount = 0;

m_pCurWnd = NULL;

m_ptTabs.x = 4;

m_ptTabs.y = 28;

}

 

CMyTab::~CMyTab()

{

}

 

 

BEGIN_MESSAGE_MAP(CMyTab, CTabCtrl)

//{{AFX_MSG_MAP(CMyTab)

// NOTE - the ClassWizard will add and remove mapping macros here.

ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange)

ON_NOTIFY_REFLECT(TCN_SELCHANGING, OnSelchanging)

ON_WM_CREATE()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

int CMyTab::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CTabCtrl::OnCreate(lpCreateStruct) == -1)

{

return -1;

}

GetWindowRect(&m_tabRect);

return 0;

}

 

void CMyTab::OnSelchange(NMHDR *pNMHDR, LRESULT *pResult)

{

int iNewTab = GetCurSel();

TCITEM item;

CWnd *pWnd;

item.mask = TCIF_PARAM;

//显示选择的

GetItem(iNewTab, &item);

pWnd = reinterpret_cast<CWnd*>(item.lParam);

ASSERT_VALID(pWnd);

pWnd->ShowWindow(SW_SHOW);

m_pCurWnd = pWnd;

*pResult = 0;

}

 

void CMyTab::OnSelchanging(NMHDR *pNMHDR, LRESULT *pResult)

{

int iNewTab = GetCurSel();

TCITEM item;

CWnd *pWnd;

item.mask = TCIF_PARAM;

 

//隐藏当前TAB

GetItem(iNewTab, &item);

pWnd = reinterpret_cast<CWnd*>(item.lParam);

ASSERT_VALID(pWnd);

pWnd->ShowWindow(SW_HIDE);

*pResult = 0;

}

 

void CMyTab::AddItem(CWnd *pWnd, LPTSTR name)

{

InsertItem(m_nItemCount, pWnd, name);

}

 

void CMyTab::InsertItem( int pos, CWnd *pWnd, LPTSTR name )

{

TCITEM item;

item.mask = TCIF_TEXT | TCIF_PARAM;

item.lParam = (LPARAM) pWnd;

item.pszText = name;

CTabCtrl::InsertItem(pos, &item);

 

pWnd->SetWindowPos(NULL,

   m_ptTabs.x,

   m_ptTabs.y,

   0,

   0,

   SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER);

if (m_nItemCount == 0)

{

pWnd->ShowWindow(SW_SHOW);//显示第一个子窗体

m_pCurWnd = pWnd;

}

else

{

pWnd->ShowWindow(SW_HIDE);

}

m_nItemCount++;

}

 

void CMyTab::ChangeTo(int index)

{

SetCurFocus(index);

}

 

void CMyTab::ChangeTo( CString name )

{

 

}

 

void CMyTab::DelItem( int index )

{

DeleteItem(index);

}

 

void CMyTab::DelItem( CString name )

{

for (int i=0;i<GetItemCount();i++)

{

if (GetItemText(i) == name)

{

DeleteItem(i);

}

}

}

 

CString CMyTab::GetItemText( int index )

{

CString retStr;

TCITEM tci;

GetItem(index, &tci);

retStr = tci.pszText;

return retStr;

}

 

/////////////////////////////////////////////////////////////////////////////

// CMyTab message handlers

 

 

// OutStream.cpp: implementation of the COutStream class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "OutStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

COutStream::COutStream()

{

m_pOutBuf = NULL;

m_pCurOutPtr = NULL;

m_nInitSize = 0;

m_nIncreaseSize = 0;

m_nMaxSize = 0;

// m_nCurSize = 0;

m_pUsedMaxPtr = 0;

}

 

COutStream::~COutStream()

{

if (m_pOutBuf != NULL)

{

delete[] m_pOutBuf;

}

}

 

BOOL COutStream::Create(int initSize /*= DEFAULT_INIT_SIZE*/,

int increaseSize /*= DEFAULT_INCREASE_SIZE*/)

{

//参数检测

if (m_pOutBuf != NULL)

{

TRACE("B COutStream::Create: Only can create once!\n");

return FALSE;

}

if (initSize <= 0)

{

initSize = DEFAULT_INIT_SIZE;

}

if (increaseSize <= 0)

{

initSize = DEFAULT_INCREASE_SIZE;

}

m_nInitSize = initSize;

m_nIncreaseSize = increaseSize;

 

//分配空间

m_pOutBuf = new char[m_nInitSize];

if (m_pOutBuf == NULL)

{

TRACE("B COutStream::Create new char error!\n");

return FALSE;

}

ZeroMemory(m_pOutBuf, m_nInitSize);

 

//指针维护

m_pCurOutPtr = m_pOutBuf;

m_pUsedMaxPtr = m_pCurOutPtr;

 

//大小维护

m_nMaxSize = m_nInitSize;

// m_nCurSize = 0;

return TRUE;

}

 

int COutStream::Write(const void *pData, int DataSize)

{

// 如果会造成数据溢出 则不执行操作

if (m_pCurOutPtr + DataSize - m_pOutBuf > m_nMaxSize)

{

TRACE("B COutStream::Write write range out of buf!\n");

return 0;

}

memcpy(m_pCurOutPtr, pData, DataSize);

 

//游标维护

m_pCurOutPtr += DataSize;

 

//当前大小维护

// m_nCurSize += DataSize;

 

//当前最大指针范围维护

if (m_pCurOutPtr > m_pUsedMaxPtr)

{

m_pUsedMaxPtr = m_pCurOutPtr;

}

return DataSize;

}

 

char * COutStream::GetHead()

{

return m_pOutBuf;

}

 

int COutStream::GetMaxSize()

{

return m_nMaxSize;

}

 

int COutStream::GetSize()

{

return m_pUsedMaxPtr - m_pOutBuf;

}

 

COutStream & COutStream::operator<<(int &value)

{

Write((const char *) &value, sizeof(int));

return *this;

}

 

COutStream & COutStream::operator<<(char &value)

{

Write((const char *) &value, sizeof(char));

return *this;

}

 

COutStream & COutStream::operator<<(char *value)

{

int len = strlen(value) + 1;

Write((const char *) &len, sizeof(len));

Write((const char *) &value, len);

return *this;

}

 

COutStream & COutStream::operator<<(CString &value)

{

int len = value.GetLength() + 1;

Write((const char *) &len, sizeof(len));

Write((const char *) value.GetBuffer(0), len);

return *this;

}

 

COutStream & COutStream::operator<<(long &value)

{

Write((const char *) &value, sizeof(long));

return *this;

}

 

COutStream & COutStream::operator<<(UINT &value)

{

Write((const char *) &value, sizeof(UINT));

return *this;

}

 

COutStream & COutStream::operator<<(ULONG &value)

{

Write((const char *) &value, sizeof(ULONG));

return *this;

}

 

COutStream & COutStream::operator<<(UCHAR &value)

{

Write((const char *) &value, sizeof(UCHAR));

return *this;

}

 

COutStream & COutStream::operator<<(float &value)

{

Write((const char *) &value, sizeof(float));

return *this;

}

 

COutStream & COutStream::operator<<(double &value)

{

Write((const char *) &value, sizeof(double));

return *this;

}

 

BOOL COutStream::MoveCurPtr(int offset, int mode /*= MD_CUR*/)

{

// 注意:此函数未对指针的访问范围进行严格检测 使用时请注意

if (mode == MP_CUR)

{

m_pCurOutPtr += offset;

}

else if (mode == MP_BEG)

{

if (offset < 0)

{

return FALSE;

}

m_pCurOutPtr = m_pOutBuf + offset;

}

else if (mode == MP_END)

{

if (m_nMaxSize == -1)

{

TRACE("B COutStream::MoveCurPtr MP_END mode not support m_nMaxSize = -1\n");

return FALSE;

}

if (offset > 0)

{

return FALSE;

}

  m_pCurOutPtr = m_pOutBuf + offset;

}

 

// 最大使用指针维护

if (m_pCurOutPtr > m_pUsedMaxPtr)

{

m_pUsedMaxPtr = m_pCurOutPtr;

}

 

return TRUE;

}

 

char * COutStream::GetCurPtr()

{

return m_pCurOutPtr;

}

 

void * COutStream::CopyTo( void *buf, int size /*= 0*/ )

{

if (buf == NULL)

{

return NULL;

}

if (size <= 0)

{

size = m_pUsedMaxPtr - m_pOutBuf;

}

memcpy(buf, m_pOutBuf, size);

return buf;

}

 

 

// Packet.cpp: implementation of the CPacket class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Packet.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CPacket::CPacket()

{

m_nType = 0;

m_nVersion = 0;

m_nDataLen = 0;

m_pData = NULL;

}

 

CPacket::~CPacket()

{

if (m_pData != NULL)

{

delete m_pData;

m_pData = NULL;

}

}

 

int CPacket::Pack(char *pData)

{

COutStream cos;

int size = GetPackSize();

cos.Create(size);

// 先写长度

cos << size;

// 再写数据

cos << m_nType << m_nVersion << m_nDataLen;

cos.Write(m_pData, m_nDataLen);

 

// 最后COPY到缓冲

cos.CopyTo(pData);

return cos.GetSize();

}

 

int CPacket::UnPack(const char *pData)

{

if (pData == NULL)

{

return 0;

}

if (m_pData != NULL)

{

delete m_pData;

m_pData = NULL;

}

CInStream cis;

cis.Create(pData);

int packSize = 0;

cis >> packSize;

cis >> m_nType >> m_nVersion >> m_nDataLen;

if (m_nDataLen > 0)

{

m_pData = new char[m_nDataLen];

cis.Read(m_pData, m_nDataLen);

}

return packSize;

}

 

void CPacket::Make( int type, int version, int dataSize, const void *pData )

{

if (m_pData != NULL)

{

delete[] m_pData;

m_pData = NULL;

}

m_nType = type;

m_nVersion = version;

m_nDataLen = dataSize;

if (pData == NULL)

{

m_pData = NULL;

}

else

{

m_pData = new char[m_nDataLen];

memcpy(m_pData, pData, m_nDataLen);

}

}

 

int CPacket::GetDataSize()

{

COutStream cos;

cos.Create(10240);

cos << m_nType << m_nVersion << m_nDataLen;

cos.Write(m_pData, m_nDataLen);

return cos.GetSize();

}

 

int CPacket::GetPackSize()

{

return GetDataSize() + sizeof(int);

}

 

 

// RegDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "RegDlg.h"

#include "RegResultDlg.h"

#include "../Common/UserMan.h"

#include "../Common/packet.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CRegDlg dialog

 

 

CRegDlg::CRegDlg(CWnd *pParent /*=NULL*/) : CDialog(CRegDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CRegDlg)

m_szUsername = _T("");

m_szPassword = _T("");

m_szPassword2 = _T("");

m_szPhone = _T("");

m_szNickname = _T("");

m_tmBrithday = 0;

m_nSex = CUser::SEX_BAOMI;

m_nFaceID = 0;

//}}AFX_DATA_INIT

 

}

 

 

void CRegDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CRegDlg)

DDX_Control(pDX, IDC_LAB_FACE, m_labFace);

DDX_Control(pDX, IDC_COMBO_FACE, m_ccbFaceID);

DDX_Control(pDX, IDC_EDIT_TISHI, m_tishi);

DDX_Text(pDX, IDC_EDIT_USERNAME, m_szUsername);

DDV_MaxChars(pDX, m_szUsername, 8);

DDX_Text(pDX, IDC_EDIT_PASSWORD, m_szPassword);

DDV_MaxChars(pDX, m_szPassword, 10);

DDX_Text(pDX, IDC_EDIT_PASSWORD2, m_szPassword2);

DDV_MaxChars(pDX, m_szPassword2, 10);

DDX_Text(pDX, IDC_EDIT_PHONENUMBER, m_szPhone);

DDV_MaxChars(pDX, m_szPhone, 12);

DDX_Text(pDX, IDC_EDIT_NICKNAME, m_szNickname);

DDV_MaxChars(pDX, m_szNickname, 8);

DDX_DateTimeCtrl(pDX, IDC_DATETIMEPICKER_BIRTHDAY, m_tmBrithday);

DDX_Radio(pDX, IDC_RADIO_SEX_MAIL, m_nSex);

DDX_CBIndex(pDX, IDC_COMBO_FACE, m_nFaceID);

//}}AFX_DATA_MAP

 

}

 

 

BEGIN_MESSAGE_MAP(CRegDlg, CDialog)

//{{AFX_MSG_MAP(CRegDlg)

ON_BN_CLICKED(IDC_BTN_REG, OnBtnReg)

ON_BN_CLICKED(IDC_BTN_EXIT, OnBtnExit)

ON_BN_CLICKED(IDC_BTN_REINPUT, OnBtnReinput)

ON_MESSAGE(WM_NET_MSG, OnNetMsg)

ON_WM_TIMER()

ON_CBN_SELCHANGE(IDC_COMBO_FACE, OnSelchangeComboFace)

ON_MESSAGE(DM_GETDEFID, OnGetDefID)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CRegDlg message handlers

BOOL CRegDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// TODO: Add extra initialization here

CString str;

for (int i = 0; i < MAX_BMP_NUMBER; i++)

{

str.Format("%03d", i);

m_ccbFaceID.InsertString(i, str);

}

m_ccbFaceID.SetCurSel(0);

m_labFace.SetBitmap(g_bmpFaceQQ[0]);

return TRUE;  // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

 

LRESULT CRegDlg::OnGetDefID(WPARAM wp, LPARAM lp)

{

return MAKELONG(0, DC_HASDEFID);

}

 

void CRegDlg::OnBtnReg()

{

// TODO: Add your control notification handler code here

UpdateData();

if (!VerifyData())

{

return;

}

DoReg();

}

 

void CRegDlg::OnBtnExit()

{

// TODO: Add your control notification handler code here

OnCancel();

}

 

void CRegDlg::OnBtnReinput()

{

// TODO: Add your control notification handler code here

m_szUsername = _T("");

m_szPassword = _T("");

m_szPassword2 = _T("");

m_szPhone = _T("");

m_szNickname = _T("");

m_tmBrithday = 0;

m_nFaceID = 0;

m_nSex = 2;

UpdateData(FALSE);

GetDlgItem(IDC_EDIT_USERNAME)->SetFocus();

}

 

BOOL CRegDlg::VerifyData()

{

CString str;

CString buf;

str.Empty();

int errCount = 0;

if (m_szUsername.IsEmpty())

{

errCount++;

buf.Format("%d.姓名不能为空.\r\n", errCount);

str += buf;

}

if (m_szNickname.IsEmpty())

{

errCount++;

buf.Format("%d.昵称不能为空.\r\n", errCount);

str += buf;

}

if (m_szPassword.IsEmpty())

{

errCount++;

buf.Format("%d.密码不能为空.\r\n", errCount);

str += buf;

}

if (m_szPassword.GetLength() < 6)

{

errCount++;

buf.Format("%d.密码的长度不能少于6.\r\n", errCount);

str += buf;

}

if (m_szPassword != m_szPassword2)

{

errCount++;

buf.Format("%d.确认密码不相符.\r\n", errCount);

str += buf;

}

 

//电话号码判断

int phoneLen = m_szPhone.GetLength();

if (m_szPhone.IsEmpty())

{

errCount++;

buf.Format("%d.请填写联系电话.\r\n", errCount);

str += buf;

}

else if (phoneLen != 7 && phoneLen != 8 && phoneLen != 11 && phoneLen != 12)

{

errCount++;

buf.Format("%d.联系电话必须是7位或8位或11位或12位的数字.\r\n", errCount);

str += buf;

}

else if (phoneLen == 12 && m_szPhone[0] != '0')

{

errCount++;

buf.Format("%d.联系电话为12位时,首位必须是0.\r\n", errCount);

str += buf;

}

if (errCount > 0)

{

str.Insert(0, "由于以下原因,注册尚未提交,请重新填写.\r\n");

}

 

if (errCount > 0)

{

m_tishi.SetWindowText(str);

return FALSE;

}

else

{

return TRUE;

}

}

 

void CRegDlg::DoReg()

{

CUser ui;

ui.ID(0);

ui.Name(m_szUsername);

ui.Nickname(m_szNickname);

ui.Password(m_szPassword);

ui.Phone(m_szPhone);

 

ui.FaceID(m_nFaceID);

ui.Sex(m_nSex);

 

ui.Birthday(m_tmBrithday.Format("%Y%I%d"));

 

g_netMan.SendRegEnter(ui);

StartAcceptNetMsg();

}

 

void CRegDlg::StartAcceptNetMsg()

{

g_netMan.Start(this);

 

//暂时禁用登录按钮

GetDlgItem(IDC_BTN_REG)->EnableWindow(FALSE);

GetDlgItem(IDC_BTN_REINPUT)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT_USERNAME)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT_NICKNAME)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT_PASSWORD)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT_PASSWORD2)->EnableWindow(FALSE);

GetDlgItem(IDC_RADIO_SEX_MAIL)->EnableWindow(FALSE);

GetDlgItem(IDC_RADIO_SEX_FEMAIL)->EnableWindow(FALSE);

GetDlgItem(IDC_RADIO_SEX_BAOMI)->EnableWindow(FALSE);

m_ccbFaceID.EnableWindow(FALSE);

GetDlgItem(IDC_DATETIMEPICKER_BIRTHDAY)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT_PHONENUMBER)->EnableWindow(FALSE);

}

 

void CRegDlg::StopAcceptNetMsg()

{

g_netMan.Stop(this);

 

//恢复按钮

//暂时禁用登录按钮

GetDlgItem(IDC_BTN_REG)->EnableWindow(TRUE);

GetDlgItem(IDC_BTN_REINPUT)->EnableWindow(TRUE);

GetDlgItem(IDC_EDIT_USERNAME)->EnableWindow(TRUE);

GetDlgItem(IDC_EDIT_NICKNAME)->EnableWindow(TRUE);

GetDlgItem(IDC_EDIT_PASSWORD)->EnableWindow(TRUE);

GetDlgItem(IDC_EDIT_PASSWORD2)->EnableWindow(TRUE);

GetDlgItem(IDC_RADIO_SEX_MAIL)->EnableWindow(TRUE);

GetDlgItem(IDC_RADIO_SEX_FEMAIL)->EnableWindow(TRUE);

GetDlgItem(IDC_RADIO_SEX_BAOMI)->EnableWindow(TRUE);

m_ccbFaceID.EnableWindow(TRUE);

GetDlgItem(IDC_DATETIMEPICKER_BIRTHDAY)->EnableWindow(TRUE);

GetDlgItem(IDC_EDIT_PHONENUMBER)->EnableWindow(TRUE);

}

 

afx_msg HRESULT CRegDlg::OnNetMsg( WPARAM wParam, LPARAM lParam )

{

int regId = 0;

long ret = g_netMan.OnNetMsg(wParam, lParam, this, ®Id);

 

switch (ret)

{

case NETMSG_RET_ERROR_TOCONNECT:

MessageBox("连接服务器出错!","提示");

break;

case PTS_REG_SUCC:

{

RegSuccess(regId);

}

break;

case PTS_REG_FAIL:

{

MessageBox("注册失败!原因未知!", "提示");

}

break;

}

StopAcceptNetMsg();

return 0;

}

 

void CRegDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

if (nIDEvent == WAIT_MSG_FROM_SERVER_TIMER_ID)

{

StopAcceptNetMsg();

MessageBox("连接服务器超时!请重试!", "提示");

}

CDialog::OnTimer(nIDEvent);

}

 

void CRegDlg::RegSuccess(int num)

{

StopAcceptNetMsg();

CRegResultDlg regResultDlg;

regResultDlg.Show(num,

  "注册成功!请保管好上面已注册的号码!\r\n提示:此号码已复制到剪粘板!");

OnOK();

}

 

void CRegDlg::OnSelchangeComboFace()

{

// TODO: Add your control notification handler code here

int index = m_ccbFaceID.GetCurSel();

m_labFace.SetBitmap(g_bmpFaceQQ[index]);

}

 

 

 

// RegResultDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "RegResultDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CRegResultDlg dialog

 

 

CRegResultDlg::CRegResultDlg(CWnd *pParent /*=NULL*/) : CDialog(CRegResultDlg::IDD,

pParent)

{

//{{AFX_DATA_INIT(CRegResultDlg)

m_nUserNumber = 0;

m_szResult = _T("");

//}}AFX_DATA_INIT

 

}

 

 

void CRegResultDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CRegResultDlg)

DDX_Text(pDX, IDC_EDIT_NUMBER, m_nUserNumber);

DDX_Text(pDX, IDC_EDIT_RESULT, m_szResult);

//}}AFX_DATA_MAP

 

}

 

 

BEGIN_MESSAGE_MAP(CRegResultDlg, CDialog)

//{{AFX_MSG_MAP(CRegResultDlg)

ON_WM_PAINT()

ON_BN_CLICKED(IDC_BTN_BACK, OnBtnBack)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

void CRegResultDlg::Show(int num, CString result)

{

m_nUserNumber = num;

m_szResult = result;

 

DoModal();

}

/////////////////////////////////////////////////////////////////////////////

// CRegResultDlg message handlers

 

BOOL CRegResultDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// TODO: Add extra initialization here

m_font.CreatePointFont(300, "宋体");

 

return TRUE;  // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

 

void CRegResultDlg::OnPaint()

{

CPaintDC dc (this); // device context for painting

 

// TODO: Add your message handler code here

 

CEdit *pEdit = (CEdit *) GetDlgItem(IDC_EDIT_NUMBER);

pEdit->SetFont(&m_font, TRUE);

pEdit->SetSel(0, -1);

pEdit->Copy();

pEdit->SetSel(-1, 0);

// Do not call CDialog::OnPaint() for painting messages

}

 

void CRegResultDlg::OnBtnBack()

{

// TODO: Add your control notification handler code here

OnCancel();

}

 

 

// RoomDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "RoomDlg.h"

#include "../Common/Packet.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CRoomDlg dialog

 

 

CRoomDlg::CRoomDlg(CWnd *pParent /*=NULL*/) : CDialog(CRoomDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CRoomDlg)

// NOTE: the ClassWizard will add member initialization here

//}}AFX_DATA_INIT

m_bFirstShow = TRUE;

}

 

 

void CRoomDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CRoomDlg)

// NOTE: the ClassWizard will add DDX and DDV calls here

//}}AFX_DATA_MAP

 

}

 

 

BEGIN_MESSAGE_MAP(CRoomDlg, CDialog)

//{{AFX_MSG_MAP(CRoomDlg)

ON_WM_SIZE()

ON_WM_PAINT()

ON_WM_CTLCOLOR()

ON_MESSAGE(WM_SEAT_DOWN, OnSeatDown)

ON_MESSAGE(WM_LOOK_ON, OnLookOn)

ON_WM_SETCURSOR()

ON_WM_TIMER()

ON_BN_CLICKED(IDC_BTN_AOTO_SEATDOWN, OnBtnAotoSeatdown)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CRoomDlg message handlers

BOOL CRoomDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// TODO: Add extra initialization here

//创建画笔

m_brushBG.CreateSolidBrush(ROOM_BACK_COLOR);

 

m_tab.Create(CTableDlg::IDD, this);

m_tab.ShowWindow(SW_SHOW);

 

return TRUE;  // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

 

 

void CRoomDlg::OnPaint()

{

CPaintDC dc (this); // device context for painting

 

// TODO: Add your message handler code here

 

if (m_bFirstShow)

{

SendMessage(WM_SIZE, 0, 0);

m_bFirstShow = FALSE;

}

 

// Do not call CDialog::OnPaint() for painting messages

}

 

void CRoomDlg::OnSize(UINT nType, int cx, int cy)

{

CDialog::OnSize(nType, cx, cy);

 

// TODO: Add your message handler code here

if (!IsWindowVisible())

{

return;

}

CRect parRect;

CRect editRect;

 

GetParent()->GetClientRect(&parRect);

SetWindowPos(NULL,

 0,

 0,

 parRect.Width() - 10,

 parRect.Height() - 35,

 SWP_NOMOVE | SWP_NOOWNERZORDER);

}

 

HBRUSH CRoomDlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

 

// TODO: Change any attributes of the DC here

if (nCtlColor == CTLCOLOR_DLG)

{

return m_brushBG;

}

// TODO: Return a different brush if the default is not desired

return hbr;

}

 

HRESULT CRoomDlg::OnSeatDown(WPARAM wParam, LPARAM lParam)

{

int sid = wParam;

int tid = 1;

int uid = g_user.ID();

 

g_netMan.SendSeatDown(uid, tid, sid);

 

return 0;

}

 

HRESULT CRoomDlg::OnLookOn(WPARAM wParam, LPARAM lParam)

{

 

int sid = wParam;

int tid = 1;

int uid = g_user.ID();

 

g_netMan.SendLookOn(uid, tid, sid);

 

return 0;

}

BOOL CRoomDlg::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message)

{

// TODO: Add your message handler code here and/or call default

 

return CDialog::OnSetCursor(pWnd, nHitTest, message);

}

 

void CRoomDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

 

CDialog::OnTimer(nIDEvent);

}

 

void CRoomDlg::OnBtnAotoSeatdown()

{

// TODO: Add your control notification handler code here

if (g_hwndLLKWin != NULL)

{

MessageBox("你已经在游戏中,无法执行些操作!", "提示");

 

return ;

}

CTable * pTable = g_tableMan.GetTable(1);

if (pTable != NULL)

{

if (pTable->TableState() == GAME_PLAYING)

{

MessageBox("没有找到可以坐下的位置!", "提示");

return;

}

for (int i=0;i<6;i++)

{

if (pTable->GetSeat(i).m_nUID == 0)

{

g_netMan.SendSeatDown(g_user.ID(), 1, i);

return ;

}

}

}

MessageBox("没有找到可以坐下的位置!", "提示");

}

 

 

// ScoreList.cpp: implementation of the CScoreList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "ScoreList.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CScoreList::CScoreList()

{

 

}

 

CScoreList::~CScoreList()

{

 

}

 

int CScoreList::Pack( void * pData )

{

COutStream cos;

int dataSize = 0;

int count = GetCount();

cos.Create(count*sizeof(SCORE_INFO)+sizeof(int)*2);

 

cos<<dataSize;

cos<<count;

for (int i=0;i<count;i++)

{

cos.Write(&m_vecScore.at(i), sizeof(SCORE_INFO));

}

dataSize = cos.GetSize() - sizeof(int);

*(int*)cos.GetHead() = dataSize;

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CScoreList::UnPack( const void * pData )

{

m_vecScore.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

int count = 0;

cis>>dataSize>>count;

SCORE_INFO scoreInfo;

for (int i=0;i<count;i++)

{

cis.Read(&scoreInfo, sizeof(SCORE_INFO));

m_vecScore.push_back(scoreInfo);

}

return cis.GetSize();

}

 

void CScoreList::Add( SCORE_INFO& scoreInfo )

{

m_vecScore.push_back(scoreInfo);

}

 

BOOL CScoreList::Del( int uid, int gid )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

for (;begit != endit; ++begit)

{

if (begit->GameID == gid && begit->UID == uid)

{

m_vecScore.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

int CScoreList::GetCount()

{

return m_vecScore.size();

}

 

SCORE_INFO &CScoreList::GetScoreByIndex( int index )

{

return m_vecScore[index];

}

 

void CScoreList::Sort( int mode /*= 0*/ )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

VEC_SCORE_INFO::iterator tmpit = begit+1;

SCORE_INFO tsi;

int swapCount = 0;

do

{

swapCount = 0;

for (;begit != endit - 1; ++begit)

{

tmpit = begit+1;

if (begit->Score > tmpit->Score)

{

tsi = *begit;

*begit = *tmpit;

*tmpit = tsi;

swapCount++;

}

}

} while (swapCount != 0);

}

 

 

// ScoreTop10Dlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "ScoreTop10Dlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CScoreTop10Dlg dialog

 

 

CScoreTop10Dlg::CScoreTop10Dlg(CWnd* pParent /*=NULL*/)

: CDialog(CScoreTop10Dlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CScoreTop10Dlg)

// NOTE: the ClassWizard will add member initialization here

//}}AFX_DATA_INIT

}

 

 

void CScoreTop10Dlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CScoreTop10Dlg)

DDX_Control(pDX, IDC_LIST_SCORE, m_listScore);

//}}AFX_DATA_MAP

}

 

 

BEGIN_MESSAGE_MAP(CScoreTop10Dlg, CDialog)

//{{AFX_MSG_MAP(CScoreTop10Dlg)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

 

/////////////////////////////////////////////////////////////////////////////

// CScoreTop10Dlg message handlers

BOOL CScoreTop10Dlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// TODO: Add extra initialization here

m_listScore.SetExtendedStyle(m_listScore.GetExtendedStyle() |

LVS_EX_FULLROWSELECT |

  LVS_EX_GRIDLINES);

m_listScore.InsertColumn(0, "名次", LVCFMT_CENTER, 50);

m_listScore.InsertColumn(1, "用户ID", LVCFMT_CENTER, 100);

m_listScore.InsertColumn(2, "用户昵称", LVCFMT_CENTER, 100);

m_listScore.InsertColumn(3, "游戏积分", LVCFMT_LEFT, 100);

 

CString str;

for (int i=0;i<m_scoreList.GetCount();i++)

{

str.Format("%d", i+1);

m_listScore.InsertItem(i, str);

str.Format("%d", m_scoreList.GetScoreByIndex(i).UID);

m_listScore.SetItemText(i, 1, str);

str.Format("%s", m_scoreList.GetScoreByIndex(i).NickName);

m_listScore.SetItemText(i, 2, str);

str.Format("%d",m_scoreList.GetScoreByIndex(i).Score);

m_listScore.SetItemText(i, 3, str);

}

return TRUE;  // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

 

void CScoreTop10Dlg::SetScoreList( CScoreList &scoreList )

{

m_scoreList = scoreList;

}

 

 

 

 

// stdafx.cpp : source file that includes just the standard includes

// Client.pch will be the pre-compiled header

// stdafx.obj will contain the pre-compiled type information

 

#include "stdafx.h"

 

 

 

 

// Table.cpp: implementation of the CTable class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Table.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

#include "LLKGameMan.h"

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTable::CTable()

{

m_nTableID = 0;

m_nTableState = GAME_NULL;

}

CTable::~CTable()

{

}

 

VOID CTable::Create(int nTableID, int nSeatCount /*= 6*/)

{

m_nTableID = nTableID;

for (int i = 0; i < 6; i++)

{

m_seat[i].Creat(m_nTableID, i);

}

}

 

BOOL CTable::AddUser(int UID, int SeatID)

{

if (m_seat[SeatID].m_nUID == 0)

{

m_seat[SeatID].m_nUID = UID;

return TRUE;

}

return FALSE;

}

 

BOOL CTable::DelUser(int UID)

{

for (int i = 0; i < 6; i++)

{

if (m_seat[i].m_nUID == UID)

{

m_seat[i].m_nUID = UID;

return TRUE;

}

}

return FALSE;

}

 

int CTable::Pack(char *pData)

{

COutStream cos;

cos.Create(512);

int dataSize = 0;

cos << dataSize;

cos << m_nTableID;

cos << m_nTableState;

cos.Write((char *) m_seat, sizeof(CSeat) * 6);

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

cos.CopyTo(pData);

return cos.GetSize();

}

 

int CTable::UnPack(const char *pData)

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

cis >> m_nTableID;

cis >> m_nTableState;

cis.Read((char *) m_seat, sizeof(CSeat) * 6);

return dataSize + sizeof(int);

}

 

CSeat & CTable::GetSeat(int SeatID)

{

return m_seat[SeatID];

}

 

BOOL CTable::StartGame()

{

m_nTableState = GAME_PLAYING;

for (int i=0;i<6;i++)

{

if (m_seat[i].m_nUID != 0)

{

m_seat[i].m_nState = GAME_PLAYING;

}

}

return TRUE;

}

 

BOOL CTable::EndGame()

{

m_nTableState = GAME_NULL;

for (int i=0;i<6;i++)

{

if (m_seat[i].m_nUID != 0)

{

m_seat[i].m_nState = GAME_NULL;

}

}

return TRUE;

}

 

int CTable::GetUserCount()

{

int count = 0;

for (int i=0; i<6; i++)

{

if (m_seat[i].m_nUID != 0)

{

count++;

}

}

return count;

}

CSeat::CSeat()

{

m_nTableID = 0;

m_nSeatID = 0;

m_nUID = 0;

m_nState = 0;

}

 

void CSeat::Creat(int nTableID, int nSeatID)

{

m_nTableID = nTableID;

m_nSeatID = nSeatID;

}

 

 

// TableDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "Client.h"

#include "TableDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

#define TIMER_REFRESH 100

#define TIMER_REFRESH_TIMEOUT 50

/////////////////////////////////////////////////////////////////////////////

// CTableDlg dialog

 

CTableDlg::CTableDlg(CWnd *pParent /*=NULL*/) : CDialog(CTableDlg::IDD,

pParent)

{

//{{AFX_DATA_INIT(CTableDlg)

//}}AFX_DATA_INIT

m_nCusorType = 0;

m_brushBG.CreateSolidBrush(ROOM_BACK_COLOR);

}

 

 

void CTableDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CTableDlg)

DDX_Control(pDX, IDC_LAB_TABLE, m_labTable);

//}}AFX_DATA_MAP

DDX_Control(pDX, IDC_SEAT_1, m_labFace[0]);

DDX_Control(pDX, IDC_SEAT_2, m_labFace[1]);

DDX_Control(pDX, IDC_SEAT_3, m_labFace[2]);

DDX_Control(pDX, IDC_SEAT_4, m_labFace[3]);

DDX_Control(pDX, IDC_SEAT_5, m_labFace[4]);

DDX_Control(pDX, IDC_SEAT_6, m_labFace[5]);

 

DDX_Control(pDX, IDC_LAB_NAME_1, m_labName[0]);

DDX_Control(pDX, IDC_LAB_NAME_2, m_labName[1]);

DDX_Control(pDX, IDC_LAB_NAME_3, m_labName[2]);

DDX_Control(pDX, IDC_LAB_NAME_4, m_labName[3]);

DDX_Control(pDX, IDC_LAB_NAME_5, m_labName[4]);

DDX_Control(pDX, IDC_LAB_NAME_6, m_labName[5]);

 

DDX_Control(pDX, IDC_LAB_READY5, m_labReady[0]);

DDX_Control(pDX, IDC_LAB_READY4, m_labReady[1]);

DDX_Control(pDX, IDC_LAB_READY3, m_labReady[2]);

DDX_Control(pDX, IDC_LAB_READY2, m_labReady[3]);

DDX_Control(pDX, IDC_LAB_READY1, m_labReady[4]);

DDX_Control(pDX, IDC_LAB_READY0, m_labReady[5]);

}

 

 

BEGIN_MESSAGE_MAP(CTableDlg, CDialog)

//{{AFX_MSG_MAP(CTableDlg)

ON_WM_MOUSEMOVE()

ON_WM_PAINT()

ON_WM_CTLCOLOR()

ON_WM_TIMER()

ON_WM_LBUTTONDOWN()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CTableDlg message handlers

 

BOOL CTableDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// TODO: Add extra initialization here

 

m_bmpTableEmpty.LoadBitmap(IDB_BMP_TABLE_OFF);

m_bmpTablePlaying.LoadBitmap(IDB_BMP_TABLE_ON);

m_bmpNoUser.LoadBitmap(IDB_BMP_NOUSER);

m_bmpReady.LoadBitmap(IDB_BMP_READY);

 

m_hcurHand = LoadCursor(NULL, IDC_HAND);

m_hcurOld = LoadCursor(NULL, IDC_ARROW);

m_hcurNO = LoadCursor(NULL, IDC_NO);

 

for (int i=0;i<6;i++)

{

m_labReady[i].SetBitmap(m_bmpReady);

//m_labReady[i].ShowWindow(SW_HIDE);

}

 

SetTimer(TIMER_REFRESH, TIMER_REFRESH_TIMEOUT, NULL);

return TRUE;  // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

 

void CTableDlg::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

BOOL bInButton = FALSE;

 

int index = PtInSeat(point);

if (index != -1 && g_tableMan.GetTableCount() > 0)

{

// 如果游戏未开始 则不能对已有人的位置操作

if (g_tableMan.GetTable(1)->GetSeat(index).m_nUID != 0 &&

g_tableMan.GetTable(1)->TableState() == GAME_NULL)

{

m_nCusorType = 2;

}

// 如果游戏已开始 则不能对没有人的位置操作

else if (g_tableMan.GetTable(1)->TableState() == GAME_PLAYING &&

g_tableMan.GetTable(1)->GetSeat(index).m_nUID == 0)

{

m_nCusorType = 2;

}

else

{

m_nCusorType = 1;

}

bInButton = TRUE;

}

 

if (!bInButton)

{

m_nCusorType = 0;

}

 

switch (m_nCusorType)

{

case 0:

SetCursor(m_hcurOld);

break;

case 1:

SetCursor(m_hcurHand);

break;

case 2:

SetCursor(m_hcurNO);

break;

}

CDialog::OnMouseMove(nFlags, point);

}

 

void CTableDlg::OnPaint()

{

CPaintDC dc (this); // device context for painting

 

// TODO: Add your message handler code here

 

// Do not call CDialog::OnPaint() for painting messages

}

 

HBRUSH CTableDlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

 

// TODO: Change any attributes of the DC here

if (nCtlColor == CTLCOLOR_STATIC)

{

pDC->SetBkMode(TRANSPARENT);

pDC->SetBkColor(ROOM_BACK_COLOR);

pDC->SetTextColor(RGB(255, 255, 255));

}

// TODO: Return a different brush if the default is not desired

return m_brushBG;

}

 

void CTableDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

if (nIDEvent == TIMER_REFRESH)

{

do

{

if (g_bTableUpdate == FALSE)

{

break;

}

if (g_tableMan.GetTableCount() > 0)

{

for (int i = 0; i < 6; i++)

{

int uid = g_tableMan.GetTable(1)->GetSeat(i).m_nUID;

int faceid = 0;

CUser *pUser = NULL;

if (uid != 0)

{

pUser = g_userMan.GetUser(uid);

if (pUser != NULL)

{

m_labFace[i].SetBitmap(g_bmpFaceOnline[pUser->FaceID()]);

m_labName[i].SetWindowText(pUser->Nickname());

}

}

if (uid == 0 || pUser == NULL)

{

m_labFace[i].SetBitmap(m_bmpNoUser);

m_labName[i].SetWindowText("");

}

}

for (int j=0;j<6;j++)

{

if (g_tableMan.GetTable(1)->TableState() != GAME_PLAYING)

{

m_labReady[j].ShowWindow(SW_HIDE);

}

else

{

if (g_tableMan.GetTable(1)->GetSeat(j).m_nState == GAME_READY)

{

m_labReady[j].ShowWindow(SW_SHOW);

}

}

}

 

if (g_tableMan.GetTable(1)->TableState() ==

GAME_PLAYING)

{

m_labTable.SetBitmap(m_bmpTablePlaying);

}

else

{

m_labTable.SetBitmap(m_bmpTableEmpty);

}

}

g_bTableUpdate = FALSE;

}

while (0);

}

CDialog::OnTimer(nIDEvent);

}

 

void CTableDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

int index = PtInSeat(point);

if (index != -1)

{

CTable *pTable = g_tableMan.GetTable(1);

int uid = 0;

int sid = index;

if (pTable != NULL)

{

uid = pTable->GetSeat(index).m_nUID;

 

if (uid == 0 && pTable->TableState() == GAME_NULL)

{

if (g_hwndLLKWin != NULL)

{

MessageBox("游戏运行时无法换座位, 请先退出再换座位!", "提示");

 

}

else

{

::SendMessage(GetParent()->m_hWnd,

  WM_SEAT_DOWN,

  (WPARAM) index,

  0);

}

}

else if (uid != 0 && pTable->TableState() == GAME_PLAYING)

{

if (g_hwndLLKWin != NULL)

{

MessageBox("游戏运行时无法旁观, 请先退出后再进行操作!", "提示");

}

else

{

::SendMessage(GetParent()->m_hWnd,

  WM_LOOK_ON,

  (WPARAM) index,

  0);

}

}

}

}

CDialog::OnLButtonDown(nFlags, point);

}

 

int CTableDlg::PtInSeat(CPoint pt)

{

CRect rect;

for (int i = 0; i < 6; i++)

{

m_labFace[i].GetWindowRect(&rect);

ScreenToClient(&rect);

if (rect.PtInRect(pt))

{

return i;

}

}

return -1;

}

 

BOOL CTableDlg::PreCreateWindow(CREATESTRUCT &cs)

{

// TODO: Add your specialized code here and/or call the base class

 

return CDialog::PreCreateWindow(cs);

}

 

 

// TableIDList.cpp: implementation of the CTableIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableIDList.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableIDList::CTableIDList()

{

}

 

CTableIDList::~CTableIDList()

{

}

 

 

// TableList.cpp: implementation of the CTableList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableList.h"

#include "LLKGameMan.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableList::CTableList()

{

}

 

CTableList::~CTableList()

{

}

 

BOOL CTableList::AddUser(int UID, int nTableID, int nSeatID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit->AddUser(UID, nSeatID);

}

}

return FALSE;

}

 

BOOL CTableList::DelUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

// 如果该位置上的id是要删除的id 则删除

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nUID = 0;

// 删除之后 看此桌上的人数是不是为0 没人的话桌面状态初始化

if (begit->GetUserCount() == 0)

{

begit->TableState(GAME_NULL);

}

return TRUE;

}

}

 

}

return FALSE;

}

 

BOOL CTableList::SetUserState(int UID, int nState)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nState = nState;

return TRUE;

}

}

}

return TRUE;

}

 

BOOL CTableList::AddTable(CTable &table)

{

m_vecTable.push_back(table);

return TRUE;

}

 

BOOL CTableList::DelTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

m_vecTable.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

 

CTable * CTableList::GetTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit;

}

}

return NULL;

}

 

int CTableList::Pack(char *pData)

{

COutStream cos;

cos.Create();

int dataSize = 0;

cos << dataSize;

int tableCount = m_vecTable.size();

cos << tableCount;

for (int i = 0; i < tableCount; i++)

{

char buf[512] ={0};

int len = m_vecTable[i].Pack(buf);

cos.Write(buf, len);

}

 

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

 

return dataSize + sizeof(int);

}

 

int CTableList::UnPack(const char *pData)

{

m_vecTable.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

int tableCount = 0;

cis >> tableCount;

for (int i = 0; i < tableCount; i++)

{

CTable table;

const char *p = (const char *)cis.GetCurPtr();

int len = table.UnPack(p);

m_vecTable.push_back(table);

cis.MoveCurPtr(len);

}

return cis.GetSize();

}

 

int CTableList::GetTableCount()

{

return m_vecTable.size();

}

 

BOOL CTableList::HasUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

return TRUE;

}

}

}

return FALSE;

}

 

 

// TableMan.cpp: implementation of the CTableMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableMan::CTableMan()

{

}

 

CTableMan::~CTableMan()

{

}

 

BOOL CTableMan::AddTable(CTable &table)

{

return m_tablelist.AddTable(table);

}

 

BOOL CTableMan::DelTable(int nTableID)

{

return m_tablelist.DelTable(nTableID);

}

 

BOOL CTableMan::AddUser(int UID, int nTableID, int nSeatID)

{

return m_tablelist.AddUser(UID, nTableID, nSeatID);

}

 

BOOL CTableMan::DelUser(int UID)

{

return m_tablelist.DelUser(UID);

}

 

BOOL CTableMan::SetUserState(int UID, int nState)

{

return m_tablelist.SetUserState(UID, nState);

}

 

int CTableMan::Pack(char *pData)

{

return m_tablelist.Pack(pData);

}

 

int CTableMan::UnPack(const char *pData)

{

return m_tablelist.UnPack(pData);

}

 

CTable * CTableMan::GetTable(int nTableID)

{

return m_tablelist.GetTable(nTableID);

}

 

int CTableMan::GetTableCount()

{

return m_tablelist.GetTableCount();

}

 

BOOL CTableMan::HasUser(int UID)

{

return m_tablelist.HasUser(UID);

}

 

BOOL CTableMan::StartGame( int nTableID /*= 1*/ )

{

CTable * pTable = GetTable(nTableID);

pTable->StartGame();

return TRUE;

}

 

BOOL CTableMan::EndGame( int nTableID /*= 1*/ )

{

CTable * pTable = GetTable(nTableID);

pTable->EndGame();

return TRUE;

}

 

 

 

/*/////////////////////////////////////////////////////////////////////////

说明:UCode 文件,一些简单常用功能函数合集。

版本:1.0

创建:[4/5/2009 Dufeng]

修改:

*///////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 预处理

 

#include "StdAfx.h"

#include "UCode.h"

#include <windows.h>

#include <stdio.h>

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 宏定义

//#define BUFFER_SIZE 256

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:OnlyRunOne,只允许运行一个实例。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:TURE为可运行,FALSE为已经在运行

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

BOOL OnlyRunOne(WCHAR *_mutexName)

{

CreateMutexW(NULL, FALSE, _mutexName);

 

if (GetLastError() == ERROR_ALREADY_EXISTS)

{

return FALSE;

}

else

{

return TRUE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,获取上次的错误信息,会自动格式化信息内容。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

 

VOID GetLastErrorMsg(TCHAR *szBuf)

{

LPVOID lpMsgBuf;

DWORD dw = GetLastError();

 

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

  NULL,

  dw,

  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

  (LPTSTR) & lpMsgBuf,

  0,

  NULL);

 

sprintf(szBuf, "错误 %d: %s", dw, lpMsgBuf);

 

LocalFree(lpMsgBuf);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,检测键盘状态。

// 版本:1.0

// 创建:[4/6/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

 

BOOL GetOneKeyState(BYTE _key)

{

BYTE keyState[256];

 

GetKeyboardState((LPBYTE) & keyState);

return (keyState[_key] & 1);

}

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的的路径 不包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppPath(char *szFilePath)

{

char szTempFilePath[BUFFER_SIZE] ={0};

GetModuleFileName(NULL, szTempFilePath, BUFFER_SIZE - 1);

size_t nTemp = strlen(szTempFilePath) -

  strlen(strrchr(szTempFilePath, '\\'));

if (nTemp != -1)

{

szTempFilePath[nTemp + 1] = 0;

}

strcpy(szFilePath, szTempFilePath);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的全路径 包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppFileFullPathName(char *szFileName)

{

GetModuleFileName(NULL, szFileName, BUFFER_SIZE - 1);

}

//////////////////////////////////////////////////////////////////////////

 

 

 

// User.cpp: implementation of the CUser class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "User.h"

 

#include <winsock2.h>

#include "../Basic/OutStream.h"

#include "../Basic/InStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

int CUser::MAX_PACK_SIZE = sizeof(int) * 10 +

  sizeof(sockaddr) +

  100;

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUser::CUser()

{

m_nID = 0;

m_szName.Empty();

m_szNickname.Empty();

m_szPassword.Empty();

m_nSex = SEX_BAOMI;

m_szBirthday.Empty();

m_szPhone.Empty();

m_nState = STATE_OFFLINE;

m_nFaceID = 0;

// 在线状态的信息

ZeroMemory(&m_addr, sizeof(sockaddr));

m_nGameState = GAME_STATE_NOTHING;

m_nRoomID = 0;

m_nTableID = 0;

m_nSeatID = 0;

 

m_nLLKScore = 0;

}

 

CUser::~CUser()

{

}

 

//////////////////////////////////////////////////////////////////////////

// 用户信息打包

// 参数:pData 存放用户打包信息的地址

// 返回:包的大小

int CUser::Pack(char *pData)

{

// 申请buf

COutStream cos;

cos.Create(MAX_PACK_SIZE);

int dataSize = 0;

// 先写大小 为0 最后修改

cos << dataSize;

// 再写数据

cos << m_nID << m_szName << m_szNickname << m_szPassword << m_nSex

<< m_szBirthday << m_nState << m_nFaceID;

cos.Write(&m_addr, sizeof(sockaddr));

cos << m_nGameState << m_nRoomID << m_nTableID << m_nSeatID << m_nLLKScore;

 

int packSize = cos.GetSize();

// 写入长度

*(int *) cos.GetHead() = packSize - sizeof(int);

 

// 向缓冲写入

cos.CopyTo(pData);

return packSize;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 解包

// 参数:pData 包数据的地址 DataSize 包数据的大小

// 返回:读取包的长度 包括长度变量

int CUser::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int DataSize = 0;

cis >> DataSize;

cis >> m_nID >> m_szName >> m_szNickname >> m_szPassword >> m_nSex

>> m_szBirthday >> m_nState >> m_nFaceID;

cis.Read(&m_addr, sizeof(sockaddr));

cis >> m_nGameState >> m_nRoomID >> m_nTableID >> m_nSeatID >> m_nLLKScore;

 

return DataSize + sizeof(int);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到打包后数据的大小

int CUser::GetPackSize()

{

return sizeof(int) + GetDataSize();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到数据大小

int CUser::GetDataSize()

{

// 先计算数据的大小

int dataSize = 0;

dataSize += sizeof(int); // m_nID

dataSize += sizeof(int) + m_szName.GetLength() + 1;

dataSize += sizeof(int) + m_szNickname.GetLength() + 1;

dataSize += sizeof(int) + m_szPassword.GetLength() + 1;

dataSize += sizeof(int); //m_nSex

dataSize += sizeof(int) + m_szBirthday.GetLength() + 1;

dataSize += sizeof(int) + m_szPhone.GetLength() + 1;

dataSize += sizeof(int); //m_nState;

dataSize += sizeof(int); //m_nFaceID;

 

// 在线状态的信息

dataSize += sizeof(sockaddr); //m_addr;

dataSize += sizeof(int); //m_nGameState;

dataSize += sizeof(int); //m_nRoomID;

dataSize += sizeof(int); //m_nTableID;

dataSize += sizeof(int); //m_nSeatID;

 

//以下是模拟打包返回长度 效率问题不使用

/*

COutStream cos;

cos.Create(1024);

cos << m_nID << m_szName << m_szNickname << m_szPassword << m_nSex

<< m_szBirthday << m_nState << m_nFaceID;

cos.Write(&m_addr, sizeof(sockaddr));

cos << m_nGameState << m_nRoomID << m_nTableID << m_nSeatID;

return cos.GetSize();

 

*/

return dataSize;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 地址的对比函数

// 参数:要比较的两个地址指针

// 返回:同则返回TRUE

BOOL CUser::AddrCmp(const sockaddr *addr1, const sockaddr *addr2)

{

for (int i = 0; i < sizeof(sockaddr); i++)

{

if (*((char *) (addr1) + i) != *((char *) (addr2) + i))

{

return FALSE;

}

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

// UserList.cpp: implementation of the CUserList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserList.h"

#include "../Basic/OutStream.h"

#include "../Basic/InStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserList::CUserList()

{

}

 

CUserList::~CUserList()

{

}

 

BOOL CUserList::AddUser(CUser &user)

{

MAP_USER::_Pairib ret = m_mapUser.insert(MAP_USER::value_type(user.m_nID,

user));

if (ret.second == true)

{

return TRUE;

}

else

{

return FALSE;

}

}

 

BOOL CUserList::DelUser(int UID)

{

int ret = m_mapUser.erase(UID);

if (ret == 1)

{

return TRUE;

}

else

{

return FALSE;

}

}

 

CUser * CUserList::GetUser(int UID)

{

MAP_USER::iterator itRet = m_mapUser.find(UID);

if (itRet == m_mapUser.end())

{

return NULL;

}

else

{

return &itRet->second;

}

}

 

 

CUser * CUserList::GetUserByIndex(int index)

{

if (index < 0 || index >= GetUserCount())

{

return NULL;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

int i = 0;

for (; begiter != enditer; ++begiter)

{

if (i == index)

{

return &begiter->second;

}

i++;

}

 

return NULL;

}

 

int CUserList::GetUserIDByAddr(const sockaddr &addr)

{

MAP_USER::iterator it;

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

if (CUser::AddrCmp(&addr, &it->second.m_addr))

{

return it->first;

}

}

return 0;

}

 

BOOL CUserList::HasUser(int UID)

{

CUser *pUser = GetUser(UID);

if (pUser == NULL)

{

return FALSE;

}

else

{

return TRUE;

}

}

 

int CUserList::GetUserCount()

{

return m_mapUser.size();

}

 

void CUserList::Empty()

{

m_mapUser.clear();

}

 

int CUserList::Pack(char *pData)

{

int userCount = GetUserCount();

COutStream cos;

cos.Create(CUser::MAX_PACK_SIZE * userCount);

int dataSize = 0;

cos << dataSize;

cos << userCount;

 

MAP_USER::iterator it;

char *buf = new char[CUser::MAX_PACK_SIZE];

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

//清空缓冲

ZeroMemory(buf, CUser::MAX_PACK_SIZE);

//打包函数已经把大小写入了 所以无需再写长度了

int len = it->second.Pack(buf);

cos.Write(buf, len);

}

cos.CopyTo(pData);

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

delete[] buf;

return dataSize + sizeof(int) ;

}

 

int CUserList::UnPack(const char *pData)

{

if (pData == NULL)

{

return 0;

}

CInStream cis;

cis.Create(pData);

int DataSize = 0;

cis >> DataSize;

Empty();

 

int userCount = 0;

cis >> userCount;

int packSize = 0;

for (int i = 0; i < userCount; i++)

{

CUser user;

packSize = user.UnPack(cis.GetCurPtr());

cis.MoveCurPtr(packSize);

m_mapUser.insert(MAP_USER::value_type(user.m_nID, user));

}

 

return cis.GetSize();

}

 

int CUserList::GetPackSize()

{

return GetDataSize() + sizeof(int);

}

 

int CUserList::GetDataSize()

{

int DataSize = 0;

DataSize += sizeof(int); //用户个数存放

 

MAP_USER::iterator it;

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

DataSize += it->second.GetPackSize(); //数据包大小 已包含数据大小

}

return DataSize;

}

 

CUser * CUserList::GetUserByAddr( const sockaddr &addr )

{

if (GetUserCount() == 0)

{

return NULL;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

for (; begiter != enditer; ++begiter)

{

if (CUser::AddrCmp(&begiter->second.m_addr, &addr))

{

return &begiter->second;

}

}

 

return NULL;

}

 

void CUserList::AddScore( int UID, int score )

{

if (GetUserCount() == 0)

{

return ;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

for (; begiter != enditer; ++begiter)

{

if (begiter->second.m_nID == UID)

{

begiter->second.m_nLLKScore+=score;

}

}

 

return ;

}

 

 

// UserMan.cpp: implementation of the CUserMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserMan::CUserMan()

{

}

 

CUserMan::~CUserMan()

{

}

 

BOOL CUserMan::AddUser( CUser &user )

{

return m_userlist.AddUser(user);

}

 

BOOL CUserMan::HasUser(int UID)

{

return m_userlist.HasUser(UID);

}

 

BOOL CUserMan::DelUser(int UID)

{

return m_userlist.DelUser(UID);

}

 

BOOL CUserMan::SetUserState(int UID, int state)

{

CUser *pUser = m_userlist.GetUser(UID);

if (pUser == NULL)

{

return FALSE;

}

else

{

pUser->State(state);

}

return TRUE;

}

 

CUser * CUserMan::GetUser(int UID)

{

return m_userlist.GetUser(UID);

}

 

int CUserMan::GetUserID(const sockaddr &addr)

{

return m_userlist.GetUserIDByAddr(addr);

}

 

CUserList CUserMan::GetUserList(int mode /*= 0*/, WPARAM wParam /*= 0*/)

{

return m_userlist;

}

 

BOOL CUserMan::AddUserIDList(CUserIDList *pUserIDList)

{

SET_CUSERIDLIST::_Pairib retPair = m_setUserIDList.insert(SET_CUSERIDLIST::value_type(pUserIDList));

if (retPair.second == false)

{

return FALSE;

}

else

{

return TRUE;

}

}

 

void CUserMan::DelUserIDList(CUserIDList *pUserIDList)

{

SET_CUSERIDLIST::iterator begit = m_setUserIDList.begin();

SET_CUSERIDLIST::iterator endit = m_setUserIDList.end();

 

for (; begit != endit; ++begit)

{

if (*begit == pUserIDList)

{

m_setUserIDList.erase(begit);

break;

}

}

}

 

int CUserMan::Pack(char *pData)

{

return m_userlist.Pack(pData);

}

 

int CUserMan::UnPack(const char *pData)

{

return m_userlist.UnPack(pData);

}

 

int CUserMan::GetUserCount()

{

return m_userlist.GetUserCount();

}

 

// sockaddr CUserMan::GetUserAddr(int UID)

// {

// return m_userlist.GetUser(UID)->Addr();

// }

 

CUser * CUserMan::GetUserByIndex(int index)

{

return m_userlist.GetUserByIndex(index);

}

 

CUser * CUserMan::GetUserByAddr( const sockaddr &addr )

{

return m_userlist.GetUserByAddr(addr);

}

 

void CUserMan::AddScore( int UID, int score )

{

m_userlist.AddScore(UID, score);

}

 

 

// WMLink.cpp: implementation of the CWMLink class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "WMLink.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CWMLink::CWMLink()

{

m_myHwnd = NULL;

m_yourHwnd = NULL;

}

 

CWMLink::~CWMLink()

{

 

}

 

void CWMLink::Create( HWND myHwnd, HWND youHwnd )

{

m_myHwnd = myHwnd;

m_yourHwnd = youHwnd;

}

 

BOOL CWMLink::Send( DWORD nType, DWORD nSize, LPVOID pData )

{

COPYDATASTRUCT cds;

cds.dwData = nType;

cds.cbData = nSize;

cds.lpData = pData;

return ::SendMessage(m_yourHwnd, WM_COPYDATA, (WPARAM)m_myHwnd, (LPARAM)&cds);

}

 

BOOL CWMLink::Post( DWORD nType, DWORD nSize, LPVOID pData )

{

COPYDATASTRUCT cds;

cds.dwData = nType;

cds.cbData = nSize;

cds.lpData = pData;

return ::PostMessage(m_yourHwnd, WM_COPYDATA, (WPARAM)m_myHwnd, (LPARAM)&cds);

}

 

 

 

// Client.h : main header file for the CLIENT application

//

 

#if !defined(AFX_CLIENT_H__C4D071E8_27C6_49BD_BD46_7714640760FE__INCLUDED_)

#define AFX_CLIENT_H__C4D071E8_27C6_49BD_BD46_7714640760FE__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#ifndef __AFXWIN_H__

#error include 'stdafx.h' before including this file for PCH

#endif

 

#include "resource.h" // main symbols

#include "../Basic/MySocket.h"

#include "../Common/UserMan.h"

#include "../Common/TableMan.h"

#include "../Common/LLKGameMan.h"

#include "../Common/ScoreList.h"

#include "ClientNetMan.h"

#include "ClientWMLink.h"

/////////////////////////////////////////////////////////////////////////////

// CClientApp:

// See Client.cpp for the implementation of this class

//

#define MAX_BMP_NUMBER 173

 

// 图片资源

extern CBitmap g_bmpFaceOnline[MAX_BMP_NUMBER];

extern CBitmap g_bmpFaceOffline[MAX_BMP_NUMBER];

extern CBitmap g_bmpFaceQQ[MAX_BMP_NUMBER];

 

// 信息与管理类

 

extern CUser g_user;

extern CTableMan g_tableMan;

extern CUserMan g_userMan;

extern BOOL g_bTableUpdate;

 

extern CLLKGameMan g_llkGameMan;

extern CClientNetMan g_netMan;

extern CClientWMLink g_clientWMLink;

extern CScoreList g_scoreTop10List;

 

extern HWND g_hwndLLKWin;

 

 

class CClientApp : public CWinApp

{

public:

CClientApp();

void ReadSetting();

void ReadImage();

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CClientApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

 

// Implementation

 

//{{AFX_MSG(CClientApp)

// NOTE - the ClassWizard will add and remove member functions here.

//    DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_CLIENT_H__C4D071E8_27C6_49BD_BD46_7714640760FE__INCLUDED_)

 

 

// ClientDlg.h : header file

//

 

#if !defined(AFX_CLIENTDLG_H__F0F8D2E8_E6D8_45F5_8496_D29F8BD85C9B__INCLUDED_)

#define AFX_CLIENTDLG_H__F0F8D2E8_E6D8_45F5_8496_D29F8BD85C9B__INCLUDED_

 

#include "HallDlg.h"

#include "RoomDlg.h"

#include "ScoreTop10Dlg.h"

#include "../Basic/MyTab.h"

#include "../Common/UserMan.h"

#include "../Common/TableMan.h"

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

/////////////////////////////////////////////////////////////////////////////

// CClientDlg dialog

 

class CClientDlg : public CDialog

{

// Construction

public:

CClientDlg(CWnd *pParent = NULL); // standard constructor

 

// Dialog Data

//{{AFX_DATA(CClientDlg)

enum { IDD = IDD_CLIENT_DIALOG };

CStatic m_labScore;

CStatic m_labFace;

CStatic m_labUserID;

CStatic m_labNickName;

CStatic m_separator;

CMyTab m_tabMain;

CTreeCtrl m_treeServer;

//}}AFX_DATA

 

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CClientDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

HICON m_hIcon;

CHallDlg *m_pHallDlg;

CRoomDlg *m_pRoomDlg;

CImageList m_imglistTreeImg;

 

DWORD m_gameProcessID;

// Generated message map functions

//{{AFX_MSG(CClientDlg)

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

afx_msg void OnSize(UINT nType, int cx, int cy);

afx_msg LRESULT OnGetDefID(WPARAM wParam, LPARAM lParam);

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

afx_msg void OnSizing(UINT fwSide, LPRECT pRect);

afx_msg void OnClickTreeServer(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnSelchangedTreeServer(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnDblclkTreeServer(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnClose();

afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);

afx_msg void OnDestroy();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

void ShowUserInfo();

HRESULT OnNetMsg(WPARAM wParam, LPARAM lParam);

void StartGame(int mainUserID, BOOL bIsLookOn = FALSE);

void OnGameExit();

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_CLIENTDLG_H__F0F8D2E8_E6D8_45F5_8496_D29F8BD85C9B__INCLUDED_)

 

 

// ClientNetMan.h: interface for the CClientNetMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_CLIENTNETMAN_H__569C5E9B_EFFE_49B2_A810_B9B827601036__INCLUDED_)

#define AFX_CLIENTNETMAN_H__569C5E9B_EFFE_49B2_A810_B9B827601036__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define NETMSG_TIMEOUT 5000

 

// 网络管理类的两种模式 是在服务器超时时的处理 不退出模式是不即使发服务器超时也不停止接收网络消息

// #define NETMAN_MODE_NOTEXIT 0

// #define NETMAN_MODE_EXT 1

 

// 处理完网络事件后的返回

#define NETMSG_RET_ERROR -1 //发生错误

#define NETMSG_RET_ERROR_TOCONNECT -2 //连接服务器出错

 

class CClientNetMan

{

public:

CLIENT_SETTING m_setting;

public:

CClientNetMan();

virtual ~CClientNetMan();

BOOL Init();

BOOL SendTo();

void EasySendToServer(int nType,

 int dataSize = 0,

 const void *pData = NULL);

void Start(CWnd *pWnd, int mode = 0);

void Stop(CWnd *pWnd);

void Stop(HWND hwnd);

 

//业务处理

// 发送相关函数

void SendRegEnter(CUser &user);

void SendLoginInfo(LOGIN_INFO &loginInfo);

void SendSeatDown(int UID, int tid, int sid);

void SendLookOn(int UID, int tid, int sid);

void SendGetLoginUserInfo();

void SendGetTableInfo();

void SendGetUserList();

void SendGetGameInfo();

void SendCheckOnline();

void SendExit();

void SendGameSingleInfo(CLLK *llk);

void SendStandUp();

void SendGetTop10();

void SendReady();

 

// 接收处理

HRESULT OnNetMsg(WPARAM wParam,

 LPARAM lParam,

 CWnd *pWnd = NULL,

 void *pData = NULL);

 

 

 

private:

int m_mode;

CWnd *m_pWnd;

CMySocket m_mysock;

};

 

#endif // !defined(AFX_CLIENTNETMAN_H__569C5E9B_EFFE_49B2_A810_B9B827601036__INCLUDED_)

 

 

 

// ClientWMLink.h: interface for the CClientWMLink class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_CLIENTWMLINK_H__DC535B54_66B4_4911_87DD_17F6FF979EC8__INCLUDED_)

#define AFX_CLIENTWMLINK_H__DC535B54_66B4_4911_87DD_17F6FF979EC8__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "..\COMMON\WMLink.h"

 

class CClientWMLink : public CWMLink  

{

public:

CClientWMLink();

virtual ~CClientWMLink();

INT OnRecv(CWnd *pWnd, COPYDATASTRUCT *pCopyData);

void SendGameInfo(CLLKGameMan * llkGM);

void SendBeginMsg(CLLKGameMan * pLLKGM);

void SendEndMsg(CPacket &pac);

 

};

 

#endif // !defined(AFX_CLIENTWMLINK_H__DC535B54_66B4_4911_87DD_17F6FF979EC8__INCLUDED_)

 

 

#if !defined(AFX_HALLDLG_H__0667DA21_4B27_40D0_BD4E_2D805A0242A3__INCLUDED_)

#define AFX_HALLDLG_H__0667DA21_4B27_40D0_BD4E_2D805A0242A3__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// HallDlg.h : header file

//

#include <afxhtml.h>

/////////////////////////////////////////////////////////////////////////////

// CHallDlg dialog

 

class CHallDlg : public CDialog

{

// Construction

public:

CHallDlg(CWnd *pParent = NULL);   // standard constructor

 

// Dialog Data

//{{AFX_DATA(CHallDlg)

enum { IDD = IDD_DLG_HALL };

CEdit m_text;

//}}AFX_DATA

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CHallDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

BOOL m_bFirstShow;

// Generated message map functions

//{{AFX_MSG(CHallDlg)

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

afx_msg void OnCancelMode();

afx_msg void OnSize(UINT nType, int cx, int cy);

afx_msg void OnPaint();

afx_msg HRESULT OnGetDefId(WPARAM wParam, LPARAM lParam);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_HALLDLG_H__0667DA21_4B27_40D0_BD4E_2D805A0242A3__INCLUDED_)

 

 

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 预处理

#pragma once

#include <afx.h>

#include <Windows.h>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// CIni

// class CIni

// {

// public:

// CIni();

// CIni(CString strIniFilePath);

// ~CIni();

// public:

// BOOL Creat(CString strIniFilePath);

//

// }

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

CString GetIniString(CString sec,

 CString key,

 CString str,

 CString sIniFileName);

 

BOOL SetIniString(CString sec, CString key, CString str, CString sIniFileName);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

#if !defined(AFX_LOGINDLG_H__03A5CEB0_7D72_4B27_B994_E7A4B7F8C48C__INCLUDED_)

#define AFX_LOGINDLG_H__03A5CEB0_7D72_4B27_B994_E7A4B7F8C48C__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// LoginDlg.h : header file

//

 

#include "../Basic/MySocket.h"

 

/////////////////////////////////////////////////////////////////////////////

// CLoginDlg dialog

 

class CLoginDlg : public CDialog

{

// Construction

public:

CLoginDlg(CWnd *pParent = NULL);   // standard constructor

 

// Dialog Data

//{{AFX_DATA(CLoginDlg)

enum { IDD = IDD_DLG_LOGIN };

CString m_szUsername;

CString m_szPassword;

//}}AFX_DATA

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CLoginDlg)

public:

virtual BOOL PreTranslateMessage(MSG* pMsg);

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

// Implementation

void StartAcceptNetMsg();

void StopAcceptNetMsg();

protected:

HACCEL m_hAccel;

// Generated message map functions

//{{AFX_MSG(CLoginDlg)

afx_msg void OnBtnExit();

afx_msg void OnBtnLogin();

afx_msg void OnBtnRegsiter();

afx_msg HRESULT OnNetMsg(WPARAM wParam, LPARAM lParam);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnCancelMode();

virtual BOOL OnInitDialog();

afx_msg LRESULT OnGetDefID(WPARAM wp, LPARAM lp);

afx_msg void OnEnter();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_LOGINDLG_H__03A5CEB0_7D72_4B27_B994_E7A4B7F8C48C__INCLUDED_)

 

 

 

// MySocket.h: interface for the CMySocket class.

// SOCKET的封装

/*

SOCKET的封装,方便了使用,但功能有限 依项目需要而完善

详细函数说明待添加

*/

//////////////////////////////////////////////////////////////////////

 

#ifndef __MYSOCKET_H_

#define __MYSOCKET_H_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <WINSOCK2.H>

 

#pragma comment(lib,"ws2_32.lib")

 

//////////////////////////////////////////////////////////////////////////

// CMySocket类定义

class CMySocket

{

public:

CMySocket();

virtual ~CMySocket();

static BOOL StartUp(); //静态, SOCKET环境的初始化

static void CleanUp(); // SOCKET环境卸载

static sockaddr_in MakeSockAddr(UINT nPort, LPCTSTR lpszAddress = NULL); //静态, 方便生成一个地址结构体

 

BOOL Create(UINT nSocketPort = 0,

   int nSocketType = SOCK_STREAM,

   LPCTSTR lpszSocketAddress = NULL); //创建SOCKET

 

void Close(); //关闭

BOOL ShutDown(int nHow = SD_BOTH); //关闭读写通道

 

BOOL AsyncSelect(HWND hWnd, UINT wMsg, long lEvent); //异步选择模式

 

int SendTo(const void *lpBuf,

   int nBufLen,

   UINT nHostPort,

   LPCTSTR lpszHostAddress = NULL,

   int nFlags = 0); //SendTo的两种方式

int SendTo(const void *lpBuf,

   int nBufLen,

   const SOCKADDR *lpSockAddr,

   int nSockAddrLen,

   int nFlags = 0);

 

public:

SOCKET m_sock; //SOCKET标识

UINT m_nPort; //端口

int m_nSocketType; //类型

CString m_szAddr; //IP的字符串形式

sockaddr_in m_sockaddr; //地址

};

//////////////////////////////////////////////////////////////////////////

 

#endif // __MYSOCKET_H_

 

 

#if !defined(AFX_MYTAB_H__A0DCFE98_D81E_47D8_A2B5_AC76F1F222AA__INCLUDED_)

#define AFX_MYTAB_H__A0DCFE98_D81E_47D8_A2B5_AC76F1F222AA__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// MyTab.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CMyTab window

 

class CMyTab : public CTabCtrl

{

// Construction

public:

CMyTab();

 

// Attributes

public:

int m_nItemCount; //窗体个数

CWnd *m_pCurWnd; //当前窗体

CPoint m_ptTabs; //左上角坐标

CRect m_tabRect; //Tab的矩形区域

// Operations

public:

void AddItem(CWnd *pWnd, LPTSTR name); //添加选项卡

void InsertItem(int pos, CWnd *pWnd, LPTSTR name);

void DelItem(CString name);

void DelItem(int index);

void ChangeTo(int index);

void ChangeTo(CString name);

CString GetItemText(int index);

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMyTab)

//}}AFX_VIRTUAL

 

// Implementation

public:

virtual ~CMyTab();

 

// Generated message map functions

protected:

//{{AFX_MSG(CMyTab)

// NOTE - the ClassWizard will add and remove member functions here.

afx_msg void OnSelchange(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

//}}AFX_MSG

 

DECLARE_MESSAGE_MAP()

};

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_MYTAB_H__A0DCFE98_D81E_47D8_A2B5_AC76F1F222AA__INCLUDED_)

 

 

// Packet.h: interface for the CPacket class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_PACKET_H__F38AB289_53A5_4601_B49F_6D96B3AA79C9__INCLUDED_)

#define AFX_PACKET_H__F38AB289_53A5_4601_B49F_6D96B3AA79C9__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

 

class CPacket

{

public:

CPacket();

virtual ~CPacket();

int Pack(char *pData);

int UnPack(const char *pData);

int GetDataSize();

int GetPackSize();

 

void Make(int type, int version, int dataSize, const void *pData);

 

public:

int m_nType;

int m_nVersion;

int m_nDataLen;

char *m_pData;

};

 

#endif // !defined(AFX_PACKET_H__F38AB289_53A5_4601_B49F_6D96B3AA79C9__INCLUDED_)

 

 

#if !defined(AFX_REGDLG_H__0ECB7818_0064_4A63_B54C_D291B073B212__INCLUDED_)

#define AFX_REGDLG_H__0ECB7818_0064_4A63_B54C_D291B073B212__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

// RegDlg.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CRegDlg dialog

 

class CRegDlg : public CDialog

{

// Construction

public:

CRegDlg(CWnd *pParent = NULL);   // standard constructor

 

// Dialog Data

//{{AFX_DATA(CRegDlg)

enum { IDD = IDD_DLG_RESISTER };

CStatic m_labFace;

CComboBox m_ccbFaceID;

CEdit m_tishi;

CString m_szUsername;

CString m_szPassword;

CString m_szPassword2;

CString m_szPhone;

CString m_szNickname;

CTime m_tmBrithday;

int m_nSex;

int m_nFaceID;

//}}AFX_DATA

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CRegDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

BOOL VerifyData();

void DoReg();

void RegSuccess(int num);

void StartAcceptNetMsg();

void StopAcceptNetMsg();

 

// Generated message map functions

//{{AFX_MSG(CRegDlg)

afx_msg void OnBtnReg();

afx_msg void OnBtnExit();

afx_msg void OnBtnReinput();

afx_msg HRESULT OnNetMsg(WPARAM wParam, LPARAM lParam);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnSelchangeComboFace();

virtual BOOL OnInitDialog();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

LRESULT OnGetDefID(WPARAM wp, LPARAM lp);

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_REGDLG_H__0ECB7818_0064_4A63_B54C_D291B073B212__INCLUDED_)

 

 

#if !defined(AFX_REGRESULTDLG_H__DC05E175_A2C6_45E1_8460_13520071B4E8__INCLUDED_)

#define AFX_REGRESULTDLG_H__DC05E175_A2C6_45E1_8460_13520071B4E8__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// RegResultDlg.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CRegResultDlg dialog

 

class CRegResultDlg : public CDialog

{

// Construction

public:

CRegResultDlg(CWnd *pParent = NULL);   // standard constructor

 

// Dialog Data

//{{AFX_DATA(CRegResultDlg)

enum { IDD = IDD_DLG_REG_RESULT };

UINT m_nUserNumber;

CString m_szResult;

//}}AFX_DATA

 

void Show(int num, CString result);

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CRegResultDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

CFont m_font;

// Generated message map functions

//{{AFX_MSG(CRegResultDlg)

virtual BOOL OnInitDialog();

afx_msg void OnPaint();

afx_msg void OnBtnBack();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_REGRESULTDLG_H__DC05E175_A2C6_45E1_8460_13520071B4E8__INCLUDED_)

 

 

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by Client.rc

//

#define IDM_ABOUTBOX                    0x0010

#define IDD_ABOUTBOX                    100

#define IDS_ABOUTBOX                    101

#define IDD_GAME_HALL_LLK               101

#define IDD_CLIENT_DIALOG               102

#define IDR_MAINFRAME                   128

#define IDD_DLG_LOGIN                   129

#define IDD_DLG_RESISTER                130

#define IDD_DLG_HALL                    132

#define IDD_DLG_REG_RESULT              133

#define IDD_DLG_ROOM                    135

#define IDD_DLG_TABLE                   136

#define IDB_BMP_NOUSER                  137

#define IDB_BMP_TABLE_OFF               142

#define IDB_BMP_TABLE_ON                143

#define IDR_ACCELERATOR                 144

#define IDD_DLG_TOP10                   145

#define IDB_BMP_READY                   146

#define IDC_BTN_LOGIN                   1000

#define IDC_BTN_EXIT                    1001

#define IDC_BTN_REGSITER                1002

#define IDC_BTN_REINPUT                 1002

#define IDC_EDIT_USERNAME               1003

#define IDC_EDIT_PASSWORD               1004

#define IDC_EDIT_NICKNAME               1005

#define IDC_EDIT_PASSWORD2              1007

#define IDC_EDIT_PHONENUMBER            1008

#define IDC_DATETIMEPICKER_BIRTHDAY     1010

#define IDC_RADIO_SEX_MAIL              1011

#define IDC_RADIO_SEX_FEMAIL            1012

#define IDC_RADIO_SEX_BAOMI             1013

#define IDC_BTN_REG                     1014

#define IDC_EDIT_TISHI                  1017

#define IDC_TREE_SERVER                 1018

#define IDC_TAB_MAIN                    1019

#define IDC_BUTTON1                     1020

#define IDC_BTN_AOTO_SEATDOWN           1020

#define IDC_SEPARATOR                   1023

#define IDC_BTN_TEST                    1024

#define IDC_EDIT_NUMBER                 1025

#define IDC_BTN_BACK                    1026

#define IDC_EDIT_RESULT                 1027

#define IDC_EDIT_TEXT                   1032

#define IDC_LAB_USER_ID                 1033

#define IDC_LAB_NICKNAME                1034

#define IDC_BMP_FACE                    1035

#define IDC_LAB_SCORE                   1036

#define IDC_LAB_TABLE_NUM               1039

#define IDC_SEAT_1                      1040

#define IDC_SEAT_2                      1041

#define IDC_SEAT_3                      1042

#define IDC_SEAT_4                      1043

#define IDC_SEAT_5                      1044

#define IDC_SEAT_6                      1045

#define IDC_LAB_TABLE                   1046

#define IDC_LAB_NAME_1                  1047

#define IDC_LAB_NAME_2                  1048

#define IDC_COMBO_FACE                  1048

#define IDC_LAB_NAME_3                  1049

#define IDC_LAB_FACE                    1049

#define IDC_LAB_NAME_4                  1050

#define IDC_LIST_SCORE                  1050

#define IDC_LAB_NAME_5                  1051

#define IDC_LAB_NAME_6                  1052

#define IDC_LAB_READY0                  1053

#define IDC_LAB_READY1                  1054

#define IDC_LAB_READY2                  1055

#define IDC_LAB_READY3                  1056

#define IDC_LAB_READY4                  1057

#define IDC_LAB_READY5                  1058

#define IDK_ENTER                       32771

 

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE        147

#define _APS_NEXT_COMMAND_VALUE         32772

#define _APS_NEXT_CONTROL_VALUE         1054

#define _APS_NEXT_SYMED_VALUE           101

#endif

#endif

 

 

#if !defined(AFX_ROOMDLG_H__05EBCF87_0B95_44DB_9E76_AFB44ACDA0D6__INCLUDED_)

#define AFX_ROOMDLG_H__05EBCF87_0B95_44DB_9E76_AFB44ACDA0D6__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// RoomDlg.h : header file

//

#include "TableDlg.h"

/////////////////////////////////////////////////////////////////////////////

// CRoomDlg dialog

 

class CRoomDlg : public CDialog

{

// Construction

public:

CRoomDlg(CWnd *pParent = NULL);   // standard constructor

 

// Dialog Data

//{{AFX_DATA(CRoomDlg)

enum { IDD = IDD_DLG_ROOM };

// NOTE: the ClassWizard will add data members here

//}}AFX_DATA

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CRoomDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

BOOL m_bFirstShow;

CBrush m_brushBG;

CTableDlg m_tab;

 

// Generated message map functions

//{{AFX_MSG(CRoomDlg)

afx_msg void OnSize(UINT nType, int cx, int cy);

afx_msg void OnPaint();

virtual BOOL OnInitDialog();

afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);

afx_msg HRESULT OnSeatDown(WPARAM wParam, LPARAM lParam);

afx_msg HRESULT OnLookOn(WPARAM wParam, LPARAM lParam);

afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnBtnAotoSeatdown();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_ROOMDLG_H__05EBCF87_0B95_44DB_9E76_AFB44ACDA0D6__INCLUDED_)

 

 

#if !defined(AFX_SCORETOP10DLG_H__5AC95D01_4813_4FE4_9E07_16AFFF5BC785__INCLUDED_)

#define AFX_SCORETOP10DLG_H__5AC95D01_4813_4FE4_9E07_16AFFF5BC785__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// ScoreTop10Dlg.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CScoreTop10Dlg dialog

 

class CScoreTop10Dlg : public CDialog

{

// Construction

public:

CScoreTop10Dlg(CWnd* pParent = NULL);   // standard constructor

void SetScoreList(CScoreList &scoreList);

 

// Dialog Data

//{{AFX_DATA(CScoreTop10Dlg)

enum { IDD = IDD_DLG_TOP10 };

CListCtrl m_listScore;

//}}AFX_DATA

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CScoreTop10Dlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

CScoreList m_scoreList;

// Generated message map functions

//{{AFX_MSG(CScoreTop10Dlg)

virtual BOOL OnInitDialog();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_SCORETOP10DLG_H__5AC95D01_4813_4FE4_9E07_16AFFF5BC785__INCLUDED_)

 

 

// stdafx.h : include file for standard system include files,

//  or project specific include files that are used frequently, but

//   are changed infrequently

//

 

#if !defined(AFX_STDAFX_H__83F9BB7D_52B8_4F51_93DA_BD97390E0859__INCLUDED_)

#define AFX_STDAFX_H__83F9BB7D_52B8_4F51_93DA_BD97390E0859__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#define  WINVER 0x0500

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

 

#pragma warning(disable:4786)

 

#include <afxwin.h> // MFC core and standard components

#include <afxext.h> // MFC extensions

#include <afxdisp.h> // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h> // MFC support for Windows Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

 

 

#include <vector>

using namespace std;

#include "../Common/ClientDefine.h"

#include "../Common/ServerDefine.h"

#include "../Basic/UCode.h"

#include "../Common/Packet.h"

#include <WINSOCK2.H>

 

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_STDAFX_H__83F9BB7D_52B8_4F51_93DA_BD97390E0859__INCLUDED_)

 

 

#if !defined(AFX_TABLEDLG_H__1E57F573_E247_4051_AC29_4DC4A3DFFF0E__INCLUDED_)

#define AFX_TABLEDLG_H__1E57F573_E247_4051_AC29_4DC4A3DFFF0E__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// TableDlg.h : header file

//

 

// extern TABLE_INFO g_table;

// extern USER_INFO g_userInfo;

 

/////////////////////////////////////////////////////////////////////////////

// CTableDlg dialog

 

class CTableDlg : public CDialog

{

// Construction

public:

CTableDlg(CWnd *pParent = NULL);   // standard constructor

 

// Dialog Data

//{{AFX_DATA(CTableDlg)

enum { IDD = IDD_DLG_TABLE };

CStatic m_labTable;

//}}AFX_DATA

CStatic m_labName[6];

CStatic m_labFace[6];

CStatic m_labReady[6];

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CTableDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

//}}AFX_VIRTUAL

int PtInSeat(CPoint pt);

// Implementation

protected:

CBrush m_brushBG;

CBitmap m_bmpTableEmpty;

CBitmap m_bmpTablePlaying;

CBitmap m_bmpNoUser;

CBitmap m_bmpReady;

HCURSOR m_hcurHand;

HCURSOR m_hcurOld;

HCURSOR m_hcurNO;

int m_nCusorType;

// Generated message map functions

//{{AFX_MSG(CTableDlg)

virtual BOOL OnInitDialog();

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

afx_msg void OnPaint();

afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_TABLEDLG_H__1E57F573_E247_4051_AC29_4DC4A3DFFF0E__INCLUDED_)

 

 

 

// TableIDList.h: interface for the CTableIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_)

#define AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CTableIDList

{

public:

CTableIDList();

virtual ~CTableIDList();

};

 

#endif // !defined(AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_)

 

 

 

/*/////////////////////////////////////////////////////////////////////////

说明:UCode 文件,一些简单常用功能函数合集。

版本:1.0

创建:[4/5/2009 Dufeng]

修改:

*///////////////////////////////////////////////////////////////////////////

 

#ifndef __U_CODE_H_

#define __U_CODE_H_

 

//////////////////////////////////////////////////////////////////////////

// 预处理

#include <windows.h>

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 宏定义

#define BUFFER_SIZE 256

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

/*

0x8000二进制值是1000000000000000,两者进行与运算

即如果GetAsyncKeyState(vk_code)最高位是1,则取值1,

即此时KEYDOWN   后者正好相反

函数GetAsyncKeyState确定在调用它时某个按键处于弹起还是按下的,以及此按键是否在上一次调用GetAsyncKeyState之后(“又”)按下过(重复也算按下)。

这句话的完整意思是:预定义了一个KEYDOWN参数为vk_code 他的定义的含义是判断一个键是否被按下(GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0如果按下了就是1,没有按下就是0

然后其它地方用的时候直接用KEYDOWN(vk_code)判断这个键是否按下,相反弹起来是1按下是0

*/

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 只允许运行一个实例。

BOOL OnlyRunOne(WCHAR *_mutexName);

 

// 获取上次的错误信息,会自动格式化信息内容。

VOID GetLastErrorMsg(CHAR *szBuf);

 

// 获取某个键的状态

BOOL GetOneKeyState(BYTE _key);

 

// 获取程序的路径

void GetAppPath(char *szFilePath);

 

// 获取程序文件名

void GetAppFileFullPathName(char *szFileName);

//////////////////////////////////////////////////////////////////////////

 

#endif //__U_CODE_H_

 

 

// WMLink.h: interface for the CWMLink class.

// 基于窗口的连接通讯 点对点的 方便游戏客户端有大厅通讯

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_)

#define AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CWMLink

{

public:

CWMLink();

virtual ~CWMLink();

virtual void Create(HWND myHwnd, HWND youHwnd);

virtual BOOL Send(DWORD nType, DWORD nSize, LPVOID pData);

virtual BOOL Post(DWORD nType, DWORD nSize, LPVOID pData);

 

virtual INT OnRecv(CWnd *pWnd, COPYDATASTRUCT *pCopyData) = 0;

 

virtual void SetMyHwnd(HWND val)

{

m_myHwnd = val;

}

virtual void SetYourHwnd(HWND val)

{

m_yourHwnd = val;

}

 

protected:

HWND m_myHwnd;

 

HWND m_yourHwnd;

};

 

#endif // !defined(AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_)

 

 

LLK连连看游戏项目代码

 

// Ccpp: implementation of the CLLK class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "CLLK.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLK::CLLK()

{

m_nBoxXCount = BOX_X_COUNT;

m_nBoxYCount = BOX_Y_COUNT;

 

Init();

}

 

CLLK::~CLLK()

{

}

 

int CLLK::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(CLLK) + sizeof(int));

int dataSize = sizeof(CLLK);

cos << dataSize;

cos.Write((char *)this, dataSize);

cos.CopyTo(pData);

 

return cos.GetSize();

}

 

int CLLK::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

if (dataSize != sizeof(CLLK))

{

TRACE("C CLLK::UnPack dataSize[%d] != sizeof(CLLK)[%d]\n", dataSize, sizeof(CLLK));

}

cis.Read((char *)this, sizeof(CLLK));

return cis.GetSize();

}

 

void CLLK::Init()

{

// 初始数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

// 初始化选择

m_nSelBox = 0;

m_ptSelBox[0] = CPoint(0, 0);

m_ptSelBox[1] = CPoint(0, 0);

 

// 初始化连线

m_nLinkLine = 0;

ZeroMemory(m_ptLinkLine, sizeof(m_ptLinkLine));

 

// 初始化将要删除的

m_bHasWillBeNullBox = FALSE;

m_typeWillBeNullBox[0] = 0;

m_typeWillBeNullBox[1] = 0;

m_ptWillBeNullBox[0] = CPoint(-1, -1);

m_ptWillBeNullBox[1] = CPoint(-1, -1);

 

// 初始化连击数

m_nCurLianji = 0;

m_nMaxLianji = 0;

m_dwLastLianjiTime = 0;

 

m_nLeaveBoxCount = 0;

}

 

//////////////////////////////////////////////////////////////////////////

// //判断两坐标是否在同一线上 并且中间无阻碍

BOOL CLLK::IsPairInlineValid(CPoint pt1, CPoint pt2)

{

//同一点判断

if (pt1 == pt2)

{

return FALSE;

}

 

//同一行类型

typedef enum _INLINE_TYPE

{

IT_NULL = 0, //不同行

IT_X = 1, //X同行

IT_Y = 2 //Y同行

} INLINE_TYPE;

 

INLINE_TYPE it;

 

if (pt1.x == pt2.x)

{

it = IT_X;

//计算出两者之大小

int x = pt1.x;

int minY, maxY;

if (pt1.y > pt2.y)

{

minY = pt2.y;

maxY = pt1.y;

}

else

{

minY = pt1.y;

maxY = pt2.y;

}

//紧挨着

if (maxY - minY == 1)

{

return TRUE;

}

//其它情况

for (int i = minY + 1; i < maxY; i++)

{

if (m_nArrType[x][i] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else if (pt1.y == pt2.y)

{

it = IT_Y;

//计算出两者之大小

int y = pt1.y;

int minX, maxX;

if (pt1.x > pt2.x)

{

minX = pt2.x;

maxX = pt1.x;

}

else

{

minX = pt1.x;

maxX = pt2.x;

}

//紧挨着

if (maxX - minX == 1)

{

return TRUE;

}

//其它情况

for (int i = minX + 1; i < maxX; i++)

{

if (m_nArrType[i][y] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else

{

it = IT_NULL;

return FALSE;

}

return FALSE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 判断两点是否可消除 完成后集成在LLK类中

BOOL CLLK::IsPairCanLink(CPoint pt1,

 CPoint pt2,

 int *pnResultPtCount /*= NULL*/,

 CPoint *pPtResult /*= NULL*/)

{

// 结果保存

BOOL bRet = FALSE;

int count = 0;

CPoint point[4];

 

// 重复点情况

if (pt1 == pt2)

{

return FALSE;

}

 

// 图标是否相同

if (m_nArrType[pt1.x][pt1.y] != m_nArrType[pt2.x][pt2.y])

{

return FALSE;

}

 

// 判断流程

do

{

// 1.同一线情况

if (IsPairInlineValid(pt1, pt2))

{

count = 2;

point[0] = pt1;

point[1] = pt2;

bRet = TRUE;

break;

}

 

// 2.一拐点情况

{

CPoint t1, t2;

 

// 两点组成的矩形另外两个顶点

t1.x = pt1.x;

t1.y = pt2.y;

 

t2.x = pt2.x;

t2.y = pt1.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t1) &&

IsPairInlineValid(t1,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t1;

point[2] = pt2;

bRet = TRUE;

break;

}

 

if (m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t2;

point[2] = pt2;

bRet = TRUE;

break;

}

}

 

// 3.两拐点情况

// 先横向检测

{

//另外的两个拐点

CPoint t1, t2;

 

//X向左检测

for (int x = pt1.x - 1; x >= 0; x--)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

//X向右检测 可以使路线变短

for (x = pt1.x + 1; x < BOX_X_COUNT; x++)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向上检测

for (int y = pt1.y - 1; y >= 0; y--)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向下检测

for (y = pt1.y + 1; y < BOX_Y_COUNT; y++)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

}

break;

}

while (1);

 

if (pnResultPtCount != NULL)

{

*pnResultPtCount = count;

if (pPtResult != NULL)

{

for (int i = 0; i < count; i++)

{

pPtResult[i] = point[i];

}

}

}

return bRet;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 执行消除响应

BOOL CLLK::DoXiaoChu()

{

if (m_nSelBox != 2)

{

return FALSE;

}

 

if (m_ptSelBox[0] == m_ptSelBox[1])

{

m_nSelBox = 0;

return FALSE;

}

if (IsPairCanLink(m_ptSelBox[0], m_ptSelBox[1], &m_nLinkLine, m_ptLinkLine))

{

// 将要删除的方块情况维护

m_bHasWillBeNullBox = TRUE;

m_ptWillBeNullBox[0] = m_ptSelBox[0];

m_ptWillBeNullBox[1] = m_ptSelBox[1];

 

m_typeWillBeNullBox[0] = m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y];

m_typeWillBeNullBox[1] = m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y];

 

// 游戏方块状态维护

m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y] = 0;

m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y] = 0;

 

// 连击情况维护

if (m_dwLastLianjiTime == 0)

{

m_dwLastLianjiTime = GetTickCount();

}

DWORD nowTime = GetTickCount();

if (nowTime - m_dwLastLianjiTime <= GAME_LIANJI_TIMEOUT)

{

m_nCurLianji++;

m_dwLastLianjiTime = nowTime;

}

else

{

m_nCurLianji = 1;

m_dwLastLianjiTime = nowTime;

}

if (m_nMaxLianji < m_nCurLianji)

{

m_nMaxLianji = m_nCurLianji;

}

 

 

// 选择情况维护

m_nSelBox = 0;

m_nLeaveBoxCount -= 2;

 

return TRUE;

//AAAASetTimer(GAME_DRAW_LINK_LINE_TIMER_ID, GAME_DRAW_LINK_LINE_TIME, NULL);

}

else

{

m_ptSelBox[0] = m_ptSelBox[1];

m_nSelBox = 1;

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

void CLLK::ResetBoxState()

{

int arrTempState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

CPoint arrPointState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

int nNotNullCount = 0;

 

//将状态和坐标放到一维数组里

for (int x = 0; x < BOX_X_COUNT; x++)

{

for (int y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

arrTempState[nNotNullCount] = m_nArrType[x][y];

arrPointState[nNotNullCount].x = x;

arrPointState[nNotNullCount].y = y;

nNotNullCount++;

}

}

}

 

//为了验证 将状态清空

ZeroMemory(m_nArrType, sizeof(m_nArrType));

 

//随机

srand(GetTickCount());

int index = 0;

int max = nNotNullCount;

for (int i = 0; i < nNotNullCount; i++)

{

index = rand() % max;

m_nArrType[arrPointState[i].x][arrPointState[i].y] = arrTempState[index];

arrTempState[index] = arrTempState[max - 1] ;

max--;

}

 

if (!IsCanXiaoChu())

{

ResetBoxState();

}

//AAAA Invalidate(FALSE);

}

 

BOOL CLLK::IsCanXiaoChu()

{

CPoint *pPt = new CPoint[m_nLeaveBoxCount];

BOOL bRet = FALSE;

int x, y;

int i = 0;

for (x = 0; x < BOX_X_COUNT; x++)

{

for (y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

pPt[i].x = x;

pPt[i].y = y;

i++;

}

}

}

 

for (i = 0; i < m_nLeaveBoxCount; i++)

{

for (int j = i + 1; j < m_nLeaveBoxCount; j++)

{

if (IsPairCanLink(pPt[i], pPt[j]))

{

bRet = TRUE;

break;

}

}

if (bRet == TRUE)

{

break;

}

}

 

delete[] pPt;

return bRet;

}

 

VOID CLLK::InitGameData(int mode /*= 0*/)

{

// 初始游戏数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

int x, y;

int n = 0;

for (x = 1; x < BOX_X_COUNT - 1; x++)

{

for (y = 1; y < BOX_Y_COUNT - 1; y++)

{

m_nArrType[x][y] = n % BOX_TYPE_SIZE + 1;

n++;

}

}

 

m_nLeaveBoxCount = (BOX_X_COUNT - 2) * (BOX_Y_COUNT - 2);

 

ResetBoxState();

}

 

//////////////////////////////////////////////////////////////////////////

 

 

// EndGameDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "LLK.h"

#include "EndGameDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CEndGameDlg dialog

 

 

CEndGameDlg::CEndGameDlg(CWnd* pParent /*=NULL*/)

: CDialog(CEndGameDlg::IDD, pParent)

{

//{{AFX_DATA_INIT(CEndGameDlg)

// NOTE: the ClassWizard will add member initialization here

//}}AFX_DATA_INIT

}

 

 

void CEndGameDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CEndGameDlg)

DDX_Control(pDX, IDC_LIST_SCORE, m_listScore);

//}}AFX_DATA_MAP

}

 

 

BEGIN_MESSAGE_MAP(CEndGameDlg, CDialog)

//{{AFX_MSG_MAP(CEndGameDlg)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CEndGameDlg message handlers

 

BOOL CEndGameDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// TODO: Add extra initialization here

m_listScore.SetExtendedStyle(m_listScore.GetExtendedStyle() |

LVS_EX_FULLROWSELECT |

LVS_EX_GRIDLINES);

m_listScore.InsertColumn(0, "名次", LVCFMT_CENTER, 50);

m_listScore.InsertColumn(1, "用户ID", LVCFMT_CENTER, 100);

m_listScore.InsertColumn(2, "用户昵称", LVCFMT_CENTER, 100);

m_listScore.InsertColumn(3, "获得游戏积分", LVCFMT_LEFT, 100);

 

CString str;

for (int i=0;i<m_scoreList.GetCount();i++)

{

str.Format("%d", i+1);

m_listScore.InsertItem(i, str);

str.Format("%d", m_scoreList.GetScoreByIndex(i).UID);

m_listScore.SetItemText(i, 1, str);

str.Format("%s", m_scoreList.GetScoreByIndex(i).NickName);

m_listScore.SetItemText(i, 2, str);

str.Format("%d",m_scoreList.GetScoreByIndex(i).Score);

m_listScore.SetItemText(i, 3, str);

}

return TRUE;  // return TRUE unless you set the focus to a control

              // EXCEPTION: OCX Property Pages should return FALSE

}

 

void CEndGameDlg::SetScoreList( CScoreList &sl )

{

m_scoreList = sl;

}

 

 

// GameMan.cpp: implementation of the CGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "GameMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CGameMan::CGameMan()

{

}

 

CGameMan::~CGameMan()

{

}

 

 

 

// GameWMLink.cpp: implementation of the CGameWMLink class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "LLK.h"

#include "GameWMLink.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CGameWMLink::CGameWMLink()

{

 

}

 

CGameWMLink::~CGameWMLink()

{

 

}

 

INT CGameWMLink::OnRecv( CWnd *pWnd, COPYDATASTRUCT *pCopyData )

{

TRACE("FC OnRecv....\n");

int gmType = pCopyData->dwData;

switch(gmType)

{

case PTS_SHOW_WINDOW:

TRACE("T Show the window...\n");

pWnd->SetForegroundWindow();

break;

case PTC_SEND_GAMEINFO:

{

 

}

break;

case PTCS_GET_GAMEINFO:

{

TRACE("FC Got game info (llk man) from Client...\n");

}

break;

case PTCS_EXIT:

{

TRACE(" S EXIT game.. \n");

}

break;

case PTS_GAME_BEGIN:

{

TRACE(" S start game.. \n");

}

break;

case PTS_GAME_END:

{

TRACE(" S end game.. \n");

}

break;

default:

break;

}

return gmType;

}

 

void CGameWMLink::SendMyGameInfo( CLLK * pLLK )

{

char buf[1024] = {0};

int len = pLLK->Pack(buf);

Send(PTC_SEND_GAMEINFO, len, buf);

TRACE("G Send my game info to client..\n");

}

 

void CGameWMLink::SendCheckOnline()

{

TRACE("T Send check online... \n");

Send(PTCS_CHECK_ONLINE, 0, 0);

}

 

void CGameWMLink::SendReady()

{

TRACE("T Send start game.. \n");

Send(PTC_GAME_READY, 0, 0);

}

 

 

 

// InStream.cpp: implementation of the CInStream class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "InStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CInStream::CInStream()

{

m_pInBuf = NULL;

m_pCurInPtr = NULL;

m_pMaxInPtr = NULL;

m_nMaxSize = 0;

}

 

CInStream::~CInStream()

{

}

 

BOOL CInStream::Create( const void *pData )

{

int BufMaxSize = -1;

if (pData == NULL)

{

return FALSE;

}

m_nMaxSize = BufMaxSize;

m_pInBuf = pData;

m_pCurInPtr = m_pInBuf;

m_pMaxInPtr = m_pCurInPtr;

return FALSE;

}

 

int CInStream::Read(void *savePtr, int readSize)

{

if (savePtr == NULL || readSize <= 0)

{

TRACE("B CInStream::Read prarm is zero!\n");

return 0;

}

if (m_nMaxSize != -1 && (const char *)m_pCurInPtr + readSize - (const char *)m_pInBuf > m_nMaxSize)

{

TRACE("B CInStread::Read out of range!\n");

return 0;

}

memcpy(savePtr, m_pCurInPtr, readSize);

m_pCurInPtr = (const char *)m_pCurInPtr + readSize;

 

//最大访问指针维护

if (m_pCurInPtr > m_pMaxInPtr)

{

m_pMaxInPtr = m_pCurInPtr;

}

return readSize;

}

 

const void * CInStream::GetHead()

{

return m_pInBuf;

}

 

const void * CInStream::GetCurPtr()

{

return m_pCurInPtr;

}

 

 

//////////////////////////////////////////////////////////////////////////

// 注意:此函数并未严格判定访问是否越界 使用时小心

BOOL CInStream::MoveCurPtr(int offset, int mode /*= MP_CUR*/)

{

if (mode == MP_CUR)

{

m_pCurInPtr = (const char *)m_pCurInPtr + offset;

}

else if (mode == MP_BEG)

{

if (offset < 0)

{

return FALSE;

}

m_pCurInPtr = (const char *)m_pInBuf + offset;

}

else if (mode == MP_END)

{

if (m_nMaxSize == -1)

{

TRACE("B CInStream::MoveCurPtr MP_END mode not support m_nMaxSize = -1\n");

return FALSE;

}

if (offset > 0)

{

return FALSE;

}

  m_pCurInPtr = (const char *)m_pInBuf + offset;

}

if (m_pCurInPtr > m_pMaxInPtr)

{

m_pMaxInPtr = m_pCurInPtr;

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

int CInStream::GetSize()

{

return (const char *)m_pMaxInPtr - (const char *)m_pInBuf;

}

 

int CInStream::GetMaxSize()

{

return m_nMaxSize;

}

 

CInStream & CInStream::operator>>(int &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(char &value)

{

Read((char *) &value, sizeof(char));

return *this;

}

 

CInStream & CInStream::operator>>(char *value)

{

int len = 0;

Read((char *) &len, sizeof(int));

Read(value, len);

return *this;

}

 

CInStream & CInStream::operator>>(CString &value)

{

int len = 0;

Read((char *) &len, sizeof(int));

Read(value.GetBuffer(len), len);

value.ReleaseBuffer();

return *this;

}

 

CInStream & CInStream::operator>>(long &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(UINT &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(ULONG &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(UCHAR &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(float &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(double &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

 

 

// LLK.cpp : Defines the class behaviors for the application.

//

 

#include "stdafx.h"

#include "LLK.h"

#include "LLKDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

HWND g_hWndParent;

CGameWMLink g_gameWMLink;

CLLKGameMan g_llkGameMan;

int g_userid = 0;

BOOL g_bLookOn = FALSE;

/////////////////////////////////////////////////////////////////////////////

// CLLKApp

 

BEGIN_MESSAGE_MAP(CLLKApp, CWinApp)

//{{AFX_MSG_MAP(CLLKApp)

// NOTE - the ClassWizard will add and remove mapping macros here.

//    DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG

ON_COMMAND(ID_HELP, CWinApp::OnHelp)

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CLLKApp construction

 

CLLKApp::CLLKApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}

 

/////////////////////////////////////////////////////////////////////////////

// The one and only CLLKApp object

 

CLLKApp theApp;

 

/////////////////////////////////////////////////////////////////////////////

// CLLKApp initialization

 

BOOL CLLKApp::InitInstance()

{

AfxEnableControlContainer();

 

// Standard initialization

// If you are not using these features and wish to reduce the size

//  of your final executable, you should remove from the following

//  the specific initialization routines you do not need.

 

#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif

 

if (!CheckRunEnv())

{

//return FALSE;

}

 

CLLKDlg dlg;

m_pMainWnd = &dlg;

int nResponse = dlg.DoModal();

if (nResponse == IDOK)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with OK

}

else if (nResponse == IDCANCEL)

{

// TODO: Place code here to handle when the dialog is

//  dismissed with Cancel

}

 

// Since the dialog has been closed, return FALSE so that we exit the

//  application, rather than start the application's message pump.

return FALSE;

}

 

BOOL CLLKApp::CheckRunEnv()

{

STARTUPINFO sui = {sizeof(STARTUPINFO)};

GetStartupInfo(&sui);

 

g_hWndParent = (HWND)sui.dwX;

g_userid = (int)sui.dwY;

g_bLookOn = (BOOL)sui.dwXSize;

TRACE("G MainWinHwnd = %d\n", g_hWndParent);

 

if (g_hWndParent == 0 || g_userid == 0)

{

MessageBox(NULL, "请从游戏大厅进入游戏!", "提醒", 0);

return FALSE;

}

return TRUE;

}

 

 

 

// LLKDlg.cpp : implementation file

//

 

#include "stdafx.h"

#include "LLK.h"

#include "LLKDlg.h"

#include "EndGameDlg.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

//#define __DEBUG

#define TIMER_CHECK_ONLINE_ID 11

 

#define WMC_MINISIZE 2001

#define WMC_CLOSE 2002

#define WMC_START 2003

#define WMC_LIANXI 2004

 

#define WMC_ENDGAME 2005

/////////////////////////////////////////////////////////////////////////////

// CAboutDlg dialog used for App About

 

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

 

// Dialog Data

//{{AFX_DATA(CAboutDlg)

enum { IDD = IDD_ABOUTBOX };

//}}AFX_DATA

 

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

//{{AFX_MSG(CAboutDlg)

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

 

}

 

void CAboutDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

 

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CLLKDlg dialog

 

CLLKDlg::CLLKDlg(CWnd *pParent /*=NULL*/) : CDialog(CLLKDlg::IDD, pParent),

m_ptLBtnDown(-1,

 -1)

{

//{{AFX_DATA_INIT(CLLKDlg)

// NOTE: the ClassWizard will add member initialization here

//}}AFX_DATA_INIT

// Note that LoadIcon does not require a subsequent DestroyIcon in Win32

 

m_bLBtnDown = FALSE;

m_bIsMoveing = FALSE;

m_bPlay = FALSE;

m_resetCount = 5;

m_bPlayerStateNeedReflash = FALSE;

m_hIcon = (HICON)LoadImage(NULL, "IMAGE\\game.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);

 

}

 

void CLLKDlg::DoDataExchange(CDataExchange *pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CLLKDlg)

//}}AFX_DATA_MAP

 

}

 

BEGIN_MESSAGE_MAP(CLLKDlg, CDialog)

//{{AFX_MSG_MAP(CLLKDlg)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_WM_MOUSEMOVE()

ON_WM_LBUTTONDOWN()

ON_WM_LBUTTONUP()

ON_WM_KEYDOWN()

ON_WM_CANCELMODE()

ON_WM_TIMER()

ON_WM_CAPTURECHANGED()

ON_WM_COPYDATA()

ON_WM_DESTROY()

ON_COMMAND(WMC_MINISIZE, OnVBMinisize)

ON_COMMAND(WMC_CLOSE, OnVBClose)

ON_COMMAND(WMC_START, OnVBStart)

ON_COMMAND(WMC_LIANXI, OnVBLianxi)

ON_MESSAGE(DM_GETDEFID, OnGetDefID)

ON_WM_KILLFOCUS()

ON_COMMAND(WMC_ENDGAME, OnEndGame)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/////////////////////////////////////////////////////////////////////////////

// CLLKDlg message handlers

LRESULT CLLKDlg::OnGetDefID(WPARAM wp, LPARAM lp)

{

return MAKELONG(0, DC_HASDEFID);

}

 

BOOL CLLKDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// Add "About..." menu item to system menu.

 

// IDM_ABOUTBOX must be in the system command range.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

 

ModifyStyle(WS_CAPTION | WS_TILEDWINDOW, WS_SYSMENU | WS_MINIMIZEBOX);   

 

CMenu *pSysMenu = GetSystemMenu(FALSE);

 

if (pSysMenu != NULL)

{

pSysMenu->DeleteMenu(1, MF_BYPOSITION);

pSysMenu->DeleteMenu(1, MF_BYPOSITION);

pSysMenu->DeleteMenu(2, MF_BYPOSITION);

 

CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->InsertMenu(0,

MF_STRING | MF_BYPOSITION,

IDM_ABOUTBOX,

strAboutMenu);

pSysMenu->InsertMenu(1, MF_SEPARATOR | MF_BYPOSITION);

}

}

 

// Set the icon for this dialog.  The framework does this automatically

//  when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set small icon

 

// TODO: Add extra initialization here

g_gameWMLink.Create(this->m_hWnd, g_hWndParent);

g_gameWMLink.Send(PTCS_GET_HWND, sizeof(HWND), &this->m_hWnd);

 

InitVB();

SetTimer(TIMER_CHECK_ONLINE_ID, 1000, NULL);

return InitGame();

 

//return TRUE;  // return TRUE  unless you set the focus to a control

}

 

void CLLKDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialog::OnSysCommand(nID, lParam);

}

}

 

// If you add a minimize button to your dialog, you will need the code below

//  to draw the icon.  For MFC applications using the document/view model,

//  this is automatically done for you by the framework.

 

void CLLKDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc (this); // device context for painting

 

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

 

// Center icon in client rectangle

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

 

// Draw the icon

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CPaintDC dc (this);

 

RefreshMain(&dc);

 

CDialog::OnPaint();

}

}

 

// The system calls this to obtain the cursor to display while the user drags

//  the minimized window.

HCURSOR CLLKDlg::OnQueryDragIcon()

{

return (HCURSOR) m_hIcon;

}

 

void CLLKDlg::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

 

do

{

if (m_vbMan.OnMouseMove(point))

{

break;

}

 

// 移动窗口

if (m_bIsMoveing)

{

RECT rectWin;

GetWindowRect(&rectWin);

 

int x, y;

x = point.x - m_ptLBtnDown.x;

y = point.y - m_ptLBtnDown.y;

 

rectWin.left += x;

rectWin.right += x;

rectWin.top += y;

rectWin.bottom += y;

 

MoveWindow(&rectWin);

}

 

} while (0);

 

CDialog::OnMouseMove(nFlags, point);

}

 

 

void CLLKDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

 

// 保存状态和坐标

do

{

m_bLBtnDown = TRUE;

m_ptLBtnDown = point;

SetCapture();

 

if (m_vbMan.OnLButtonDown(point))

{

break;

}

if (m_rectTitleBar.PtInRect(point))

{

m_bIsMoveing = TRUE;

}

 

// 客户区处理

if (m_bPlay && !g_bLookOn)

{

CPoint ptSelBox = InWhichBox(point);

if (ptSelBox.x != -1 && ptSelBox.y != -1)

{

if (m_llk.m_nArrType[ptSelBox.x][ptSelBox.y] != 0)

{

if (m_llk.m_nSelBox >= 2)

{

m_llk.m_nSelBox = 0;

}

m_llk.m_nSelBox++;

m_llk.m_ptSelBox[m_llk.m_nSelBox - 1] = ptSelBox;

if (m_llk.m_nSelBox >= 2)

{

if (m_llk.DoXiaoChu())

{

SetTimer(GAME_DRAW_LINK_LINE_TIMER_ID,

GAME_DRAW_LINK_LINE_TIME,

NULL);

g_gameWMLink.SendMyGameInfo(&m_llk);

 

}

}

}

}

}

} while (0);

 

Invalidate(FALSE);

 

CDialog::OnLButtonDown(nFlags, point);

}

 

void CLLKDlg::OnLButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

m_bLBtnDown = FALSE;

m_bIsMoveing = FALSE;

 

m_vbMan.OnLButtonUp(point);

 

ReleaseCapture();

CDialog::OnLButtonUp(nFlags, point);

}

//////////////////////////////////////////////////////////////////////////

 

void CLLKDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

{

// TODO: Add your message handler code here and/or call default

if (nChar == VK_F5 && m_bPlay && !g_bLookOn)

{

if (m_resetCount > 0 )

{

m_llk.ResetBoxState();

m_resetCount--;

g_gameWMLink.SendMyGameInfo(&m_llk);

}

}

 

CDialog::OnKeyDown(nChar, nRepCnt, nFlags);

}

 

void CLLKDlg::OnCancelMode()

{

CDialog::OnCancelMode();

 

// TODO: Add your message handler code here

}

//////////////////////////////////////////////////////////////////////////

 

 

void CLLKDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

if (nIDEvent == GAME_TIMER_ID_REFLASH)

{

// 连击维护

if (m_bPlay && GetTickCount() - m_llk.m_dwLastLianjiTime >= GAME_LIANJI_TIMEOUT)

{

m_llk.m_nCurLianji = 0;

m_llk.m_dwLastLianjiTime = 0;

}

Invalidate(FALSE);

}

if (nIDEvent == GAME_DRAW_LINK_LINE_TIMER_ID)

{

if (m_bPlay || g_bLookOn)

{

m_llk.m_nLinkLine = 0;

m_llk.m_bHasWillBeNullBox = FALSE;

}

KillTimer(GAME_DRAW_LINK_LINE_TIMER_ID);

}

if (nIDEvent == TIMER_CHECK_ONLINE_ID)

{

g_gameWMLink.SendCheckOnline();

}

CDialog::OnTimer(nIDEvent);

}

 

void CLLKDlg::OnCaptureChanged(CWnd *pWnd)

{

// TODO: Add your message handler code here

 

CDialog::OnCaptureChanged(pWnd);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 初始化游戏

BOOL CLLKDlg::InitGame()

{

// 窗口大小调整

RECT rectWin;

RECT rectClient;

GetWindowRect(&rectWin);

GetClientRect(&rectClient);

 

m_sizeDC.cx = 800;

m_sizeDC.cy = 600;

 

this->SetWindowPos(NULL,

   0,

   0,

   m_sizeDC.cx + rectWin.right - rectClient.right,

   m_sizeDC.cy + rectWin.bottom - rectClient.bottom,

   SWP_NOZORDER | SWP_NOMOVE);

 

// 窗口文字

SetWindowText("连连看 0.1 ");

 

// 字体

LOGFONT LogFnt;

memset(&LogFnt, 0, sizeof(LOGFONT));  // 清零结构

LogFnt.lfHeight = 12; // 字体高度为22像素

strcpy(LogFnt.lfFaceName, "宋体"); // 设置字体

VERIFY(m_font.CreateFontIndirect(&LogFnt));   // 创建字体

 

// 相关DC创建

CDC *pDC = GetDC();

m_dcMem.CreateCompatibleDC(pDC);

 

m_dcMem.SelectObject(&m_font);

m_dcMem.SetTextColor(RGB(255, 255, 255));

 

 

m_dcBuf.CreateCompatibleDC(pDC);

m_dcBg.CreateCompatibleDC(pDC);

 

m_bmpBg.m_hObject = LoadImage(NULL,

"IMAGE/llkkong.bmp",

IMAGE_BITMAP,

0,

0,

LR_LOADFROMFILE);

 

m_bmpMem.CreateCompatibleBitmap(pDC, m_sizeDC.cx, m_sizeDC.cy);

m_bmpBuf.CreateCompatibleBitmap(pDC, m_sizeDC.cx, m_sizeDC.cy);

 

m_dcBg.SelectObject(&m_bmpBg);

m_dcMem.SelectObject(&m_bmpMem);

 

m_dcBg.SetBkMode(TRANSPARENT);

m_dcBg.SelectObject(&m_font);

m_dcBg.SetTextColor(RGB(255, 255, 255));

m_dcBg.TextOut(30, 8, "连连看 0.1 ");

 

::DrawIconEx(m_dcBg.m_hDC, 8 , 6, m_hIcon, 16, 16, 0, NULL, DI_NORMAL);

m_dcMem.BitBlt(0, 0, m_sizeDC.cx, m_sizeDC.cy, &m_dcBg, 0, 0, SRCCOPY);

 

m_dcMem.SetBkMode(TRANSPARENT);

 

ReleaseDC(pDC);

 

// 载入方块元素

CString str;

for (int i = 0; i < BOX_TYPE_SIZE; i++)

{

str.Format("IMAGE/%02d.bmp", i + 1);

m_bmpBox[i].m_hObject = LoadImage(NULL,

  str.GetBuffer(0),

  IMAGE_BITMAP,

  0,

  0,

  LR_LOADFROMFILE);

if (m_bmpBox[i].m_hObject == NULL)

{

MessageBox(str, "LOAD FILE ERROR!!!");

return FALSE;

}

 

str.Format("IMAGE/%02d_m.bmp", i + 1);

m_bmpMiniBox[i].m_hObject = LoadImage(NULL,

str.GetBuffer(0),

IMAGE_BITMAP,

0,

0,

LR_LOADFROMFILE);

 

if (m_bmpMiniBox[i].m_hObject == NULL)

{

MessageBox(str, "LOAD FILE ERROR!!!");

return FALSE;

}

}

 

// 刷新定时器

SetTimer(GAME_TIMER_ID_REFLASH, GAME_TIME_REFLASH, NULL);

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 刷新界面

void CLLKDlg::RefreshMain(CDC *pDC)

{

int x, y;

 

// 初始背景

m_dcMem.BitBlt(0, 0, m_sizeDC.cx, m_sizeDC.cy, &m_dcBg, 0, 0, SRCCOPY);

 

CString str;

str.Format("用户ID: %d",g_userid );

m_dcMem.TextOut(673, 103, str);

{

for (int i=0;i<6;i++)

{

if (g_llkGameMan.m_UID[i] == g_userid)

{

str.Format("昵  称: %s", g_llkGameMan.m_NickName[i]);

m_dcMem.TextOut(673, 130, str);

break;

}

}

}

// 显示剩余数

 

str.Format("剩余方块:%d", m_llk.m_nLeaveBoxCount);

m_dcMem.TextOut(GAME_LAST_BOX_COUNT_OUT_X, GAME_LAST_BOX_COUNT_OUT_Y, str);

 

str.Format("连击数:%d/%d", m_llk.m_nCurLianji, m_llk.m_nMaxLianji);

m_dcMem.TextOut(GAME_LAST_BOX_COUNT_OUT_X - 150,

GAME_LAST_BOX_COUNT_OUT_Y,

str);

 

str.Format("F5  重置  剩余:%d", m_resetCount);

m_dcMem.TextOut(633, 197, str);

// 如果没在游戏的显示

if (!m_bPlay)

{

 

}

if (m_bPlay || g_bLookOn)

{

// 画方块

for (y = 0; y < BOX_Y_COUNT; y++)

{

for (x = 0; x < BOX_X_COUNT; x++)

{

DrawBox(&m_dcMem, x, y, m_llk.m_nArrType[x][y]);

}

}

 

// 画选择框

for (int i = 0; i < m_llk.m_nSelBox; i++)

{

DrawSelectBox(&m_dcMem, m_llk.m_ptSelBox[i].x, m_llk.m_ptSelBox[i].y);

}

 

// 画将要删除的方块显示出来

if (m_llk.m_bHasWillBeNullBox)

{

DrawBox(&m_dcMem, m_llk.m_ptWillBeNullBox[0], m_llk.m_typeWillBeNullBox[0]);

DrawBox(&m_dcMem, m_llk.m_ptWillBeNullBox[1], m_llk.m_typeWillBeNullBox[1]);

}

 

// 画选择线

for (i = 0; i < m_llk.m_nLinkLine - 1; i++)

{

CPen pen;

pen.CreatePen(PS_JOIN_ROUND, 4, RGB(255, 0, 0));

 

CPen*pOldPen = m_dcMem.SelectObject(&pen);

m_dcMem.MoveTo(GetBoxRect(m_llk.m_ptLinkLine[i]).CenterPoint());

m_dcMem.LineTo(GetBoxRect(m_llk.m_ptLinkLine[i + 1]).CenterPoint());

m_dcMem.SelectObject(pOldPen);

}

 

// 画其它人状态

ShowPlayerState();

}

 

//DEBUG 信息

#ifdef __DEBUG

CPoint point;

GetCursorPos(&point);

 

ScreenToClient(&point);

str.Format("x=%d, y=%d     ", point.x, point.y);

 

CString strBoxPos;

 

CPoint ptSelBox = InWhichBox(point);

if (ptSelBox.x == -1 || ptSelBox.y == -1)

{

strBoxPos = "鼠标不在方块里!                        ";

}

else

{

strBoxPos.Format("鼠标在 %d%d                      ",

ptSelBox.x,

ptSelBox.y);

}

 

m_dcMem.TextOut(200, 60, str);

m_dcMem.TextOut(200, 80, strBoxPos);

 

// ReleaseDC(dc);

#endif

 

m_vbMan.OnPaint(&m_dcMem, &m_dcBuf);

 

// 显示到屏幕

pDC->BitBlt(0, 0, m_sizeDC.cx, m_sizeDC.cy, &m_dcMem, 0, 0, SRCCOPY);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 判断光标移动到哪个方块里

CPoint CLLKDlg::InWhichBox(CPoint mousePoint)

{

return InWhichBox(mousePoint.x, mousePoint.y);

}

 

CPoint CLLKDlg::InWhichBox(int _x, int _y)

{

CPoint point (-1, -1);

int x, y;

 

//先判断在哪个方块范围 包括间距

if (_x >= GAME_BEGIN_X && _x <= GAME_BEGIN_X + GAME_MAX_X - BOX_X_SEPRETER)

{

x = (_x - GAME_BEGIN_X) / (BOX_X + BOX_X_SEPRETER);

}

else

{

return point;

}

if (_y >= GAME_BEGIN_Y && _y <= GAME_BEGIN_Y + GAME_MAX_Y - BOX_Y_SEPRETER)

{

y = (_y - GAME_BEGIN_Y) / (BOX_Y + BOX_Y_SEPRETER);

}

else

{

return point;

}

 

//看是否是在方块里

if ((_x - GAME_BEGIN_X) >= x * (BOX_X + BOX_X_SEPRETER) &&

(_x - GAME_BEGIN_X) <= (x * (BOX_X + BOX_X_SEPRETER) + BOX_X))

{

point.x = x;

}

if ((_y - GAME_BEGIN_Y) >= y * (BOX_Y + BOX_Y_SEPRETER) &&

(_y - GAME_BEGIN_Y) <= (y * (BOX_Y + BOX_Y_SEPRETER) + BOX_Y))

{

point.y = y;

}

 

return point;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 判断一个点是否在一个范围内

BOOL CLLKDlg::IsInRect(CPoint point, CRect rect)

{

return rect.PtInRect(point);

}

 

BOOL CLLKDlg::IsInRect(int x, int y, CRect rect)

{

CPoint pt (x, y);

return rect.PtInRect(pt);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 画方块

void CLLKDlg::DrawBox(CDC *pDC, int x, int y, int mode /*= 0*/)

{

if (mode <= 0)

{

return;

}

if (mode > BOX_TYPE_SIZE)

{

mode = BOX_TYPE_SIZE;

}

 

RECT rect;

rect.left = x * (BOX_X + BOX_X_SEPRETER) + GAME_BEGIN_X ;

rect.top = y * (BOX_Y + BOX_Y_SEPRETER) + GAME_BEGIN_Y ;

rect.right = rect.left + BOX_X ;

rect.bottom = rect.top + BOX_Y ;

 

// 位图贴图模式

m_dcBuf.SelectObject(&m_bmpBox[mode - 1]);

pDC->BitBlt(rect.left, rect.top, BOX_X, BOX_Y, &m_dcBuf, 0, 0, SRCCOPY);

}

 

void CLLKDlg::DrawBox(CDC *pDC, CPoint pt, int mode /*= 0*/)

{

DrawBox(pDC, pt.x, pt.y, mode);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 绘制选中效果

void CLLKDlg::DrawSelectBox(CDC *pDC, int x, int y, int mode /*= 1*/)

{

if (mode <= 0)

{

return;

}

 

RECT rect;

rect.left = x * (BOX_X + BOX_X_SEPRETER) + GAME_BEGIN_X - 2;

rect.top = y * (BOX_Y + BOX_Y_SEPRETER) + GAME_BEGIN_Y - 2;

rect.right = rect.left + BOX_X + 4;

rect.bottom = rect.top + BOX_Y + 4;

 

CBrush brush;

brush.CreateStockObject(NULL_BRUSH);

 

CBrush *pOldBrush = pDC->SelectObject(&brush);

 

CPen pen;

pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));

 

CPen*pOldPen = pDC->SelectObject(&pen);

 

pDC->Rectangle(&rect);

rect.left++;

rect.right--;

rect.top++;

rect.bottom--;

pDC->Rectangle(&rect);

rect.left++;

rect.right--;

rect.top++;

rect.bottom--;

pDC->Rectangle(&rect);

rect.left++;

rect.right--;

rect.top++;

rect.bottom--;

pDC->Rectangle(&rect);

 

pDC->SelectObject(pOldPen);

pDC->SelectObject(pOldBrush);

}

 

void CLLKDlg::DrawSelectBox(CDC *pDC, CPoint pt, int mode /*= 1 */)

{

DrawSelectBox(pDC, pt.x, pt.y, mode);

}

//////////////////////////////////////////////////////////////////////////

 

 

 

//////////////////////////////////////////////////////////////////////////

// 得到方块的范围

CRect CLLKDlg::GetBoxRect(CPoint pt)

{

return GetBoxRect(pt.x, pt.y);

}

 

CRect CLLKDlg::GetBoxRect(int x, int y)

{

CRect rect;

rect.left = x * (BOX_X + BOX_X_SEPRETER) + GAME_BEGIN_X ;

rect.top = y * (BOX_Y + BOX_Y_SEPRETER) + GAME_BEGIN_Y ;

rect.right = rect.left + BOX_X ;

rect.bottom = rect.top + BOX_Y ;

 

return rect;

}

 

CLLK CLLKDlg::GetGameState()

{

return m_llk;

}

 

void CLLKDlg::ShowPlayerState()

{

CLLK * pLLK = NULL;

 

// 如果不在游戏的话显示

if (g_llkGameMan.m_state == GAME_NULL)

{

//TODO:

}

else if (g_llkGameMan.m_state == GAME_PLAYING)

{

// 游戏中则显示状态 缩略图

int showIndex = 0;

for (int n=0;n<6;n++)

{

pLLK = &g_llkGameMan.m_llk[n];

 

if (g_llkGameMan.m_UID[n] != 0 && g_llkGameMan.m_UID[n] != g_userid)

{

//TRACE("G g_llkGameMan...\n");

for (int y = 0; y < pLLK->m_nBoxYCount; y++)

{

for (int x = 0; x < pLLK->m_nBoxXCount; x++)

{

DrawStateBox(showIndex, x, y, pLLK);

}

}

showIndex ++;

}

}

}

}

 

void CLLKDlg::DrawStateBox( int index, int x, int y, CLLK * pLLK )

{

int type = pLLK->m_nArrType[x][y];

 

//TRACE("G llk index = %d, type = %d\n", index, type);

 

if (type == BT_NULL || type < 0)

{

return;

}

int width = 8;

int height = 10;

m_dcBuf.SelectObject(&m_bmpMiniBox[type - 1]);

m_dcMem.StretchBlt(GAME_PLAYER_STATE_X_BEGIN +

   index * 120 +

   width * x -

   3,

   GAME_PLAYER_STATE_Y_BEGIN +

   height * y -

   5,

   width,

   height,

   &m_dcBuf,

   0,

   0,

   10,

   10,

   SRCCOPY);

 

CString str;

str.Format("剩余方块:%d", pLLK->m_nLeaveBoxCount);

m_dcMem.TextOut(GAME_PLAYER_STATE_X_BEGIN + index * 120 + 30,

GAME_PLAYER_STATE_Y_BEGIN + 110,

str);

}

//////////////////////////////////////////////////////////////////////////

 

 

BOOL CLLKDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)

{

// TODO: Add your message handler code here and/or call default

int ret = g_gameWMLink.OnRecv(pWnd, pCopyDataStruct);

switch (ret)

{

case PTCS_GET_GAMEINFO:

TRACE("FC Get game info...\n");

g_llkGameMan.UnPack(pCopyDataStruct->lpData);

m_bPlayerStateNeedReflash = TRUE;

if (g_bLookOn)

{

//如果是旁观模式 则将信息复制到自己

m_bPlayerStateNeedReflash = TRUE;

for (int i=0;i<6;i++)

{

if (g_llkGameMan.m_UID[i] == g_userid)

{

TRACE("G Look on mode m_llk copyed ! my id = %d ...\n", g_userid);

m_llk = g_llkGameMan.m_llk[i];

}

}

if (i == 6)

{

MessageBox("游戏退出,因为你观看的玩家已退出游戏!", "提示");

OnCancel();

}

}

break;

case PTCS_EXIT:

MessageBox("服务器请求断开..游戏退出!");

OnOK();

break;

case PTS_GAME_BEGIN:

{

TRACE("S game begin... \n");

g_llkGameMan.UnPack(pCopyDataStruct->lpData);

m_bPlayerStateNeedReflash = TRUE;

for (int i=0;i<6;i++)

{

if (g_llkGameMan.m_UID[i] == g_userid)

{

TRACE("G m_llk copyed ! my id = %d ...\n", g_userid);

m_llk = g_llkGameMan.m_llk[i];

}

}

}

BeginGame();

break;

case PTS_GAME_END:

{

m_scoreList.UnPack(pCopyDataStruct->lpData);

PostMessage(WM_COMMAND, WMC_ENDGAME, 0);

m_bPlay = FALSE;

}

break;

}

return CDialog::OnCopyData(pWnd, pCopyDataStruct);

}

 

void CLLKDlg::OnDestroy()

{

CDialog::OnDestroy();

 

// TODO: Add your message handler code here

TRACE("TC send exit msg...\n");

g_gameWMLink.Send(PTCS_EXIT, 0, 0);

}

 

void CLLKDlg::OnVBMinisize()

{

this->ShowWindow(SW_MINIMIZE);

}

 

void CLLKDlg::OnVBClose()

{

OnCancel();

}

 

void CLLKDlg::InitVB()

{

m_rectTitleBar = CRect(0, 0, 800, 27);

 

m_bmpVBMinibox.m_hObject = LoadImage(NULL, "IMAGE\\minibox.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

m_bmpVBClosebox.m_hObject = LoadImage(NULL, "IMAGE\\closebox.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

m_bmpVBStart.m_hObject = LoadImage(NULL, "IMAGE\\zhunbei.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

m_bmpVBLianxi.m_hObject = LoadImage(NULL, "IMAGE\\lianxi.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

 

m_vbMan.AddBtn(this->m_hWnd, 0, CRect(CPoint(722+24, 4), CSize(24, 24)), &m_bmpVBMinibox, WMC_MINISIZE);

m_vbMan.AddBtn(this->m_hWnd, 0, CRect(CPoint(770, 4), CSize(24, 24)), &m_bmpVBClosebox, WMC_CLOSE);

m_vbMan.AddBtn(this->m_hWnd, 0, CRect(CPoint(621, 542), CSize(79, 36)), &m_bmpVBStart, WMC_START);

m_vbMan.AddBtn(this->m_hWnd, 0, CRect(CPoint(706, 542), CSize(79, 36)), &m_bmpVBLianxi, WMC_LIANXI);

}

 

void CLLKDlg::OnKillFocus(CWnd* pNewWnd)

{

CDialog::OnKillFocus(pNewWnd);

 

// TODO: Add your message handler code here

m_bIsMoveing = FALSE;

m_vbMan.OnMainWinKillFocus();

}

 

void CLLKDlg::OnVBStart()

{

g_gameWMLink.SendReady();

}

 

void CLLKDlg::OnVBLianxi()

{

 

}

 

void CLLKDlg::BeginGame()

{

TRACE("G Start game.... \n");

m_resetCount = 5;

m_bPlay = TRUE;

}

 

void CLLKDlg::OnEndGame()

{

CEndGameDlg egd;

egd.SetScoreList(m_scoreList);

egd.DoModal();

}

 

 

 

// LLKGameMan.cpp: implementation of the CLLKGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "LLKGameMan.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#include "../Common/User.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLKGameMan::CLLKGameMan()

{

m_state = GAME_NULL;

ZeroMemory(m_UID, sizeof(m_UID));

}

 

CLLKGameMan::~CLLKGameMan()

{

}

 

int CLLKGameMan::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(int) + sizeof(CLLKGameMan));

int dataSize = sizeof(CLLKGameMan);

cos << dataSize;

cos.Write(this, dataSize);

// cos.Write((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// char * pBuf = cos.GetCurPtr();

// int len = m_llk[i].Pack(pBuf);

// cos.MoveCurPtr(len);

// }

// }

// dataSize = cos.GetSize() - sizeof(int);

// *(int*)cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CLLKGameMan::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

cis.Read(this, sizeof(CLLKGameMan));

// cis.Read((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// const char * pBuf = cis.GetCurPtr();

// int len = m_llk[i].UnPack(pBuf);

// cis.MoveCurPtr(len);

// }

// }

return cis.GetSize();

}

 

BOOL CLLKGameMan::AddUser( int UID, char * nickName, int score, int tid, int sid )

{

if (m_UID[sid] == 0)

{

m_UID[sid] = UID;

strcpy(m_NickName[sid], nickName);

m_Score[sid] = score;

}

return TRUE;

}

 

BOOL CLLKGameMan::DelUser( int UID )

{

 

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_UID[i] = 0;

strcpy(m_NickName[i], "");

m_Score[i] = 0;

m_userState[i] = GAME_NULL;

if (GetUserCount() == 0)

{

m_state = GAME_NULL;

}

return TRUE;

}

}

 

return FALSE;

}

 

void CLLKGameMan::InitGame()

{

for (int i = 0; i < 6; i++)

{

m_llk[i].Init();

}

m_llk[0].InitGameData();

// m_llk[0].m_nArrType[1][1] = 1;

// m_llk[0].m_nArrType[1][5] = 1;

// m_llk[0].m_nLeaveBoxCount = 2;

for (i = 1; i < 6; i++)

{

m_llk[i] = m_llk[0];

}

}

 

void CLLKGameMan::SetUserState( int UID, int state )

{

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_userState[i] = state;

return;

}

}

}

 

int CLLKGameMan::CheckGame()

{

if (m_state == GAME_NULL)

{

int userCount = GetUserCount();

if (GetUserCount() == 0)

{

return 0;

}

int readyUserCount = GetReadyUserCount();

if (userCount == readyUserCount && userCount >= MINI_USER_TO_PLAY)

{

return CGR_TOBEGIN;

}

}

else if (m_state == GAME_PLAYING)

{

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_llk[i].m_nLeaveBoxCount == 0)

{

return CGR_TOEND;

}

}

}

 

return CGR_NULL;

}

 

int CLLKGameMan::GetUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

count++;

}

}

return count;

}

 

int CLLKGameMan::GetReadyUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_userState[i] == CUser::GAME_STATE_READY)

{

count++;

}

}

return count;

}

 

BOOL CLLKGameMan::StartGame( int nGameID /*= 1*/ )

{

m_state = GAME_PLAYING;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_PLAYING;

}

}

InitGame();

return TRUE;

}

 

CScoreList CLLKGameMan::EndGame( int nGameID /*= 1*/ )

{

CScoreList  sl;

//游戏结束前计算分数

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

SCORE_INFO si;

si.UID = m_UID[i];

strcpy(si.NickName, m_NickName[i]);

si.GameID = 1000;

si.Score = m_llk[i].m_nLeaveBoxCount;

sl.Add(si);

}

}

CalcScore(sl);

 

//清除各种状态

m_state = GAME_NULL;

for (i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_NULL;

}

}

 

return sl;

}

 

int CLLKGameMan::CalcScore( CScoreList &sl )

{

sl.Sort();

switch (sl.GetCount())

{

case 0:

TRACE("CalcScore not item in scoreList.. \n");

break;

case 1:

sl.GetScoreByIndex(0).Score = 1;

break;

case 2:

sl.GetScoreByIndex(0).Score = 2;

sl.GetScoreByIndex(1).Score = 0;

 

break;

case 3:

sl.GetScoreByIndex(0).Score = 3;

sl.GetScoreByIndex(1).Score = 1;

sl.GetScoreByIndex(2).Score = -1;

break;

case 4:

sl.GetScoreByIndex(0).Score = 4;

sl.GetScoreByIndex(1).Score = 2;

sl.GetScoreByIndex(2).Score = 0;

sl.GetScoreByIndex(3).Score = -1;

break;

case 5:

sl.GetScoreByIndex(0).Score = 5;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

break;

case 6:

sl.GetScoreByIndex(0).Score = 6;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

sl.GetScoreByIndex(5).Score = -2;

break;

}

return sl.GetCount();

}

 

 

// OutStream.cpp: implementation of the COutStream class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "OutStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

COutStream::COutStream()

{

m_pOutBuf = NULL;

m_pCurOutPtr = NULL;

m_nInitSize = 0;

m_nIncreaseSize = 0;

m_nMaxSize = 0;

// m_nCurSize = 0;

m_pUsedMaxPtr = 0;

}

 

COutStream::~COutStream()

{

if (m_pOutBuf != NULL)

{

delete[] m_pOutBuf;

}

}

 

BOOL COutStream::Create(int initSize /*= DEFAULT_INIT_SIZE*/,

int increaseSize /*= DEFAULT_INCREASE_SIZE*/)

{

//参数检测

if (m_pOutBuf != NULL)

{

TRACE("B COutStream::Create: Only can create once!\n");

return FALSE;

}

if (initSize <= 0)

{

initSize = DEFAULT_INIT_SIZE;

}

if (increaseSize <= 0)

{

initSize = DEFAULT_INCREASE_SIZE;

}

m_nInitSize = initSize;

m_nIncreaseSize = increaseSize;

 

//分配空间

m_pOutBuf = new char[m_nInitSize];

if (m_pOutBuf == NULL)

{

TRACE("B COutStream::Create new char error!\n");

return FALSE;

}

ZeroMemory(m_pOutBuf, m_nInitSize);

 

//指针维护

m_pCurOutPtr = m_pOutBuf;

m_pUsedMaxPtr = m_pCurOutPtr;

 

//大小维护

m_nMaxSize = m_nInitSize;

// m_nCurSize = 0;

return TRUE;

}

 

int COutStream::Write(const void *pData, int DataSize)

{

// 如果会造成数据溢出 则不执行操作

if (m_pCurOutPtr + DataSize - m_pOutBuf > m_nMaxSize)

{

TRACE("B COutStream::Write write range out of buf!\n");

return 0;

}

memcpy(m_pCurOutPtr, pData, DataSize);

 

//游标维护

m_pCurOutPtr += DataSize;

 

//当前大小维护

// m_nCurSize += DataSize;

 

//当前最大指针范围维护

if (m_pCurOutPtr > m_pUsedMaxPtr)

{

m_pUsedMaxPtr = m_pCurOutPtr;

}

return DataSize;

}

 

char * COutStream::GetHead()

{

return m_pOutBuf;

}

 

int COutStream::GetMaxSize()

{

return m_nMaxSize;

}

 

int COutStream::GetSize()

{

return m_pUsedMaxPtr - m_pOutBuf;

}

 

COutStream & COutStream::operator<<(int &value)

{

Write((const char *) &value, sizeof(int));

return *this;

}

 

COutStream & COutStream::operator<<(char &value)

{

Write((const char *) &value, sizeof(char));

return *this;

}

 

COutStream & COutStream::operator<<(char *value)

{

int len = strlen(value) + 1;

Write((const char *) &len, sizeof(len));

Write((const char *) &value, len);

return *this;

}

 

COutStream & COutStream::operator<<(CString &value)

{

int len = value.GetLength() + 1;

Write((const char *) &len, sizeof(len));

Write((const char *) value.GetBuffer(0), len);

return *this;

}

 

COutStream & COutStream::operator<<(long &value)

{

Write((const char *) &value, sizeof(long));

return *this;

}

 

COutStream & COutStream::operator<<(UINT &value)

{

Write((const char *) &value, sizeof(UINT));

return *this;

}

 

COutStream & COutStream::operator<<(ULONG &value)

{

Write((const char *) &value, sizeof(ULONG));

return *this;

}

 

COutStream & COutStream::operator<<(UCHAR &value)

{

Write((const char *) &value, sizeof(UCHAR));

return *this;

}

 

COutStream & COutStream::operator<<(float &value)

{

Write((const char *) &value, sizeof(float));

return *this;

}

 

COutStream & COutStream::operator<<(double &value)

{

Write((const char *) &value, sizeof(double));

return *this;

}

 

BOOL COutStream::MoveCurPtr(int offset, int mode /*= MD_CUR*/)

{

// 注意:此函数未对指针的访问范围进行严格检测 使用时请注意

if (mode == MP_CUR)

{

m_pCurOutPtr += offset;

}

else if (mode == MP_BEG)

{

if (offset < 0)

{

return FALSE;

}

m_pCurOutPtr = m_pOutBuf + offset;

}

else if (mode == MP_END)

{

if (m_nMaxSize == -1)

{

TRACE("B COutStream::MoveCurPtr MP_END mode not support m_nMaxSize = -1\n");

return FALSE;

}

if (offset > 0)

{

return FALSE;

}

  m_pCurOutPtr = m_pOutBuf + offset;

}

 

// 最大使用指针维护

if (m_pCurOutPtr > m_pUsedMaxPtr)

{

m_pUsedMaxPtr = m_pCurOutPtr;

}

 

return TRUE;

}

 

char * COutStream::GetCurPtr()

{

return m_pCurOutPtr;

}

 

void * COutStream::CopyTo( void *buf, int size /*= 0*/ )

{

if (buf == NULL)

{

return NULL;

}

if (size <= 0)

{

size = m_pUsedMaxPtr - m_pOutBuf;

}

memcpy(buf, m_pOutBuf, size);

return buf;

}

 

 

 

// ScoreList.cpp: implementation of the CScoreList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "ScoreList.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CScoreList::CScoreList()

{

 

}

 

CScoreList::~CScoreList()

{

 

}

 

int CScoreList::Pack( void * pData )

{

COutStream cos;

int dataSize = 0;

int count = GetCount();

cos.Create(count*sizeof(SCORE_INFO)+sizeof(int)*2);

 

cos<<dataSize;

cos<<count;

for (int i=0;i<count;i++)

{

cos.Write(&m_vecScore.at(i), sizeof(SCORE_INFO));

}

dataSize = cos.GetSize() - sizeof(int);

*(int*)cos.GetHead() = dataSize;

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CScoreList::UnPack( const void * pData )

{

m_vecScore.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

int count = 0;

cis>>dataSize>>count;

SCORE_INFO scoreInfo;

for (int i=0;i<count;i++)

{

cis.Read(&scoreInfo, sizeof(SCORE_INFO));

m_vecScore.push_back(scoreInfo);

}

return cis.GetSize();

}

 

void CScoreList::Add( SCORE_INFO& scoreInfo )

{

m_vecScore.push_back(scoreInfo);

}

 

BOOL CScoreList::Del( int uid, int gid )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

for (;begit != endit; ++begit)

{

if (begit->GameID == gid && begit->UID == uid)

{

m_vecScore.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

int CScoreList::GetCount()

{

return m_vecScore.size();

}

 

SCORE_INFO &CScoreList::GetScoreByIndex( int index )

{

return m_vecScore[index];

}

 

void CScoreList::Sort( int mode /*= 0*/ )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

VEC_SCORE_INFO::iterator tmpit = begit+1;

SCORE_INFO tsi;

int swapCount = 0;

do

{

swapCount = 0;

for (;begit != endit - 1; ++begit)

{

tmpit = begit+1;

if (begit->Score > tmpit->Score)

{

tsi = *begit;

*begit = *tmpit;

*tmpit = tsi;

swapCount++;

}

}

} while (swapCount != 0);

}

 

 

 

// stdafx.cpp : source file that includes just the standard includes

// LLK.pch will be the pre-compiled header

// stdafx.obj will contain the pre-compiled type information

 

#include "stdafx.h"

 

 

 

 

 

/*/////////////////////////////////////////////////////////////////////////

说明:UCode 文件,一些简单常用功能函数合集。

版本:1.0

创建:[4/5/2009 Dufeng]

修改:

*///////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 预处理

 

#include "StdAfx.h"

#include "UCode.h"

#include <windows.h>

#include <stdio.h>

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 宏定义

//#define BUFFER_SIZE 256

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:OnlyRunOne,只允许运行一个实例。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:TURE为可运行,FALSE为已经在运行

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

BOOL OnlyRunOne(WCHAR *_mutexName)

{

CreateMutexW(NULL, FALSE, _mutexName);

 

if (GetLastError() == ERROR_ALREADY_EXISTS)

{

return FALSE;

}

else

{

return TRUE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,获取上次的错误信息,会自动格式化信息内容。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

 

VOID GetLastErrorMsg(TCHAR *szBuf)

{

LPVOID lpMsgBuf;

DWORD dw = GetLastError();

 

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

  NULL,

  dw,

  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

  (LPTSTR) & lpMsgBuf,

  0,

  NULL);

 

sprintf(szBuf, "错误 %d: %s", dw, lpMsgBuf);

 

LocalFree(lpMsgBuf);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,检测键盘状态。

// 版本:1.0

// 创建:[4/6/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

 

BOOL GetOneKeyState(BYTE _key)

{

BYTE keyState[256];

 

GetKeyboardState((LPBYTE) & keyState);

return (keyState[_key] & 1);

}

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的的路径 不包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppPath(char *szFilePath)

{

char szTempFilePath[BUFFER_SIZE] ={0};

GetModuleFileName(NULL, szTempFilePath, BUFFER_SIZE - 1);

size_t nTemp = strlen(szTempFilePath) -

  strlen(strrchr(szTempFilePath, '\\'));

if (nTemp != -1)

{

szTempFilePath[nTemp + 1] = 0;

}

strcpy(szFilePath, szTempFilePath);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的全路径 包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppFileFullPathName(char *szFileName)

{

GetModuleFileName(NULL, szFileName, BUFFER_SIZE - 1);

}

//////////////////////////////////////////////////////////////////////////

 

 

// VirtualButton.cpp: implementation of the CVirtualButton class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "VirtualButton.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CVirtualButton::CVirtualButton(): m_Rect(0, 0, 0, 0)

{

m_hwndParent = NULL;

m_ID = 0;

m_pBmp = NULL;

m_cmd = 0;

 

m_isBtnDown = FALSE;

m_isOnMove = FALSE;

}

 

CVirtualButton::CVirtualButton(const CVirtualButton & vb )

{

m_hwndParent = vb.m_hwndParent;

m_ID = vb.m_ID;

m_Rect = vb.m_Rect;

m_pBmp = vb.m_pBmp;

m_cmd = vb.m_cmd;

 

m_isBtnDown = vb.m_isBtnDown;

m_isOnMove = vb.m_isOnMove;

}

CVirtualButton::~CVirtualButton()

{

 

}

 

CVirtualButton::operator=(const CVirtualButton &vb )

{

m_hwndParent = vb.m_hwndParent;

m_ID = vb.m_ID;

m_Rect = vb.m_Rect;

m_pBmp = vb.m_pBmp;

m_cmd = vb.m_cmd;

 

m_isBtnDown = vb.m_isBtnDown;

m_isOnMove = vb.m_isOnMove;

}

 

void CVirtualButton::Create( HWND hWnd, int id, CRect &rect, CBitmap *pBmp, int cmd )

{

m_hwndParent = hWnd;

m_ID = id;

m_Rect = rect;

m_pBmp = pBmp;

m_cmd = cmd;

}

 

BOOL CVirtualButton::OnMouseMove( CPoint point )

{

if (m_Rect.PtInRect(point))

{

m_isOnMove = TRUE;

return TRUE;

}

else

{

m_isOnMove = FALSE;

return FALSE;

}

}

 

BOOL CVirtualButton::OnLButtonDown( CPoint point )

{

if (m_Rect.PtInRect(point))

{

m_isBtnDown = TRUE;

return TRUE;

}

else

{

m_isBtnDown = FALSE;

return FALSE;

}

}

 

BOOL CVirtualButton::OnLButtonUp( CPoint point )

{

int bRet = FALSE;

if (m_isBtnDown && m_Rect.PtInRect(point))

{

::SendMessage(m_hwndParent, WM_COMMAND, m_cmd, 0);

bRet = TRUE;

}

m_isBtnDown = FALSE;

return FALSE;

}

 

void CVirtualButton::OnPaint( CDC *pDestDC, CDC * pBufDC )

{

if (m_pBmp == NULL)

{

return;

}

pBufDC->SelectObject(m_pBmp);

int x = 0;

int y = 0;

 

if (m_isBtnDown)

{

x = m_Rect.Width()*2;

}

else if (m_isOnMove)

{

x = m_Rect.Width();

}

pDestDC->BitBlt(m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height(), pBufDC, x, y, SRCCOPY);

}

 

void CVirtualButton::OnMainWinKillFocus()

{

m_isBtnDown = FALSE;

m_isOnMove = FALSE;

}

 

 

//  VirtualButtonMan.cpp: implementation of the CVirtualButtonMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "VirtualButtonMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CVirtualButtonMan::CVirtualButtonMan()

{

 

}

 

CVirtualButtonMan::~CVirtualButtonMan()

{

 

}

 

void CVirtualButtonMan::AddBtn(HWND hwnd, int id, CRect &rect, CBitmap *pBmp, int cmd)

{

CVirtualButton vb;

vb.Create(hwnd, id, rect, pBmp, cmd);

m_vecVB.push_back(vb);

}

 

void CVirtualButtonMan::AddBtn( CVirtualButton &vb )

{

m_vecVB.push_back(vb);

}

 

void CVirtualButtonMan::DelBtn( int id )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->m_ID == id)

{

m_vecVB.erase(begit);

}

}

}

 

BOOL CVirtualButtonMan::OnMouseMove( CPoint &point )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->OnMouseMove(point))

{

return TRUE;

}

}

return FALSE;

}

 

BOOL CVirtualButtonMan::OnLButtonDown( CPoint point )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->OnLButtonDown(point))

{

return TRUE;

}

}

return FALSE;

}

 

BOOL CVirtualButtonMan::OnLButtonUp( CPoint point )

{

int bRet = FALSE;

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->OnLButtonUp(point))

{

bRet = TRUE;

}

}

return bRet;

}

 

void CVirtualButtonMan::OnPaint( CDC *pDestDC, CDC *pBufDC )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

begit->OnPaint(pDestDC, pBufDC);

}

}

 

void CVirtualButtonMan::OnMainWinKillFocus()

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

begit->OnMainWinKillFocus();

}

}

 

 

// WMLink.cpp: implementation of the CWMLink class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "WMLink.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CWMLink::CWMLink()

{

m_myHwnd = NULL;

m_yourHwnd = NULL;

}

 

CWMLink::~CWMLink()

{

 

}

 

void CWMLink::Create( HWND myHwnd, HWND youHwnd )

{

m_myHwnd = myHwnd;

m_yourHwnd = youHwnd;

}

 

BOOL CWMLink::Send( DWORD nType, DWORD nSize, LPVOID pData )

{

COPYDATASTRUCT cds;

cds.dwData = nType;

cds.cbData = nSize;

cds.lpData = pData;

return ::SendMessage(m_yourHwnd, WM_COPYDATA, (WPARAM)m_myHwnd, (LPARAM)&cds);

}

 

BOOL CWMLink::Post( DWORD nType, DWORD nSize, LPVOID pData )

{

COPYDATASTRUCT cds;

cds.dwData = nType;

cds.cbData = nSize;

cds.lpData = pData;

return ::PostMessage(m_yourHwnd, WM_COPYDATA, (WPARAM)m_myHwnd, (LPARAM)&cds);

}

 

 

 

#ifndef __CLIENT_DEFINE_H_

#define __CLIENT_DEFINE_H_

 

//窗口颜色

#define ROOM_BACK_COLOR RGB(82,113,156)

 

//窗口大小

#define MIN_WIDTH_OF_SERVER_TREE 300

#define MIN_WIDTH_OF_HALL_DLG 300

 

//窗口消息

#define WM_NET_MSG WM_USER+1

 

#define WM_SEAT_DOWN WM_USER+100

#define WM_LOOK_ON WM_USER+101

 

//TimerID

#define WAIT_MSG_FROM_SERVER_TIMER_ID 10

 

 

//////////////////////////////////////////////////////////////////////////

// 定义发送的消息类型

// #define GM_NULL 0

// #define GM_GAME_HWND 1

// #define GM_SEND_GAME_INFO 2

// #define GM_GET_GAME_INFO 3

// #define GM_EXIT 4

 

//////////////////////////////////////////////////////////////////////////

#endif //__CLIENT_DEFINE_H_

 

 

// CLLK.h: interface for the CLLK class.

// 连连看游戏封装

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_CLLK_H__3524DD44_7C12_44D5_9C56_E7E47FE54BF4__INCLUDED_)

#define AFX_CLLK_H__3524DD44_7C12_44D5_9C56_E7E47FE54BF4__INCLUDED_

#include "LLKDefine.h"

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

enum BOX_TYPE

{

BT_NULL = 0

};

 

// 连连看结构体

typedef struct _LLK_STATE

{

// 游戏状态

int m_nBoxXCount;

int m_nBoxYCount;

int m_nArrType[BOX_X_COUNT][BOX_Y_COUNT]; //矩阵元素数组

 

int m_nSelBox; //当前选择的方块个数

CPoint m_ptSelBox[2]; //当前选择的坐标

 

int m_nLeaveBoxCount; //剩余的方块数

 

BOOL m_bHasWillBeNullBox; //是否存在要被删除的方块

CPoint m_ptWillBeNullBox[2]; //将要被删除的方块 为了延迟显示消除

int m_typeWillBeNullBox[2]; //将要被删除的方块的类型

 

int m_nLinkLine; //被消除时需要的连接线的个数

CPoint m_ptLinkLine[4]; //消除时需要的连接各坐标

 

int m_nMaxLianji; //最大连击数

int m_nCurLianji; //当前连击数

DWORD m_dwLastLianjiTime; //上次的连击时间

}LLK_STATE;

 

// 连连看类

class CLLK : public LLK_STATE

{

public:

CLLK();

virtual ~CLLK();

 

int Pack(char *pData);

int UnPack(const void *pData);

 

void Init();

VOID InitGameData(int mode = 0);

BOOL IsPairCanLink(CPoint pt1,

  CPoint pt2,

  int *nResultPtCount = NULL,

  CPoint *result = NULL); //判断两坐标是否消除

 

BOOL IsPairInlineValid(CPoint pt1, CPoint pt2); //判断两坐标是否在同一线上 并且中间无阻碍

BOOL IsCanXiaoChu(); //判断当时是否有可以消除的两张图

BOOL DoXiaoChu(); //执行消除

void ResetBoxState();

};

 

#endif // !defined(AFX_CLLK_H__3524DD44_7C12_44D5_9C56_E7E47FE54BF4__INCLUDED_)

 

 

#if !defined(AFX_ENDGAMEDLG_H__843025C2_F1B5_4010_A8B9_0DE3395BF8B4__INCLUDED_)

#define AFX_ENDGAMEDLG_H__843025C2_F1B5_4010_A8B9_0DE3395BF8B4__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// EndGameDlg.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CEndGameDlg dialog

 

class CEndGameDlg : public CDialog

{

// Construction

public:

CEndGameDlg(CWnd* pParent = NULL);   // standard constructor

void SetScoreList(CScoreList &sl);

// Dialog Data

//{{AFX_DATA(CEndGameDlg)

enum { IDD = IDD_DLG_ENDGAME };

CListCtrl m_listScore;

//}}AFX_DATA

 

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CEndGameDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

protected:

CScoreList m_scoreList;

 

// Generated message map functions

//{{AFX_MSG(CEndGameDlg)

virtual BOOL OnInitDialog();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_ENDGAMEDLG_H__843025C2_F1B5_4010_A8B9_0DE3395BF8B4__INCLUDED_)

 

 

// GameWMLink.h: interface for the CGameWMLink class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_GAMEWMLINK_H__45BBAADE_F449_4533_B4B4_8621A66E63A2__INCLUDED_)

#define AFX_GAMEWMLINK_H__45BBAADE_F449_4533_B4B4_8621A66E63A2__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "..\COMMON\WMLink.h"

#include "..\Common\CLLK.h"

#include "..\Common\ServerDefine.h"

 

class CGameWMLink : public CWMLink  

{

public:

CGameWMLink();

virtual ~CGameWMLink();

INT OnRecv(CWnd *pWnd, COPYDATASTRUCT *pCopyData);

void SendMyGameInfo(CLLK * pLLK);

void SendCheckOnline();

void SendReady();

 

 

};

 

#endif // !defined(AFX_GAMEWMLINK_H__45BBAADE_F449_4533_B4B4_8621A66E63A2__INCLUDED_)

 

 

// LLK.h : main header file for the LLK application

//

 

#if !defined(AFX_LLK_H__0C3CEF42_CF21_408A_A4F4_26F9675F071A__INCLUDED_)

#define AFX_LLK_H__0C3CEF42_CF21_408A_A4F4_26F9675F071A__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#ifndef __AFXWIN_H__

#error include 'stdafx.h' before including this file for PCH

#endif

 

#include "GameWMLink.h"

#include "../Common/LLKGameMan.h"

#include "resource.h" // main symbols

 

extern HWND g_hWndParent;

extern CGameWMLink g_gameWMLink;

extern CLLKGameMan g_llkGameMan;

extern int g_userid;

extern BOOL g_bLookOn;

/////////////////////////////////////////////////////////////////////////////

// CLLKApp:

// See LLK.cpp for the implementation of this class

//

 

class CLLKApp : public CWinApp

{

public:

CLLKApp();

BOOL CheckRunEnv();

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CLLKApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL

 

// Implementation

 

//{{AFX_MSG(CLLKApp)

// NOTE - the ClassWizard will add and remove member functions here.

//    DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

 

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_LLK_H__0C3CEF42_CF21_408A_A4F4_26F9675F071A__INCLUDED_)

 

 

//////////////////////////////////////////////////////////////////////////

// define.h 公共定义文件

 

#ifndef __LLK_DEFINE_H

#define __LLK_DEFINE_H

 

// 游戏基本设置

#define GAME_BEGIN_X -10 //游戏框起始X

#define GAME_BEGIN_Y 160 //游戏框起始Y

 

#define BOX_X_COUNT 14 //X轴方块个数

#define BOX_Y_COUNT 10 //Y轴方块个数

 

#define BOX_X 40 //方块X像素

#define BOX_Y 40 //方块Y像素

 

#define BOX_X_SEPRETER 5 //方块X间距

#define BOX_Y_SEPRETER 4 //方块Y间距

 

#define GAME_MAX_X BOX_X_COUNT*(BOX_X+BOX_X_SEPRETER) //游戏窗口X大小

#define GAME_MAX_Y BOX_Y_COUNT*(BOX_Y+BOX_Y_SEPRETER) //游戏窗口Y大小

 

#define GAME_LAST_BOX_COUNT_OUT_X 480

#define GAME_LAST_BOX_COUNT_OUT_Y 570

 

#define BOX_TYPE_SIZE 16 //方块种类总数

 

#define GAME_DRAW_LINK_LINE_TIMER_ID 100

#define GAME_DRAW_LINK_LINE_TIME 500

 

#define GAME_TIMER_ID_REFLASH 101

#define GAME_TIME_REFLASH 1000/60

 

#define GAME_LIANJI_TIMEOUT 2000

 

#define GAME_PLAYER_STATE_X_BEGIN 16

#define GAME_PLAYER_STATE_Y_BEGIN 36

//BOX_TYPE

 

typedef struct _BOX_STATE

{

INT nType;

// BOOL bIsSelect;

INT nAniState;

}BOX_STATE;

 

#endif

 

 

 

//  LLKDlg.h : header file

//

 

#if !defined(AFX_LLKDLG_H__3222FCB7_27A1_45B3_BA24_2D4861C470AB__INCLUDED_)

#define AFX_LLKDLG_H__3222FCB7_27A1_45B3_BA24_2D4861C470AB__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "..\Common\CLLK.h"

#include "..\Common\VirtualButtonMan.h"

/////////////////////////////////////////////////////////////////////////////

// CLLKDlg dialog

class CLLKDlg : public CDialog

{

// Construction

public:

CLLKDlg(CWnd *pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CLLKDlg)

enum { IDD = IDD_LLK_DIALOG };

//}}AFX_DATA

 

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CLLKDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL

 

// Implementation

BOOL InitGame(); //初始化游戏

 

void DrawBox(CDC *pDC, int x, int y, int mode = 0); //画方块

void DrawBox(CDC *pDC, CPoint pt, int mode = 0);

 

void DrawSelectBox(CDC *pDC, int x, int y, int mode = 1); //画选中的方块

void DrawSelectBox(CDC *pDC, CPoint pt, int mode = 1);

 

void RefreshMain(CDC *pDC); //刷新主界面

 

CPoint InWhichBox(CPoint mousePoint); //判断指定的鼠标坐标指向方块的坐标

CPoint InWhichBox(int x, int y); //判断指定的鼠标坐标指向方块的坐标

 

BOOL IsInRect(CPoint point, CRect rect); //判断鼠标坐标是否在指定区域

BOOL IsInRect(int x, int y, CRect rect);

 

CRect GetBoxRect(CPoint pt); //得到方块的范围

CRect GetBoxRect(int x, int y); //得到方块的范围

 

CLLK GetGameState(); //得到游戏状态

 

void ShowPlayerState(); //显示其它玩家状态

void DrawStateBox(int index, int x, int y, CLLK * pLLK);

 

void InitVB(); //初始化虚拟控件

void BeginGame();

 

protected:

// 游戏是否开始

BOOL m_bPlay;

 

// 游戏图标

HICON m_hIcon;

 

// 游戏状态

CLLK m_llk;

int m_resetCount;

BOOL m_bPlayerStateNeedReflash;

 

// 多缓冲使用的DC

CDC m_dcMem; //内存DC

CDC m_dcBuf; //缓冲DC 画图时需要

CDC m_dcBg; //背景DC

 

CSize m_sizeDC; //DC的大小

 

CBitmap m_bmpBg; //背景位图

CBitmap m_bmpMem; //内存位图 用于设定内存DC的大小

CBitmap m_bmpBuf; //缓冲位图 用于让缓冲dc足够大

 

// 图片资料

CBitmap m_bmpBox[BOX_TYPE_SIZE];

CBitmap m_bmpMiniBox[BOX_TYPE_SIZE];

 

// 字体

CFont m_font;

 

// 左键的状态

BOOL m_bLBtnDown;

CPoint m_ptLBtnDown;

 

// 窗口移动

BOOL m_bIsMoveing;

 

// 虚拟控件

CVirtualButtonMan m_vbMan;

// 界面相关区域

CRect m_rectTitleBar;

 

// 控件用到的BMP

CBitmap m_bmpVBMinibox;

CBitmap m_bmpVBClosebox;

CBitmap m_bmpVBStart;

CBitmap m_bmpVBLianxi;

 

// 游戏结果用到的分数表

CScoreList m_scoreList;

 

 

// Generated message map functions

//{{AFX_MSG(CLLKDlg)

virtual BOOL OnInitDialog();

afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

afx_msg void OnPaint();

afx_msg HCURSOR OnQueryDragIcon();

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

afx_msg void OnCancelMode();

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnCaptureChanged(CWnd *pWnd);

afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);

afx_msg void OnDestroy();

afx_msg void OnVBMinisize();

afx_msg void OnVBClose();

afx_msg void OnVBStart();

afx_msg void OnVBLianxi();

afx_msg void OnKillFocus(CWnd* pNewWnd);

afx_msg void OnEndGame();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

LRESULT OnGetDefID(WPARAM wp, LPARAM lp);

};

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_LLKDLG_H__3222FCB7_27A1_45B3_BA24_2D4861C470AB__INCLUDED_)

 

 

 

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by LLK.rc

//

#define IDM_ABOUTBOX                    0x0010

#define IDD_ABOUTBOX                    100

#define IDS_ABOUTBOX                    101

#define IDD_LLK_DIALOG                  102

#define IDP_SOCKETS_INIT_FAILED         103

#define IDR_MAINFRAME                   128

#define IDD_DLG_ENDGAME                 145

#define IDC_LIST_SCORE                  1050

 

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE        130

#define _APS_NEXT_COMMAND_VALUE         32772

#define _APS_NEXT_CONTROL_VALUE         1006

#define _APS_NEXT_SYMED_VALUE           101

#endif

#endif

 

 

// stdafx.h : include file for standard system include files,

//  or project specific include files that are used frequently, but

//   are changed infrequently

//

 

#if !defined(AFX_STDAFX_H__05A38DDA_18F4_4F2C_AC12_A3ED24EF3D73__INCLUDED_)

#define AFX_STDAFX_H__05A38DDA_18F4_4F2C_AC12_A3ED24EF3D73__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

 

#include <afxwin.h> // MFC core and standard components

#include <afxext.h> // MFC extensions

#include <afxdisp.h> // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h> // MFC support for Windows Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

 

//#include <afxsock.h> // MFC socket extensions

 

#include "../Common/ClientDefine.h"

#include "../Basic/UCode.h"

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_STDAFX_H__05A38DDA_18F4_4F2C_AC12_A3ED24EF3D73__INCLUDED_)

 

 

// VirtualButton.h: interface for the CVirtualButton class.

// 用于游戏里的按钮绘制

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_VIRTUALBUTTON_H__4CE87721_3410_4E6D_A23A_34E894570D27__INCLUDED_)

#define AFX_VIRTUALBUTTON_H__4CE87721_3410_4E6D_A23A_34E894570D27__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CVirtualButtonMan;

 

class CVirtualButton  

{

public:

enum{

VB_NULL = 0,

VB_ONMOVE = 1,

VB_ONDOWN = 2,

VB_ONUP = 3

};

public:

CVirtualButton();

CVirtualButton(const CVirtualButton & vb);

virtual ~CVirtualButton();

void Create(HWND hWnd, int id, CRect &rect, CBitmap *pBmp, int cmd);

BOOL OnMouseMove(CPoint point);

BOOL OnLButtonDown(CPoint point);

BOOL OnLButtonUp(CPoint point);

void OnMainWinKillFocus();

 

void OnPaint(CDC *pDestDC, CDC * pBufDC);

 

operator =(const CVirtualButton &vb);

friend CVirtualButtonMan;

 

public:

HWND m_hwndParent; //主窗口句柄

int m_ID; //唯一标识

BOOL m_isBtnDown;

BOOL m_isOnMove;

CRect m_Rect; //范围

CBitmap *m_pBmp; //关联的图片

int m_cmd; //ON_COMMOND消息类型 用于向主窗口发送消息实现功能

 

};

 

#endif // !defined(AFX_VIRTUALBUTTON_H__4CE87721_3410_4E6D_A23A_34E894570D27__INCLUDED_)

 

 

 

// VirtualButtonMan.h: interface for the CVirtualButtonMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_VIRTUALBUTTONMAN_H__421D9ABF_941E_43D5_BA96_04AC043339A0__INCLUDED_)

#define AFX_VIRTUALBUTTONMAN_H__421D9ABF_941E_43D5_BA96_04AC043339A0__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "VirtualButton.h"

#include <vector>

using namespace std;

 

class CVirtualButton;

 

typedef vector<CVirtualButton> VEC_VB;

 

class CVirtualButtonMan  

{

public:

CVirtualButtonMan();

virtual ~CVirtualButtonMan();

void AddBtn(HWND hwnd, int id, CRect &rect, CBitmap *pBmp, int cmd);

void AddBtn(CVirtualButton &vb);

void DelBtn(int id);

 

BOOL OnMouseMove(CPoint &point);

BOOL OnLButtonDown(CPoint point);

BOOL OnLButtonUp(CPoint point);

void OnPaint(CDC *pDestDC, CDC *pBufDC);

void OnMainWinKillFocus();

private:

VEC_VB m_vecVB;

 

};

 

#endif // !defined(AFX_VIRTUALBUTTONMAN_H__421D9ABF_941E_43D5_BA96_04AC043339A0__INCLUDED_)

 

 

// WMLink.h: interface for the CWMLink class.

// 基于窗口的连接通讯 点对点的 方便游戏客户端有大厅通讯

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_)

#define AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CWMLink

{

public:

CWMLink();

virtual ~CWMLink();

virtual void Create(HWND myHwnd, HWND youHwnd);

virtual BOOL Send(DWORD nType, DWORD nSize, LPVOID pData);

virtual BOOL Post(DWORD nType, DWORD nSize, LPVOID pData);

 

virtual INT OnRecv(CWnd *pWnd, COPYDATASTRUCT *pCopyData) = 0;

 

virtual void SetMyHwnd(HWND val)

{

m_myHwnd = val;

}

virtual void SetYourHwnd(HWND val)

{

m_yourHwnd = val;

}

 

protected:

HWND m_myHwnd;

 

HWND m_yourHwnd;

};

 

#endif // !defined(AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_)

 

 

 

Basic封装的基础类

 

 

// Ado.cpp: implementation of the CAdo class.

//

//////////////////////////////////////////////////////////////////////

 

#include "StdAfx.h"

#include "Ado.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

 

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CAdoConnection::CAdoConnection()

{

m_szOpenStr = "";

m_szOpenUsername = "";

m_szOpenPassword = "";

}

 

CAdoConnection::CAdoConnection(const CString openStr,

   const CString szUser /*= ""*/,

   const CString szPassword /*= ""*/)

{

m_szOpenStr = openStr;

m_szOpenUsername = szUser;

m_szOpenPassword = szPassword;

}

 

CAdoConnection::~CAdoConnection()

{

Close();

}

 

VOID CAdoConnection::Create()

{

m_pCon.CreateInstance("ADODB.Connection");

 

if (NULL == m_pCon)

{

int err = GetLastError();

throw "CreateInstance Error!";

}

}

 

VOID CAdoConnection::Open()

{

Open(m_szOpenStr, m_szOpenUsername, m_szOpenPassword);

}

 

VOID CAdoConnection::Open(CString openStr,

  CString szUser /*= ""*/,

  CString szPassword /*= ""*/)

{

if (NULL == m_pCon)

{

return;

}

 

if (m_pCon->State)

{

TRACE("D DB open already!!!\n");

return;

}

 

m_szOpenStr = openStr;

m_szOpenUsername = szUser;

m_szOpenPassword = szPassword;

 

try

{

HRESULT hr = m_pCon->Open((LPCTSTR) m_szOpenStr,

   (LPCTSTR) m_szOpenUsername,

   (LPCTSTR) m_szOpenPassword,

   adModeUnknown);

 

if (SUCCEEDED(hr))

{

TRACE("D Ado Con Open Ok!");

}

}

catch (_com_error &err)

{

_bstr_t str = err.Description();

MessageBox(NULL, (LPCTSTR) str, "_com_error", 0);

}

}

 

 

VOID CAdoConnection::Close()

{

if (m_pCon == NULL)

{

return ;

}

if (this->State())

{

m_pCon->Close();

m_pCon = NULL;

}

}

 

CAdoRecordSet CAdoConnection::Execute(CString sqlText,

  long *lRecordAffected,

  long Options /*= adOptionUnspecified */)

{

CAdoRecordSet adoSet;

_RecordsetPtr setPtr;

try

{

setPtr = m_pCon->Execute((LPCTSTR) sqlText,

 (VARIANT *) lRecordAffected,

 Options);

adoSet.m_pAdoCon = this;

adoSet.m_pSet = setPtr;

adoSet.m_szSql = sqlText;

}

catch (_com_error &err)

{

_bstr_t str = err.Description();

 

MessageBox(NULL, (LPCTSTR) str, "_com_error at Execute", 0);

}

return adoSet;

}

 

long CAdoConnection::State()

{

return m_pCon->State;

}

//////////////////////////////////////////////////////////////////////////

 

CAdoRecordSet::CAdoRecordSet()

{

m_pSet = NULL;

m_pAdoCon = NULL;

m_szSql.Empty();

}

 

CAdoRecordSet::CAdoRecordSet(_RecordsetPtr pSet)

{

m_pSet = pSet;

m_pAdoCon = NULL;

m_szSql.Empty();

}

CAdoRecordSet::~CAdoRecordSet()

{

Close();

}

 

VOID CAdoRecordSet::Close()

{

if (m_pSet == NULL)

{

return ;

}

 

if (this->State())

{

m_pSet->Close();

}

}

 

CAdoRecordSet::operator _RecordsetPtr()

{

return m_pSet;

}

 

VOID CAdoRecordSet::Create()

{

m_pSet.CreateInstance("ADODB.RecordSet");

if (m_pSet == NULL)

{

throw "CreateInstance ADODB.RecordSet Error!";

}

}

 

VOID CAdoRecordSet::Open(const CString szSql,

 CAdoConnection &AcctiveConnection,

 enum CursorTypeEnum CursorType /*= adOpenDynamic */,

 enum LockTypeEnum LockType /*= adLockOptimistic*/,

 long Options /*= adCmdText*/)

{

try

{

HRESULT hr = m_pSet->Open((LPCTSTR) szSql,

   AcctiveConnection.m_pCon.GetInterfacePtr(),

   adOpenDynamic,

   adLockOptimistic,

   adCmdText);

if (SUCCEEDED(hr))

{

TRACE("D Ado Set Open Ok!\n");

}

}

catch (_com_error &err)

{

_bstr_t str = err.Description();

MessageBox(NULL, (LPCTSTR) str, "_com_error", 0);

}

}

 

 

BOOL CAdoRecordSet::adoEOF()

{

return m_pSet->adoEOF;

}

 

_variant_t CAdoRecordSet::GetCollect(const _variant_t &index)

{

return m_pSet->GetCollect(index);

}

 

HRESULT CAdoRecordSet::MoveFirst()

{

return m_pSet->MoveFirst();

}

 

HRESULT CAdoRecordSet::MoveLast()

{

return m_pSet->MoveLast();

}

 

HRESULT CAdoRecordSet::MoveNext()

{

return m_pSet->MoveNext();

}

 

HRESULT CAdoRecordSet::MovePrevious()

{

return m_pSet->MovePrevious();

}

 

HRESULT CAdoRecordSet::Move(ADO_LONGPTR NumRecords,

const _variant_t &Start /* = vtMissing */)

{

return m_pSet->Move(NumRecords, Start);

}

 

long CAdoRecordSet::State()

{

return m_pSet->State;

}

 

HRESULT CAdoRecordSet::AddNew()

{

return m_pSet->AddNew();

}

 

HRESULT CAdoRecordSet::Update()

{

return m_pSet->Update();

}

 

HRESULT CAdoRecordSet::Delete(enum AffectEnum AffectRecords /*= adAffectCurrent*/)

{

return m_pSet->Delete(AffectRecords);

}

 

VOID CAdoRecordSet::PutCollect(const _variant_t &Index, const _variant_t &pvar)

{

m_pSet->PutCollect(Index, pvar);

}

 

HRESULT CAdoRecordSet::Requery(long Options /*= adOptionUnspecified*/)

{

return m_pSet->Requery(Options);

}

 

LONG CAdoRecordSet::GetRecordCount()

{

return m_pSet->GetRecordCount();

}

 

BOOL CAdoRecordSet::BOF()

{

return m_pSet->BOF;

}

 

BOOL CAdoRecordSet::IsEmpty()

{

return BOF() && adoEOF();

}

 

 

 

// Ado.h: interface for the CAdo class.

// ADO数据库类封装

//////////////////////////////////////////////////////////////////////

 

#ifndef __ADO_H_

#define __ADO_H_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

// 基本头文件包含

#import "C:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "adoEOF")

#include <icrsint.h>

 

class CAdoConnection;

class CAdoRecordSet;

 

// ADO 连接类

class CAdoConnection

{

public:

CAdoConnection();

CAdoConnection(const CString openStr,

   const CString szUser = "",

   const CString szPassword = "");

virtual ~CAdoConnection();

VOID Create();

VOID Open();

VOID Open(const CString openStr,

 const CString szUser = "",

 const CString szPassword = "");

VOID Close();

CAdoRecordSet Execute(CString sqlText,

long *lRecordAffected,

long Options = adOptionUnspecified);

long State();

 

public:

_ConnectionPtr m_pCon;

CString m_szOpenStr;

CString m_szOpenUsername;

CString m_szOpenPassword;

private:

};

 

// ADO 记录集类

class CAdoRecordSet

{

public:

CAdoRecordSet();

CAdoRecordSet(_RecordsetPtr pSet);

~CAdoRecordSet();

VOID Create();

VOID Open(const CString szSql,

 CAdoConnection &AcctiveConnection,

 enum CursorTypeEnum CursorType = adOpenDynamic,

 enum LockTypeEnum LockType = adLockOptimistic,

 long Options = adCmdText);

VOID Close();

long State();

 

LONG GetRecordCount();

 

HRESULT MoveFirst();

HRESULT MoveLast();

HRESULT MoveNext();

HRESULT MovePrevious();

HRESULT Move(ADO_LONGPTR NumRecords,

 const _variant_t &Start = vtMissing);

 

BOOL BOF();

BOOL adoEOF();

_variant_t GetCollect(const _variant_t &index);

VOID PutCollect(const _variant_t &Index, const _variant_t &pvar);

HRESULT Requery(long Options = adOptionUnspecified);

 

HRESULT AddNew();

HRESULT Update();

HRESULT Delete(enum AffectEnum AffectRecords = adAffectCurrent);

 

BOOL IsEmpty();

 

operator _RecordsetPtr();

 

public:

_RecordsetPtr m_pSet;

 

CAdoConnection *m_pAdoCon;

CString m_szSql;

};

#endif // __ADO_H_

 

 

 

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 预处理

#include "Ini.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 函数实现

CString GetIniString(CString sec,

 CString key,

 CString str,

 CString sIniFileName)

{

CString sss;

GetPrivateProfileString(sec,

key,

str,

sss.GetBuffer(512),

511,

sIniFileName);

sss.ReleaseBuffer();

return sss;

}

 

BOOL SetIniString(CString sec, CString key, CString str, CString sIniFileName)

{

return WritePrivateProfileString(sec, key, str, sIniFileName);

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 预处理

#pragma once

#include <afx.h>

#include <Windows.h>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// CIni

// class CIni

// {

// public:

// CIni();

// CIni(CString strIniFilePath);

// ~CIni();

// public:

// BOOL Creat(CString strIniFilePath);

//

// }

 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

CString GetIniString(CString sec,

 CString key,

 CString str,

 CString sIniFileName);

 

BOOL SetIniString(CString sec, CString key, CString str, CString sIniFileName);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

// InStream.cpp: implementation of the CInStream class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "InStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CInStream::CInStream()

{

m_pInBuf = NULL;

m_pCurInPtr = NULL;

m_pMaxInPtr = NULL;

m_nMaxSize = 0;

}

 

CInStream::~CInStream()

{

}

 

BOOL CInStream::Create( const void *pData )

{

int BufMaxSize = -1;

if (pData == NULL)

{

return FALSE;

}

m_nMaxSize = BufMaxSize;

m_pInBuf = pData;

m_pCurInPtr = m_pInBuf;

m_pMaxInPtr = m_pCurInPtr;

return FALSE;

}

 

int CInStream::Read(void *savePtr, int readSize)

{

if (savePtr == NULL || readSize <= 0)

{

TRACE("B CInStream::Read prarm is zero!\n");

return 0;

}

if (m_nMaxSize != -1 && (const char *)m_pCurInPtr + readSize - (const char *)m_pInBuf > m_nMaxSize)

{

TRACE("B CInStread::Read out of range!\n");

return 0;

}

memcpy(savePtr, m_pCurInPtr, readSize);

m_pCurInPtr = (const char *)m_pCurInPtr + readSize;

 

//最大访问指针维护

if (m_pCurInPtr > m_pMaxInPtr)

{

m_pMaxInPtr = m_pCurInPtr;

}

return readSize;

}

 

const void * CInStream::GetHead()

{

return m_pInBuf;

}

 

const void * CInStream::GetCurPtr()

{

return m_pCurInPtr;

}

 

 

//////////////////////////////////////////////////////////////////////////

// 注意:此函数并未严格判定访问是否越界 使用时小心

BOOL CInStream::MoveCurPtr(int offset, int mode /*= MP_CUR*/)

{

if (mode == MP_CUR)

{

m_pCurInPtr = (const char *)m_pCurInPtr + offset;

}

else if (mode == MP_BEG)

{

if (offset < 0)

{

return FALSE;

}

m_pCurInPtr = (const char *)m_pInBuf + offset;

}

else if (mode == MP_END)

{

if (m_nMaxSize == -1)

{

TRACE("B CInStream::MoveCurPtr MP_END mode not support m_nMaxSize = -1\n");

return FALSE;

}

if (offset > 0)

{

return FALSE;

}

  m_pCurInPtr = (const char *)m_pInBuf + offset;

}

if (m_pCurInPtr > m_pMaxInPtr)

{

m_pMaxInPtr = m_pCurInPtr;

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

int CInStream::GetSize()

{

return (const char *)m_pMaxInPtr - (const char *)m_pInBuf;

}

 

int CInStream::GetMaxSize()

{

return m_nMaxSize;

}

 

CInStream & CInStream::operator>>(int &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(char &value)

{

Read((char *) &value, sizeof(char));

return *this;

}

 

CInStream & CInStream::operator>>(char *value)

{

int len = 0;

Read((char *) &len, sizeof(int));

Read(value, len);

return *this;

}

 

CInStream & CInStream::operator>>(CString &value)

{

int len = 0;

Read((char *) &len, sizeof(int));

Read(value.GetBuffer(len), len);

value.ReleaseBuffer();

return *this;

}

 

CInStream & CInStream::operator>>(long &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(UINT &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(ULONG &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(UCHAR &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(float &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

CInStream & CInStream::operator>>(double &value)

{

Read((char *) &value, sizeof(int));

return *this;

}

 

 

 

 

// InStream.h: interface for the CInStream class.

// 输入流的封装 将它与一个已分配的缓冲相绑定 然后就可以将这个缓冲当成流使用

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_INSTREAM_H__D495714A_B3D7_43AE_B800_CB826FB57C11__INCLUDED_)

#define AFX_INSTREAM_H__D495714A_B3D7_43AE_B800_CB826FB57C11__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define MP_CUR 0

#define MP_BEG 1

#define MP_END 2

 

class CInStream

{

public:

CInStream();

virtual ~CInStream();

virtual BOOL Create(const void *pData);

virtual int Read(void *savePtr, int readSize);

const void *GetHead();

const void *GetCurPtr();

BOOL MoveCurPtr(int offset, int mode = MP_CUR);

int GetSize();

int GetMaxSize();

 

CInStream &operator >>(int &value);

CInStream &operator >>(char &value);

CInStream &operator >>(char *value);

CInStream &operator >>(CString &value);

CInStream &operator >>(long &value);

CInStream &operator >>(UINT &value);

CInStream &operator >>(ULONG &value);

CInStream &operator >>(UCHAR &value);

CInStream &operator >>(float &value);

CInStream &operator >>(double &value);

 

public:

LPCVOID m_pInBuf;

LPCVOID m_pCurInPtr;

LPCVOID m_pMaxInPtr;

int m_nMaxSize;

};

 

#endif // !defined(AFX_INSTREAM_H__D495714A_B3D7_43AE_B800_CB826FB57C11__INCLUDED_)

 

 

 

 

// IOCP.cpp: implementation of the CIOCP class.

//

//////////////////////////////////////////////////////////////////////

 

#include "StdAfx.h"

#include "IOCP.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

int CIOCP::m_nIODateCount = 0;

 

//////////////////////////////////////////////////////////////////////////

// 构造函数

CIOCP::CIOCP()

{

m_hIocp = NULL;

m_nCurThreadCount = 0;

m_nMaxThreadCount = 0;

}

//////////////////////////////////////////////////////////////////////////

 

 

 

//////////////////////////////////////////////////////////////////////////

// 析构函数

CIOCP::~CIOCP()

{

Stop();

TRACE("B CIOCP::destory m_nIODataCount = %d\n ", m_nIODateCount);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 初始化

// 返回:成功返回TRUE

BOOL CIOCP::Create()

{

m_hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

if (m_hIocp == NULL)

{

return FALSE;

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 线程函数

DWORD WINAPI CIOCP::IocpThd(LPVOID para)

{

CIOCP *pIOCP = (CIOCP *) para;

pIOCP->m_nCurThreadCount++;

while (1)

{

DWORD bytes;

DWORD key;

LPOVERLAPPED lpOverLapped = NULL;

BOOL ret = GetQueuedCompletionStatus(pIOCP->m_hIocp,

&bytes,

&key,

&lpOverLapped,

2000);

 

IO_DATA *pIOData = (IO_DATA *) lpOverLapped;

 

if (ret == TRUE)

{

if (key == IOCP_MSG_EXIT_THREAD && lpOverLapped == NULL)

{

TRACE("B Iocp thread exit!!!\n");

pIOCP->m_nCurThreadCount--;

return 0;

}

 

pIOData->m_numberOfBytes = bytes;

pIOData->m_key = key;

 

//TRACE("Iocp status ok....\n");

 

/*

TRACE("bytes = %d, key = %d, pData = %d, m_type = %d\n",

  pIOData->m_numberOfBytes,

  pIOData->m_key,

  pIOData,

  pIOData->m_type);

  */

 

if (pIOData->m_type == IT_RECV)

{

pIOCP->OnRecv(pIOData);

}

 

if (pIOData->m_type == IT_SEND)

{

pIOCP->OnSend(pIOData);

}

 

if (pIOData->m_type == IT_RECVFROM)

{

pIOCP->OnRecvFrom(pIOData);

}

 

if (pIOData->m_type == IT_SENDTO)

{

pIOCP->OnSendTo(pIOData);

}

 

//处理完后删除变量

DelIOData(pIOData);

}

else

{

int err = GetLastError();

pIOCP->OnError(err, pIOData);

}

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// SOCKETIOCP绑定

// 参数:sock 要绑定的SOCKET

// 返回:成功返回TRUE

BOOL CIOCP::Bind(SOCKET sock)

{

HANDLE handle = CreateIoCompletionPort((HANDLE) sock,

 m_hIocp,

 IOCP_MSG_SOCK_KEY,

 0);

if (handle == NULL)

{

return FALSE;

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 开启线程

// 参数:nMaxThreadCount 最大线程数,如果为0(默认)则自动计算为CPU数目

// 返回:没用到

BOOL CIOCP::Start(int nMaxThreadCount /*= 0*/)

{

if (nMaxThreadCount == 0)

{

SYSTEM_INFO sysInfo;

GetSystemInfo(&sysInfo);

m_nMaxThreadCount = sysInfo.dwNumberOfProcessors;

}

else

{

m_nMaxThreadCount = nMaxThreadCount;

}

 

for (unsigned int i = m_nCurThreadCount; i < m_nMaxThreadCount; i++)

{

CreateThread(NULL, 0, IocpThd, (LPVOID)this, 0, 0);

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 关闭线程

// 返回:关闭成功返回TRUE

BOOL CIOCP::Stop()

{

int max = m_nCurThreadCount;

for (int i = 0; i < max; i++)

{

PostMessage(IOCP_MSG_EXIT_THREAD);

}

if (m_nCurThreadCount > 0)

{

return FALSE;

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送消息到ICOP

// 参数:key 消息类型, bytes 数据大小 默认为0 不发送数据, lpOverlapped重叠结构体指针 默认为NULL 不发送数据

void CIOCP::PostMessage(ULONG key,

DWORD bytes /*= 0*/,

LPOVERLAPPED lpOverlapped /*= NULL*/)

{

PostQueuedCompletionStatus(m_hIocp, bytes, key, lpOverlapped);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// Recv事件的处理

// 参数:pIOData 数据

// 备注:为了保证Rec事件的循环链 请在派生类的重写函数中调用些函数

void CIOCP::OnRecv(IO_DATA *pIOData)

{

StartRecv(pIOData->m_sock);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// Send事件的处理

void CIOCP::OnSend(IO_DATA *pIOData)

{

//TODO:

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// RecvFrom的处理

// 备注:为了保证RecvFrom事件的循环链 请在派生类的重写函数中调用些函数

void CIOCP::OnRecvFrom(IO_DATA *pIOData)

{

StartRecvFrom(pIOData->m_sock);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// SendTo的处理

void CIOCP::OnSendTo(IO_DATA *pIOData)

{

//TODO: NOTHING

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 新分配一个IO_DATA数据

// 返回:新创建的IO_DATA指针

IO_DATA * CIOCP::NewIOData()

{

IO_DATA *pIOData = new IO_DATA;

ZeroMemory(pIOData, sizeof(IO_DATA));

pIOData->m_wsaBuf.buf = pIOData->m_data;

pIOData->m_wsaBuf.len = sizeof(pIOData->m_data);

pIOData->m_fromLen = sizeof(pIOData->m_from);

pIOData->m_key = IOCP_MSG_SOCK_KEY;

pIOData->m_flag = 0;

 

m_nIODateCount++;

 

return pIOData;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 删除由NewIOData()分配的内存

// 备注:对内存泄露有计数

VOID CIOCP::DelIOData(IO_DATA *pIOData)

{

m_nIODateCount--;

delete pIOData;

}

 

void CIOCP::OnError(int err, IO_DATA *pIOData)

{

if (err == WAIT_TIMEOUT)

{

TRACE("B OnError:IOCP thread: Timeout!!...\n");

}

else if (err == WSAECONNRESET || err == 1234)

{

TRACE("B OnError:WSAECONNRESET\n");

DealClientCloseError(pIOData->m_sock, pIOData->m_type);

}

else

{

TRACE("B IOCP Thread: err_code = %d\n", err);

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 开始RecvFrom的循环

void CIOCP::StartRecvFrom(SOCKET sock)

{

IO_DATA *pIODataNew = NewIOData();

pIODataNew->m_sock = sock;

pIODataNew->m_type = IT_RECVFROM;

 

int recvRet = WSARecvFrom(pIODataNew->m_sock,

  &pIODataNew->m_wsaBuf,

  1,

  &pIODataNew->m_numberOfBytes,

  &pIODataNew->m_flag,

  &pIODataNew->m_from,

  &pIODataNew->m_fromLen,

  (LPWSAOVERLAPPED) pIODataNew,

  NULL);

 

if (recvRet == SOCKET_ERROR)

{

int err = GetLastError();

if (err == WSA_IO_PENDING)

{

TRACE("B CIOCP::StartRecvFrom:IO pending......\n");

}

//如果对方关闭

else if (err == WSAECONNRESET)

{

TRACE("B CIOCP::StartRecvFrom:Client is close!\n");

DealClientCloseError(sock, IT_RECVFROM);

}

else

{

TRACE("B CIOCP::StartRecvFrom::WSARecvFrom err = %d\n", err);

}

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 开始Recv的循环

void CIOCP::StartRecv(SOCKET sock)

{

IO_DATA *pIODataNew = NewIOData();

pIODataNew->m_sock = sock;

pIODataNew->m_type = IT_RECV;

int recvRet = WSARecv(pIODataNew->m_sock,

  &pIODataNew->m_wsaBuf,

  1,

  &pIODataNew->m_numberOfBytes,

  &pIODataNew->m_flag,

  (LPOVERLAPPED) pIODataNew,

  NULL);

 

if (recvRet == SOCKET_ERROR)

{

int err = GetLastError();

if (err == WSA_IO_PENDING)

{

TRACE("B CIOCP::StartRecv:IO pending......\n");

}

else

{

TRACE("B CIOCP::StartRecv::WSARecv err = %d\n", err);

}

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 处理客户端异常中断

// 参数:sock 出错的SOCKET

void CIOCP::DealClientCloseError(SOCKET sock, int type)

{

Bind(sock);

if (type == IT_RECV)

{

StartRecv(sock);

}

else if (type == IT_RECVFROM)

{

StartRecvFrom(sock);

}

}

//////////////////////////////////////////////////////////////////////////

 

 

 

 

// IOCP.h: interface for the CIOCP class.

// 对完成端口的封装

/* 类说明

2009719日版本

   CIOCP 是对完成端口的封装,能方便的对完成端口进行处理

   对完成端口的进行的封装,不必再自行写线程函数了.线程里会回调类里的OnXXX虚数,只要自行重写处理函数就可以了.

   对完成端口所用的数据进行了定义 可以方便的获取所需要的数据了

 

  注意的是 IO_DATA的数据都需要new出来,线程会自动释放.注意使用方法

   

  */

//////////////////////////////////////////////////////////////////////

 

#ifndef __IOCP_H_

#define __IOCP_H_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <winsock2.h>

 

//////////////////////////////////////////////////////////////////////////

//IOCP的消息(KEY)类型

#define IOCP_MSG_EXIT_THREAD 100 //退出线程消息

#define IOCP_MSG_SOCK_KEY 10 //SOCK处理消息

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

//IOCP处理的SOCK事件

enum IO_TYPE

{

IT_SEND = 1,

IT_RECV = 2,

IT_SENDTO = 3,

IT_RECVFROM = 4

};

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

//数据的封装

typedef struct _IO_DATA

{

//基础重叠结构体

OVERLAPPED m_OverLapped;

 

//重叠IO操作函数用到的变量

WSABUF m_wsaBuf;

char m_data[10240];

SOCKET m_sock;

sockaddr m_from;

int m_fromLen;

ULONG m_flag;

 

//标识事件类型

IO_TYPE m_type;

 

//线程里用到的key

int m_key;

ULONG m_numberOfBytes;

}IO_DATA;

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// CIOCP类定义

class CIOCP

{

public:

CIOCP();

virtual ~CIOCP();

virtual BOOL Create(); //创建并初始化

virtual BOOL Bind(SOCKET sock); //socket与该完成端口绑定

virtual BOOL Start(int nMaxThreadCount = 0); //开启线程

virtual BOOL Stop(); //停止线程

void PostMessage(ULONG key,

DWORD bytes = 0,

LPOVERLAPPED lpOverlapped = NULL); //向完成端口发送消息

 

virtual void OnRecv(IO_DATA *pIOData); //对各种事件处理的回调函数

virtual void OnSend(IO_DATA *pIOData);

virtual void OnRecvFrom(IO_DATA *pIOData);

virtual void OnSendTo(IO_DATA *pIOData);

virtual void OnError(int err, IO_DATA *pIOData);

 

virtual void StartRecvFrom(SOCKET sock); //开始RecvFrom的循环

virtual void StartRecv(SOCKET sock); //开始Recv循环

 

virtual void DealClientCloseError(SOCKET sock, int type); //处理客户端异常中断的错误

 

private:

HANDLE m_hIocp; //完成端口句柄

UINT m_nCurThreadCount; //当前在运行的线程计数

UINT m_nMaxThreadCount; //设定的最大线程数

 

// 静态成员

public:

static IO_DATA *NewIOData(); //IO_DATA的新建, 会自动完成一些变量的赋值 及内存泄露的统计

static VOID DelIOData(IO_DATA *pIOData); //IO_DATA的释放, 会对内在泄露进行统计

private :

static int m_nIODateCount; //IO_DATA的统计计数

static DWORD WINAPI IocpThd(LPVOID para); //线程封装

};

//////////////////////////////////////////////////////////////////////////

 

#endif // __IOCP_H_

 

 

 

 

// MySocket.cpp: implementation of the CMySocket class.

//

//////////////////////////////////////////////////////////////////////

 

#include "StdAfx.h"

#include "MySocket.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

//////////////////////////////////////////////////////////////////////////

// 构造函数

CMySocket::CMySocket()

{

m_sock = NULL;

m_nPort = 0;

m_nSocketType = 0;

m_szAddr.Empty();

ZeroMemory(&m_sockaddr, sizeof(sockaddr_in));

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 析构函数

CMySocket::~CMySocket()

{

ShutDown();

Close();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 初始化SOCKET环境

BOOL CMySocket::StartUp()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

 

wVersionRequested = MAKEWORD(2, 2);

 

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0)

{

/* Tell the user that we could not find a usable */

/* WinSock DLL.  */

return FALSE;

}

 

/* Confirm that the WinSock DLL supports 2.2.*/

/* Note that if the DLL supports versions greater    */

/* than 2.2 in addition to 2.2, it will still return */

/* 2.2 in wVersion since that is the version we  */

/* requested.     */

 

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

/* Tell the user that we could not find a usable */

/* WinSock DLL.  */

WSACleanup();

return FALSE;

}

 

/* The WinSock DLL is acceptable. Proceed. */

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// SOCKET环境卸载

void CMySocket::CleanUp()

{

WSACleanup();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 创建地址

sockaddr_in CMySocket::MakeSockAddr(UINT nPort, LPCTSTR lpszAddress /*= NULL*/)

{

sockaddr_in addr;

ZeroMemory(&addr, sizeof(sockaddr_in));

addr.sin_family = AF_INET;

addr.sin_port = htons(nPort);

if (lpszAddress == NULL)

{

addr.sin_addr.S_un.S_addr = INADDR_ANY;

}

else

{

addr.sin_addr.S_un.S_addr = inet_addr(lpszAddress);

}

return addr;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 关闭

void CMySocket::Close()

{

closesocket(m_sock);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 关闭读写通道

BOOL CMySocket::ShutDown(int nHow /*= SD_BOTH */)

{

if (shutdown(m_sock, nHow) == 0)

{

return TRUE;

}

else

{

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 创建

BOOL CMySocket::Create(UINT nSocketPort /*= 0*/,

   int nSocketType /*= SOCK_STREAM*/,

   LPCTSTR lpszSocketAddress /*= NULL */)

{

m_nPort = nSocketPort;

m_nSocketType = nSocketType;

m_szAddr = lpszSocketAddress;

 

m_sockaddr.sin_family = AF_INET;

m_sockaddr.sin_port = htons(m_nPort);

if (m_szAddr.IsEmpty())

{

m_sockaddr.sin_addr.S_un.S_addr = INADDR_ANY;

}

else

{

m_sockaddr.sin_addr.S_un.S_addr = inet_addr(m_szAddr.GetBuffer(0));

}

 

m_sock = socket(AF_INET, m_nSocketType, 0);

 

if (m_sock == NULL)

{

return FALSE;

}

else

{

return TRUE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 发送

int CMySocket::SendTo(const void *lpBuf,

  int nBufLen,

  UINT nHostPort,

  LPCTSTR lpszHostAddress /*= NULL*/,

  int nFlags /*= 0*/)

{

sockaddr_in addr = MakeSockAddr(nHostPort, lpszHostAddress);

return SendTo(lpBuf,

  nBufLen,

  (sockaddr *) &addr,

  sizeof(sockaddr_in),

  nFlags);

}

 

int CMySocket::SendTo(const void *lpBuf,

  int nBufLen,

  const SOCKADDR *lpSockAddr,

  int nSockAddrLen,

  int nFlags /*= 0*/)

{

return sendto(m_sock,

  (char *) lpBuf,

  nBufLen,

  nFlags,

  lpSockAddr,

  nSockAddrLen);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 异步选择

BOOL CMySocket::AsyncSelect(HWND hWnd, UINT wMsg, long lEvent)

{

int ret = WSAAsyncSelect(m_sock, hWnd, wMsg, lEvent);

if (ret == 0)

{

return TRUE;

}

else

{

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

 

 

// MySocket.h: interface for the CMySocket class.

// SOCKET的封装

/*

SOCKET的封装,方便了使用,但功能有限 依项目需要而完善

详细函数说明待添加

*/

//////////////////////////////////////////////////////////////////////

 

#ifndef __MYSOCKET_H_

#define __MYSOCKET_H_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <WINSOCK2.H>

 

#pragma comment(lib,"ws2_32.lib")

 

//////////////////////////////////////////////////////////////////////////

// CMySocket类定义

class CMySocket

{

public:

CMySocket();

virtual ~CMySocket();

static BOOL StartUp(); //静态, SOCKET环境的初始化

static void CleanUp(); // SOCKET环境卸载

static sockaddr_in MakeSockAddr(UINT nPort, LPCTSTR lpszAddress = NULL); //静态, 方便生成一个地址结构体

 

BOOL Create(UINT nSocketPort = 0,

   int nSocketType = SOCK_STREAM,

   LPCTSTR lpszSocketAddress = NULL); //创建SOCKET

 

void Close(); //关闭

BOOL ShutDown(int nHow = SD_BOTH); //关闭读写通道

 

BOOL AsyncSelect(HWND hWnd, UINT wMsg, long lEvent); //异步选择模式

 

int SendTo(const void *lpBuf,

   int nBufLen,

   UINT nHostPort,

   LPCTSTR lpszHostAddress = NULL,

   int nFlags = 0); //SendTo的两种方式

int SendTo(const void *lpBuf,

   int nBufLen,

   const SOCKADDR *lpSockAddr,

   int nSockAddrLen,

   int nFlags = 0);

 

public:

SOCKET m_sock; //SOCKET标识

UINT m_nPort; //端口

int m_nSocketType; //类型

CString m_szAddr; //IP的字符串形式

sockaddr_in m_sockaddr; //地址

};

//////////////////////////////////////////////////////////////////////////

 

#endif // __MYSOCKET_H_

 

 

 

 

// MyTab.cpp : implementation file

//

 

#include "stdafx.h"

#include "..\Client\Client.h"

#include "MyTab.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// CMyTab

 

CMyTab::CMyTab()

{

m_nItemCount = 0;

m_pCurWnd = NULL;

m_ptTabs.x = 4;

m_ptTabs.y = 28;

}

 

CMyTab::~CMyTab()

{

}

 

 

BEGIN_MESSAGE_MAP(CMyTab, CTabCtrl)

//{{AFX_MSG_MAP(CMyTab)

// NOTE - the ClassWizard will add and remove mapping macros here.

ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange)

ON_NOTIFY_REFLECT(TCN_SELCHANGING, OnSelchanging)

ON_WM_CREATE()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

int CMyTab::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CTabCtrl::OnCreate(lpCreateStruct) == -1)

{

return -1;

}

GetWindowRect(&m_tabRect);

return 0;

}

 

void CMyTab::OnSelchange(NMHDR *pNMHDR, LRESULT *pResult)

{

int iNewTab = GetCurSel();

TCITEM item;

CWnd *pWnd;

item.mask = TCIF_PARAM;

//显示选择的

GetItem(iNewTab, &item);

pWnd = reinterpret_cast<CWnd*>(item.lParam);

ASSERT_VALID(pWnd);

pWnd->ShowWindow(SW_SHOW);

m_pCurWnd = pWnd;

*pResult = 0;

}

 

void CMyTab::OnSelchanging(NMHDR *pNMHDR, LRESULT *pResult)

{

int iNewTab = GetCurSel();

TCITEM item;

CWnd *pWnd;

item.mask = TCIF_PARAM;

 

//隐藏当前TAB

GetItem(iNewTab, &item);

pWnd = reinterpret_cast<CWnd*>(item.lParam);

ASSERT_VALID(pWnd);

pWnd->ShowWindow(SW_HIDE);

*pResult = 0;

}

 

void CMyTab::AddItem(CWnd *pWnd, LPTSTR name)

{

InsertItem(m_nItemCount, pWnd, name);

}

 

void CMyTab::InsertItem( int pos, CWnd *pWnd, LPTSTR name )

{

TCITEM item;

item.mask = TCIF_TEXT | TCIF_PARAM;

item.lParam = (LPARAM) pWnd;

item.pszText = name;

CTabCtrl::InsertItem(pos, &item);

 

pWnd->SetWindowPos(NULL,

   m_ptTabs.x,

   m_ptTabs.y,

   0,

   0,

   SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER);

if (m_nItemCount == 0)

{

pWnd->ShowWindow(SW_SHOW);//显示第一个子窗体

m_pCurWnd = pWnd;

}

else

{

pWnd->ShowWindow(SW_HIDE);

}

m_nItemCount++;

}

 

void CMyTab::ChangeTo(int index)

{

SetCurFocus(index);

}

 

void CMyTab::ChangeTo( CString name )

{

 

}

 

void CMyTab::DelItem( int index )

{

DeleteItem(index);

}

 

void CMyTab::DelItem( CString name )

{

for (int i=0;i<GetItemCount();i++)

{

if (GetItemText(i) == name)

{

DeleteItem(i);

}

}

}

 

CString CMyTab::GetItemText( int index )

{

CString retStr;

TCITEM tci;

GetItem(index, &tci);

retStr = tci.pszText;

return retStr;

}

 

/////////////////////////////////////////////////////////////////////////////

// CMyTab message handlers

 

 

 

 

#if !defined(AFX_MYTAB_H__A0DCFE98_D81E_47D8_A2B5_AC76F1F222AA__INCLUDED_)

#define AFX_MYTAB_H__A0DCFE98_D81E_47D8_A2B5_AC76F1F222AA__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// MyTab.h : header file

//

 

/////////////////////////////////////////////////////////////////////////////

// CMyTab window

 

class CMyTab : public CTabCtrl

{

// Construction

public:

CMyTab();

 

// Attributes

public:

int m_nItemCount; //窗体个数

CWnd *m_pCurWnd; //当前窗体

CPoint m_ptTabs; //左上角坐标

CRect m_tabRect; //Tab的矩形区域

// Operations

public:

void AddItem(CWnd *pWnd, LPTSTR name); //添加选项卡

void InsertItem(int pos, CWnd *pWnd, LPTSTR name);

void DelItem(CString name);

void DelItem(int index);

void ChangeTo(int index);

void ChangeTo(CString name);

CString GetItemText(int index);

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMyTab)

//}}AFX_VIRTUAL

 

// Implementation

public:

virtual ~CMyTab();

 

// Generated message map functions

protected:

//{{AFX_MSG(CMyTab)

// NOTE - the ClassWizard will add and remove member functions here.

afx_msg void OnSelchange(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg void OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult);

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

//}}AFX_MSG

 

DECLARE_MESSAGE_MAP()

};

 

/////////////////////////////////////////////////////////////////////////////

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_MYTAB_H__A0DCFE98_D81E_47D8_A2B5_AC76F1F222AA__INCLUDED_)

 

 

 

 

// OutStream.cpp: implementation of the COutStream class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "OutStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

COutStream::COutStream()

{

m_pOutBuf = NULL;

m_pCurOutPtr = NULL;

m_nInitSize = 0;

m_nIncreaseSize = 0;

m_nMaxSize = 0;

// m_nCurSize = 0;

m_pUsedMaxPtr = 0;

}

 

COutStream::~COutStream()

{

if (m_pOutBuf != NULL)

{

delete[] m_pOutBuf;

}

}

 

BOOL COutStream::Create(int initSize /*= DEFAULT_INIT_SIZE*/,

int increaseSize /*= DEFAULT_INCREASE_SIZE*/)

{

//参数检测

if (m_pOutBuf != NULL)

{

TRACE("B COutStream::Create: Only can create once!\n");

return FALSE;

}

if (initSize <= 0)

{

initSize = DEFAULT_INIT_SIZE;

}

if (increaseSize <= 0)

{

initSize = DEFAULT_INCREASE_SIZE;

}

m_nInitSize = initSize;

m_nIncreaseSize = increaseSize;

 

//分配空间

m_pOutBuf = new char[m_nInitSize];

if (m_pOutBuf == NULL)

{

TRACE("B COutStream::Create new char error!\n");

return FALSE;

}

ZeroMemory(m_pOutBuf, m_nInitSize);

 

//指针维护

m_pCurOutPtr = m_pOutBuf;

m_pUsedMaxPtr = m_pCurOutPtr;

 

//大小维护

m_nMaxSize = m_nInitSize;

// m_nCurSize = 0;

return TRUE;

}

 

int COutStream::Write(const void *pData, int DataSize)

{

// 如果会造成数据溢出 则不执行操作

if (m_pCurOutPtr + DataSize - m_pOutBuf > m_nMaxSize)

{

TRACE("B COutStream::Write write range out of buf!\n");

return 0;

}

memcpy(m_pCurOutPtr, pData, DataSize);

 

//游标维护

m_pCurOutPtr += DataSize;

 

//当前大小维护

// m_nCurSize += DataSize;

 

//当前最大指针范围维护

if (m_pCurOutPtr > m_pUsedMaxPtr)

{

m_pUsedMaxPtr = m_pCurOutPtr;

}

return DataSize;

}

 

char * COutStream::GetHead()

{

return m_pOutBuf;

}

 

int COutStream::GetMaxSize()

{

return m_nMaxSize;

}

 

int COutStream::GetSize()

{

return m_pUsedMaxPtr - m_pOutBuf;

}

 

COutStream & COutStream::operator<<(int &value)

{

Write((const char *) &value, sizeof(int));

return *this;

}

 

COutStream & COutStream::operator<<(char &value)

{

Write((const char *) &value, sizeof(char));

return *this;

}

 

COutStream & COutStream::operator<<(char *value)

{

int len = strlen(value) + 1;

Write((const char *) &len, sizeof(len));

Write((const char *) &value, len);

return *this;

}

 

COutStream & COutStream::operator<<(CString &value)

{

int len = value.GetLength() + 1;

Write((const char *) &len, sizeof(len));

Write((const char *) value.GetBuffer(0), len);

return *this;

}

 

COutStream & COutStream::operator<<(long &value)

{

Write((const char *) &value, sizeof(long));

return *this;

}

 

COutStream & COutStream::operator<<(UINT &value)

{

Write((const char *) &value, sizeof(UINT));

return *this;

}

 

COutStream & COutStream::operator<<(ULONG &value)

{

Write((const char *) &value, sizeof(ULONG));

return *this;

}

 

COutStream & COutStream::operator<<(UCHAR &value)

{

Write((const char *) &value, sizeof(UCHAR));

return *this;

}

 

COutStream & COutStream::operator<<(float &value)

{

Write((const char *) &value, sizeof(float));

return *this;

}

 

COutStream & COutStream::operator<<(double &value)

{

Write((const char *) &value, sizeof(double));

return *this;

}

 

BOOL COutStream::MoveCurPtr(int offset, int mode /*= MD_CUR*/)

{

// 注意:此函数未对指针的访问范围进行严格检测 使用时请注意

if (mode == MP_CUR)

{

m_pCurOutPtr += offset;

}

else if (mode == MP_BEG)

{

if (offset < 0)

{

return FALSE;

}

m_pCurOutPtr = m_pOutBuf + offset;

}

else if (mode == MP_END)

{

if (m_nMaxSize == -1)

{

TRACE("B COutStream::MoveCurPtr MP_END mode not support m_nMaxSize = -1\n");

return FALSE;

}

if (offset > 0)

{

return FALSE;

}

  m_pCurOutPtr = m_pOutBuf + offset;

}

 

// 最大使用指针维护

if (m_pCurOutPtr > m_pUsedMaxPtr)

{

m_pUsedMaxPtr = m_pCurOutPtr;

}

 

return TRUE;

}

 

char * COutStream::GetCurPtr()

{

return m_pCurOutPtr;

}

 

void * COutStream::CopyTo( void *buf, int size /*= 0*/ )

{

if (buf == NULL)

{

return NULL;

}

if (size <= 0)

{

size = m_pUsedMaxPtr - m_pOutBuf;

}

memcpy(buf, m_pOutBuf, size);

return buf;

}

 

 

 

 

// OutStream.h: interface for the COutStream class.

// 输入字节流的封装 尚未实现自动大小 所以 相关参数无效

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_OUTSTREAM_H__072F3A97_E186_44F1_A3BC_934AA6C44B2D__INCLUDED_)

#define AFX_OUTSTREAM_H__072F3A97_E186_44F1_A3BC_934AA6C44B2D__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define DEFAULT_INIT_SIZE 1024

#define DEFAULT_INCREASE_SIZE 512

 

#define MP_CUR 0

#define MP_BEG 1

#define MP_END 2

class COutStream

{

public:

COutStream();

virtual ~COutStream();

virtual BOOL Create(int initSize = DEFAULT_INIT_SIZE,

   int increaseSize = DEFAULT_INCREASE_SIZE);

virtual int Write(const void *pData, int DataSize);

char *GetHead();

int GetMaxSize();

int GetSize();

 

char *GetCurPtr();

BOOL MoveCurPtr(int offset, int mode = MP_CUR);

 

void *CopyTo(void *buf, int size = 0);

 

COutStream &operator <<(int &value);

COutStream &operator <<(char &value);

COutStream &operator <<(char *value);

COutStream &operator <<(CString &value);

COutStream &operator <<(long &value);

COutStream &operator <<(UINT &value);

COutStream &operator <<(ULONG &value);

COutStream &operator <<(UCHAR &value);

COutStream &operator <<(float &value);

COutStream &operator <<(double &value);

 

private:

// 数据指针与当前指针

char *m_pOutBuf;

char *m_pCurOutPtr;

// 动态大小的判断

int m_nInitSize;

int m_nIncreaseSize;

// 当前可用的最大空间

int m_nMaxSize;

// 当前最大的游标(当前指针)

char *m_pUsedMaxPtr;

};

 

#endif // !defined(AFX_OUTSTREAM_H__072F3A97_E186_44F1_A3BC_934AA6C44B2D__INCLUDED_)

 

 

 

 

// stdafx.h : include file for standard system include files,

//  or project specific include files that are used frequently, but

//      are changed infrequently

//

 

#ifndef __BASIC_STDAFX_H_

#define __BASIC_STDAFX_H_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

 

#include <afxwin.h>         // MFC core and standard components

#include <afxext.h>         // MFC extensions

#include <afxdisp.h>        // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h> // MFC support for Windows Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

 

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // __BASIC_STDAFX_H_

 

 

 

 

 

/*/////////////////////////////////////////////////////////////////////////

说明:UCode 文件,一些简单常用功能函数合集。

版本:1.0

创建:[4/5/2009 Dufeng]

修改:

*///////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 预处理

 

#include "StdAfx.h"

#include "UCode.h"

#include <windows.h>

#include <stdio.h>

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 宏定义

//#define BUFFER_SIZE 256

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:OnlyRunOne,只允许运行一个实例。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:TURE为可运行,FALSE为已经在运行

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

BOOL OnlyRunOne(WCHAR *_mutexName)

{

CreateMutexW(NULL, FALSE, _mutexName);

 

if (GetLastError() == ERROR_ALREADY_EXISTS)

{

return FALSE;

}

else

{

return TRUE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,获取上次的错误信息,会自动格式化信息内容。

// 版本:1.0

// 创建:[4/5/2009 Dufeng]

// 返回:

// 修改:

// 备注:只能使用WCHAR,不然总是失败

//////////////////////////////////////////////////////////////////////////

 

VOID GetLastErrorMsg(TCHAR *szBuf)

{

LPVOID lpMsgBuf;

DWORD dw = GetLastError();

 

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

  NULL,

  dw,

  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

  (LPTSTR) & lpMsgBuf,

  0,

  NULL);

 

sprintf(szBuf, "错误 %d: %s", dw, lpMsgBuf);

 

LocalFree(lpMsgBuf);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:GetLastErrorMsg,检测键盘状态。

// 版本:1.0

// 创建:[4/6/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

 

BOOL GetOneKeyState(BYTE _key)

{

BYTE keyState[256];

 

GetKeyboardState((LPBYTE) & keyState);

return (keyState[_key] & 1);

}

 

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的的路径 不包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppPath(char *szFilePath)

{

char szTempFilePath[BUFFER_SIZE] ={0};

GetModuleFileName(NULL, szTempFilePath, BUFFER_SIZE - 1);

size_t nTemp = strlen(szTempFilePath) -

  strlen(strrchr(szTempFilePath, '\\'));

if (nTemp != -1)

{

szTempFilePath[nTemp + 1] = 0;

}

strcpy(szFilePath, szTempFilePath);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 说明:得到程序的全路径 包括文件名

// 版本:1.0

// 创建:[22/7/2009 Dufeng]

// 返回:

// 修改:

// 备注:

//////////////////////////////////////////////////////////////////////////

void GetAppFileFullPathName(char *szFileName)

{

GetModuleFileName(NULL, szFileName, BUFFER_SIZE - 1);

}

//////////////////////////////////////////////////////////////////////////

 

 

 

 

/*/////////////////////////////////////////////////////////////////////////

说明:UCode 文件,一些简单常用功能函数合集。

版本:1.0

创建:[4/5/2009 Dufeng]

修改:

*///////////////////////////////////////////////////////////////////////////

 

#ifndef __U_CODE_H_

#define __U_CODE_H_

 

//////////////////////////////////////////////////////////////////////////

// 预处理

#include <windows.h>

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 宏定义

#define BUFFER_SIZE 256

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

/*

0x8000二进制值是1000000000000000,两者进行与运算

即如果GetAsyncKeyState(vk_code)最高位是1,则取值1,

即此时KEYDOWN   后者正好相反

函数GetAsyncKeyState确定在调用它时某个按键处于弹起还是按下的,以及此按键是否在上一次调用GetAsyncKeyState之后(“又”)按下过(重复也算按下)。

这句话的完整意思是:预定义了一个KEYDOWN参数为vk_code 他的定义的含义是判断一个键是否被按下(GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0如果按下了就是1,没有按下就是0

然后其它地方用的时候直接用KEYDOWN(vk_code)判断这个键是否按下,相反弹起来是1按下是0

*/

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 只允许运行一个实例。

BOOL OnlyRunOne(WCHAR *_mutexName);

 

// 获取上次的错误信息,会自动格式化信息内容。

VOID GetLastErrorMsg(CHAR *szBuf);

 

// 获取某个键的状态

BOOL GetOneKeyState(BYTE _key);

 

// 获取程序的路径

void GetAppPath(char *szFilePath);

 

// 获取程序文件名

void GetAppFileFullPathName(char *szFileName);

//////////////////////////////////////////////////////////////////////////

 

#endif //__U_CODE_H_

 

 

 

 

       Common项目共用的类代码

#ifndef __CLIENT_DEFINE_H_

#define __CLIENT_DEFINE_H_

 

//窗口颜色

#define ROOM_BACK_COLOR RGB(82,113,156)

 

//窗口大小

#define MIN_WIDTH_OF_SERVER_TREE 300

#define MIN_WIDTH_OF_HALL_DLG 300

 

//窗口消息

#define WM_NET_MSG WM_USER+1

 

#define WM_SEAT_DOWN WM_USER+100

#define WM_LOOK_ON WM_USER+101

 

//TimerID

#define WAIT_MSG_FROM_SERVER_TIMER_ID 10

 

 

//////////////////////////////////////////////////////////////////////////

// 定义发送的消息类型

// #define GM_NULL 0

// #define GM_GAME_HWND 1

// #define GM_SEND_GAME_INFO 2

// #define GM_GET_GAME_INFO 3

// #define GM_EXIT 4

 

//////////////////////////////////////////////////////////////////////////

#endif //__CLIENT_DEFINE_H_

 

 

#ifndef __CLIENT_DEFINE_H_

#define __CLIENT_DEFINE_H_

 

//窗口颜色

#define ROOM_BACK_COLOR RGB(82,113,156)

 

//窗口大小

#define MIN_WIDTH_OF_SERVER_TREE 300

#define MIN_WIDTH_OF_HALL_DLG 300

 

//窗口消息

#define WM_NET_MSG WM_USER+1

 

#define WM_SEAT_DOWN WM_USER+100

#define WM_LOOK_ON WM_USER+101

 

//TimerID

#define WAIT_MSG_FROM_SERVER_TIMER_ID 10

 

 

//////////////////////////////////////////////////////////////////////////

// 定义发送的消息类型

// #define GM_NULL 0

// #define GM_GAME_HWND 1

// #define GM_SEND_GAME_INFO 2

// #define GM_GET_GAME_INFO 3

// #define GM_EXIT 4

 

//////////////////////////////////////////////////////////////////////////

#endif //__CLIENT_DEFINE_H_

 

 

 

// Ccpp: implementation of the CLLK class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "CLLK.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLK::CLLK()

{

m_nBoxXCount = BOX_X_COUNT;

m_nBoxYCount = BOX_Y_COUNT;

 

Init();

}

 

CLLK::~CLLK()

{

}

 

int CLLK::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(CLLK) + sizeof(int));

int dataSize = sizeof(CLLK);

cos << dataSize;

cos.Write((char *)this, dataSize);

cos.CopyTo(pData);

 

return cos.GetSize();

}

 

int CLLK::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

if (dataSize != sizeof(CLLK))

{

TRACE("C CLLK::UnPack dataSize[%d] != sizeof(CLLK)[%d]\n", dataSize, sizeof(CLLK));

}

cis.Read((char *)this, sizeof(CLLK));

return cis.GetSize();

}

 

void CLLK::Init()

{

// 初始数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

// 初始化选择

m_nSelBox = 0;

m_ptSelBox[0] = CPoint(0, 0);

m_ptSelBox[1] = CPoint(0, 0);

 

// 初始化连线

m_nLinkLine = 0;

ZeroMemory(m_ptLinkLine, sizeof(m_ptLinkLine));

 

// 初始化将要删除的

m_bHasWillBeNullBox = FALSE;

m_typeWillBeNullBox[0] = 0;

m_typeWillBeNullBox[1] = 0;

m_ptWillBeNullBox[0] = CPoint(-1, -1);

m_ptWillBeNullBox[1] = CPoint(-1, -1);

 

// 初始化连击数

m_nCurLianji = 0;

m_nMaxLianji = 0;

m_dwLastLianjiTime = 0;

 

m_nLeaveBoxCount = 0;

}

 

//////////////////////////////////////////////////////////////////////////

// //判断两坐标是否在同一线上 并且中间无阻碍

BOOL CLLK::IsPairInlineValid(CPoint pt1, CPoint pt2)

{

//同一点判断

if (pt1 == pt2)

{

return FALSE;

}

 

//同一行类型

typedef enum _INLINE_TYPE

{

IT_NULL = 0, //不同行

IT_X = 1, //X同行

IT_Y = 2 //Y同行

} INLINE_TYPE;

 

INLINE_TYPE it;

 

if (pt1.x == pt2.x)

{

it = IT_X;

//计算出两者之大小

int x = pt1.x;

int minY, maxY;

if (pt1.y > pt2.y)

{

minY = pt2.y;

maxY = pt1.y;

}

else

{

minY = pt1.y;

maxY = pt2.y;

}

//紧挨着

if (maxY - minY == 1)

{

return TRUE;

}

//其它情况

for (int i = minY + 1; i < maxY; i++)

{

if (m_nArrType[x][i] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else if (pt1.y == pt2.y)

{

it = IT_Y;

//计算出两者之大小

int y = pt1.y;

int minX, maxX;

if (pt1.x > pt2.x)

{

minX = pt2.x;

maxX = pt1.x;

}

else

{

minX = pt1.x;

maxX = pt2.x;

}

//紧挨着

if (maxX - minX == 1)

{

return TRUE;

}

//其它情况

for (int i = minX + 1; i < maxX; i++)

{

if (m_nArrType[i][y] != BT_NULL)

{

return FALSE;

}

}

return TRUE;

}

else

{

it = IT_NULL;

return FALSE;

}

return FALSE;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 判断两点是否可消除 完成后集成在LLK类中

BOOL CLLK::IsPairCanLink(CPoint pt1,

 CPoint pt2,

 int *pnResultPtCount /*= NULL*/,

 CPoint *pPtResult /*= NULL*/)

{

// 结果保存

BOOL bRet = FALSE;

int count = 0;

CPoint point[4];

 

// 重复点情况

if (pt1 == pt2)

{

return FALSE;

}

 

// 图标是否相同

if (m_nArrType[pt1.x][pt1.y] != m_nArrType[pt2.x][pt2.y])

{

return FALSE;

}

 

// 判断流程

do

{

// 1.同一线情况

if (IsPairInlineValid(pt1, pt2))

{

count = 2;

point[0] = pt1;

point[1] = pt2;

bRet = TRUE;

break;

}

 

// 2.一拐点情况

{

CPoint t1, t2;

 

// 两点组成的矩形另外两个顶点

t1.x = pt1.x;

t1.y = pt2.y;

 

t2.x = pt2.x;

t2.y = pt1.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t1) &&

IsPairInlineValid(t1,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t1;

point[2] = pt2;

bRet = TRUE;

break;

}

 

if (m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1, t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 3;

point[0] = pt1;

point[1] = t2;

point[2] = pt2;

bRet = TRUE;

break;

}

}

 

// 3.两拐点情况

// 先横向检测

{

//另外的两个拐点

CPoint t1, t2;

 

//X向左检测

for (int x = pt1.x - 1; x >= 0; x--)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

//X向右检测 可以使路线变短

for (x = pt1.x + 1; x < BOX_X_COUNT; x++)

{

// 1点在同线上的点

t1.y = pt1.y;

t1.x = x;

 

// 2点在同线上的点

t2.x = x;

t2.y = pt2.y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向上检测

for (int y = pt1.y - 1; y >= 0; y--)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

if (bRet)

{

break;

}

 

//Y向下检测

for (y = pt1.y + 1; y < BOX_Y_COUNT; y++)

{

// 1点在同线上的点

t1.x = pt1.x;

t1.y = y;

 

// 2点在同线上的点

t2.x = pt2.x;

t2.y = y;

 

if (m_nArrType[t1.x][t1.y] ==

BT_NULL &&

m_nArrType[t2.x][t2.y] ==

BT_NULL &&

IsPairInlineValid(pt1,

  t1) &&

IsPairInlineValid(t1,

  t2) &&

IsPairInlineValid(t2,

  pt2))

{

count = 4;

point[0] = pt1;

point[1] = t1;

point[2] = t2;

point[3] = pt2;

bRet = TRUE;

break;

}

}

}

break;

}

while (1);

 

if (pnResultPtCount != NULL)

{

*pnResultPtCount = count;

if (pPtResult != NULL)

{

for (int i = 0; i < count; i++)

{

pPtResult[i] = point[i];

}

}

}

return bRet;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 执行消除响应

BOOL CLLK::DoXiaoChu()

{

if (m_nSelBox != 2)

{

return FALSE;

}

 

if (m_ptSelBox[0] == m_ptSelBox[1])

{

m_nSelBox = 0;

return FALSE;

}

if (IsPairCanLink(m_ptSelBox[0], m_ptSelBox[1], &m_nLinkLine, m_ptLinkLine))

{

// 将要删除的方块情况维护

m_bHasWillBeNullBox = TRUE;

m_ptWillBeNullBox[0] = m_ptSelBox[0];

m_ptWillBeNullBox[1] = m_ptSelBox[1];

 

m_typeWillBeNullBox[0] = m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y];

m_typeWillBeNullBox[1] = m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y];

 

// 游戏方块状态维护

m_nArrType[m_ptSelBox[0].x][m_ptSelBox[0].y] = 0;

m_nArrType[m_ptSelBox[1].x][m_ptSelBox[1].y] = 0;

 

// 连击情况维护

if (m_dwLastLianjiTime == 0)

{

m_dwLastLianjiTime = GetTickCount();

}

DWORD nowTime = GetTickCount();

if (nowTime - m_dwLastLianjiTime <= GAME_LIANJI_TIMEOUT)

{

m_nCurLianji++;

m_dwLastLianjiTime = nowTime;

}

else

{

m_nCurLianji = 1;

m_dwLastLianjiTime = nowTime;

}

if (m_nMaxLianji < m_nCurLianji)

{

m_nMaxLianji = m_nCurLianji;

}

 

 

// 选择情况维护

m_nSelBox = 0;

m_nLeaveBoxCount -= 2;

 

return TRUE;

//AAAASetTimer(GAME_DRAW_LINK_LINE_TIMER_ID, GAME_DRAW_LINK_LINE_TIME, NULL);

}

else

{

m_ptSelBox[0] = m_ptSelBox[1];

m_nSelBox = 1;

return FALSE;

}

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

void CLLK::ResetBoxState()

{

int arrTempState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

CPoint arrPointState[BOX_X_COUNT *BOX_Y_COUNT] ={0};

int nNotNullCount = 0;

 

//将状态和坐标放到一维数组里

for (int x = 0; x < BOX_X_COUNT; x++)

{

for (int y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

arrTempState[nNotNullCount] = m_nArrType[x][y];

arrPointState[nNotNullCount].x = x;

arrPointState[nNotNullCount].y = y;

nNotNullCount++;

}

}

}

 

//为了验证 将状态清空

ZeroMemory(m_nArrType, sizeof(m_nArrType));

 

//随机

srand(GetTickCount());

int index = 0;

int max = nNotNullCount;

for (int i = 0; i < nNotNullCount; i++)

{

index = rand() % max;

m_nArrType[arrPointState[i].x][arrPointState[i].y] = arrTempState[index];

arrTempState[index] = arrTempState[max - 1] ;

max--;

}

 

if (!IsCanXiaoChu())

{

ResetBoxState();

}

//AAAA Invalidate(FALSE);

}

 

BOOL CLLK::IsCanXiaoChu()

{

CPoint *pPt = new CPoint[m_nLeaveBoxCount];

BOOL bRet = FALSE;

int x, y;

int i = 0;

for (x = 0; x < BOX_X_COUNT; x++)

{

for (y = 0; y < BOX_Y_COUNT; y++)

{

if (m_nArrType[x][y] != BT_NULL)

{

pPt[i].x = x;

pPt[i].y = y;

i++;

}

}

}

 

for (i = 0; i < m_nLeaveBoxCount; i++)

{

for (int j = i + 1; j < m_nLeaveBoxCount; j++)

{

if (IsPairCanLink(pPt[i], pPt[j]))

{

bRet = TRUE;

break;

}

}

if (bRet == TRUE)

{

break;

}

}

 

delete[] pPt;

return bRet;

}

 

VOID CLLK::InitGameData(int mode /*= 0*/)

{

// 初始游戏数据

ZeroMemory(&m_nArrType, sizeof(m_nArrType));

int x, y;

int n = 0;

for (x = 1; x < BOX_X_COUNT - 1; x++)

{

for (y = 1; y < BOX_Y_COUNT - 1; y++)

{

m_nArrType[x][y] = n % BOX_TYPE_SIZE + 1;

n++;

}

}

 

m_nLeaveBoxCount = (BOX_X_COUNT - 2) * (BOX_Y_COUNT - 2);

 

ResetBoxState();

}

 

//////////////////////////////////////////////////////////////////////////

 

 

 

// CLLK.h: interface for the CLLK class.

// 连连看游戏封装

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_CLLK_H__3524DD44_7C12_44D5_9C56_E7E47FE54BF4__INCLUDED_)

#define AFX_CLLK_H__3524DD44_7C12_44D5_9C56_E7E47FE54BF4__INCLUDED_

#include "LLKDefine.h"

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

enum BOX_TYPE

{

BT_NULL = 0

};

 

// 连连看结构体

typedef struct _LLK_STATE

{

// 游戏状态

int m_nBoxXCount;

int m_nBoxYCount;

int m_nArrType[BOX_X_COUNT][BOX_Y_COUNT]; //矩阵元素数组

 

int m_nSelBox; //当前选择的方块个数

CPoint m_ptSelBox[2]; //当前选择的坐标

 

int m_nLeaveBoxCount; //剩余的方块数

 

BOOL m_bHasWillBeNullBox; //是否存在要被删除的方块

CPoint m_ptWillBeNullBox[2]; //将要被删除的方块 为了延迟显示消除

int m_typeWillBeNullBox[2]; //将要被删除的方块的类型

 

int m_nLinkLine; //被消除时需要的连接线的个数

CPoint m_ptLinkLine[4]; //消除时需要的连接各坐标

 

int m_nMaxLianji; //最大连击数

int m_nCurLianji; //当前连击数

DWORD m_dwLastLianjiTime; //上次的连击时间

}LLK_STATE;

 

// 连连看类

class CLLK : public LLK_STATE

{

public:

CLLK();

virtual ~CLLK();

 

int Pack(char *pData);

int UnPack(const void *pData);

 

void Init();

VOID InitGameData(int mode = 0);

BOOL IsPairCanLink(CPoint pt1,

  CPoint pt2,

  int *nResultPtCount = NULL,

  CPoint *result = NULL); //判断两坐标是否消除

 

BOOL IsPairInlineValid(CPoint pt1, CPoint pt2); //判断两坐标是否在同一线上 并且中间无阻碍

BOOL IsCanXiaoChu(); //判断当时是否有可以消除的两张图

BOOL DoXiaoChu(); //执行消除

void ResetBoxState();

};

 

#endif // !defined(AFX_CLLK_H__3524DD44_7C12_44D5_9C56_E7E47FE54BF4__INCLUDED_)

 

 

 

// Game.cpp: implementation of the CGame class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Game.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CGame::CGame()

{

}

 

CGame::~CGame()

{

}

 

 

// Game.h: interface for the CGame class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_GAME_H__2156043B_DDE0_4B94_8291_2C8C2396DF63__INCLUDED_)

#define AFX_GAME_H__2156043B_DDE0_4B94_8291_2C8C2396DF63__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CGame

{

public:

CGame();

virtual ~CGame();

};

 

#endif // !defined(AFX_GAME_H__2156043B_DDE0_4B94_8291_2C8C2396DF63__INCLUDED_)

 

 

 

// GameMan.cpp: implementation of the CGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "GameMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CGameMan::CGameMan()

{

}

 

CGameMan::~CGameMan()

{

}

 

 

 

 

// GameMan.h: interface for the CGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_GAMEMAN_H__92B4DE1C_A491_4CFB_B156_02C5A80A6AC0__INCLUDED_)

#define AFX_GAMEMAN_H__92B4DE1C_A491_4CFB_B156_02C5A80A6AC0__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

// #define GAME_STATE_NULL 0

// #define GAME_STATE_READY 1

// #define GAME_STATE_PLAYING 2

 

class CGameMan

{

public:

CGameMan();

virtual ~CGameMan();

};

 

#endif // !defined(AFX_GAMEMAN_H__92B4DE1C_A491_4CFB_B156_02C5A80A6AC0__INCLUDED_)

 

 

 

 

//////////////////////////////////////////////////////////////////////////

// define.h 公共定义文件

 

#ifndef __LLK_DEFINE_H

#define __LLK_DEFINE_H

 

// 游戏基本设置

#define GAME_BEGIN_X -10 //游戏框起始X

#define GAME_BEGIN_Y 160 //游戏框起始Y

 

#define BOX_X_COUNT 14 //X轴方块个数

#define BOX_Y_COUNT 10 //Y轴方块个数

 

#define BOX_X 40 //方块X像素

#define BOX_Y 40 //方块Y像素

 

#define BOX_X_SEPRETER 5 //方块X间距

#define BOX_Y_SEPRETER 4 //方块Y间距

 

#define GAME_MAX_X BOX_X_COUNT*(BOX_X+BOX_X_SEPRETER) //游戏窗口X大小

#define GAME_MAX_Y BOX_Y_COUNT*(BOX_Y+BOX_Y_SEPRETER) //游戏窗口Y大小

 

#define GAME_LAST_BOX_COUNT_OUT_X 480

#define GAME_LAST_BOX_COUNT_OUT_Y 570

 

#define BOX_TYPE_SIZE 16 //方块种类总数

 

#define GAME_DRAW_LINK_LINE_TIMER_ID 100

#define GAME_DRAW_LINK_LINE_TIME 500

 

#define GAME_TIMER_ID_REFLASH 101

#define GAME_TIME_REFLASH 1000/60

 

#define GAME_LIANJI_TIMEOUT 2000

 

#define GAME_PLAYER_STATE_X_BEGIN 16

#define GAME_PLAYER_STATE_Y_BEGIN 36

//BOX_TYPE

 

typedef struct _BOX_STATE

{

INT nType;

// BOOL bIsSelect;

INT nAniState;

}BOX_STATE;

 

#endif

 

 

// LLKGameMan.cpp: implementation of the CLLKGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "LLKGameMan.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#include "../Common/User.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CLLKGameMan::CLLKGameMan()

{

m_state = GAME_NULL;

ZeroMemory(m_UID, sizeof(m_UID));

}

 

CLLKGameMan::~CLLKGameMan()

{

}

 

int CLLKGameMan::Pack(char *pData)

{

COutStream cos;

cos.Create(sizeof(int) + sizeof(CLLKGameMan));

int dataSize = sizeof(CLLKGameMan);

cos << dataSize;

cos.Write(this, dataSize);

// cos.Write((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// char * pBuf = cos.GetCurPtr();

// int len = m_llk[i].Pack(pBuf);

// cos.MoveCurPtr(len);

// }

// }

// dataSize = cos.GetSize() - sizeof(int);

// *(int*)cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CLLKGameMan::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

cis.Read(this, sizeof(CLLKGameMan));

// cis.Read((char *)m_bHasPlayer, sizeof(m_bHasPlayer));

// for (int i=0;i<6;i++)

// {

// if (m_bHasPlayer[i])

// {

// const char * pBuf = cis.GetCurPtr();

// int len = m_llk[i].UnPack(pBuf);

// cis.MoveCurPtr(len);

// }

// }

return cis.GetSize();

}

 

BOOL CLLKGameMan::AddUser( int UID, char * nickName, int score, int tid, int sid )

{

if (m_UID[sid] == 0)

{

m_UID[sid] = UID;

strcpy(m_NickName[sid], nickName);

m_Score[sid] = score;

}

return TRUE;

}

 

BOOL CLLKGameMan::DelUser( int UID )

{

 

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_UID[i] = 0;

strcpy(m_NickName[i], "");

m_Score[i] = 0;

m_userState[i] = GAME_NULL;

if (GetUserCount() == 0)

{

m_state = GAME_NULL;

}

return TRUE;

}

}

 

return FALSE;

}

 

void CLLKGameMan::InitGame()

{

for (int i = 0; i < 6; i++)

{

m_llk[i].Init();

}

m_llk[0].InitGameData();

// m_llk[0].m_nArrType[1][1] = 1;

// m_llk[0].m_nArrType[1][5] = 1;

// m_llk[0].m_nLeaveBoxCount = 2;

for (i = 1; i < 6; i++)

{

m_llk[i] = m_llk[0];

}

}

 

void CLLKGameMan::SetUserState( int UID, int state )

{

for (int i= 0;i<6;i++)

{

if (m_UID[i] == UID)

{

m_userState[i] = state;

return;

}

}

}

 

int CLLKGameMan::CheckGame()

{

if (m_state == GAME_NULL)

{

int userCount = GetUserCount();

if (GetUserCount() == 0)

{

return 0;

}

int readyUserCount = GetReadyUserCount();

if (userCount == readyUserCount && userCount >= MINI_USER_TO_PLAY)

{

return CGR_TOBEGIN;

}

}

else if (m_state == GAME_PLAYING)

{

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_llk[i].m_nLeaveBoxCount == 0)

{

return CGR_TOEND;

}

}

}

 

return CGR_NULL;

}

 

int CLLKGameMan::GetUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

count++;

}

}

return count;

}

 

int CLLKGameMan::GetReadyUserCount()

{

int count = 0;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0 && m_userState[i] == CUser::GAME_STATE_READY)

{

count++;

}

}

return count;

}

 

BOOL CLLKGameMan::StartGame( int nGameID /*= 1*/ )

{

m_state = GAME_PLAYING;

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_PLAYING;

}

}

InitGame();

return TRUE;

}

 

CScoreList CLLKGameMan::EndGame( int nGameID /*= 1*/ )

{

CScoreList  sl;

//游戏结束前计算分数

for (int i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

SCORE_INFO si;

si.UID = m_UID[i];

strcpy(si.NickName, m_NickName[i]);

si.GameID = 1000;

si.Score = m_llk[i].m_nLeaveBoxCount;

sl.Add(si);

}

}

CalcScore(sl);

 

//清除各种状态

m_state = GAME_NULL;

for (i=0;i<6;i++)

{

if (m_UID[i] != 0)

{

m_userState[i] = GAME_NULL;

}

}

 

return sl;

}

 

int CLLKGameMan::CalcScore( CScoreList &sl )

{

sl.Sort();

switch (sl.GetCount())

{

case 0:

TRACE("CalcScore not item in scoreList.. \n");

break;

case 1:

sl.GetScoreByIndex(0).Score = 1;

break;

case 2:

sl.GetScoreByIndex(0).Score = 2;

sl.GetScoreByIndex(1).Score = 0;

 

break;

case 3:

sl.GetScoreByIndex(0).Score = 3;

sl.GetScoreByIndex(1).Score = 1;

sl.GetScoreByIndex(2).Score = -1;

break;

case 4:

sl.GetScoreByIndex(0).Score = 4;

sl.GetScoreByIndex(1).Score = 2;

sl.GetScoreByIndex(2).Score = 0;

sl.GetScoreByIndex(3).Score = -1;

break;

case 5:

sl.GetScoreByIndex(0).Score = 5;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

break;

case 6:

sl.GetScoreByIndex(0).Score = 6;

sl.GetScoreByIndex(1).Score = 3;

sl.GetScoreByIndex(2).Score = 1;

sl.GetScoreByIndex(3).Score = 0;

sl.GetScoreByIndex(4).Score = -1;

sl.GetScoreByIndex(5).Score = -2;

break;

}

return sl.GetCount();

}

 

 

 

// LLKGameMan.h: interface for the CLLKGameMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_LLKGAMEMAN_H__F6E46830_2429_4016_913A_8EC2CB188689__INCLUDED_)

#define AFX_LLKGAMEMAN_H__F6E46830_2429_4016_913A_8EC2CB188689__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "GameMan.h"

#include "CLLK.h"

#include "ScoreList.h"

 

#define GAME_NULL 0

#define GAME_READY 1

#define GAME_PLAYING 2

#define GAME_END

 

#define CHECK_GAME_RET

#define CGR_NULL 0

#define CGR_TOBEGIN 1

#define CGR_TOEND 2

 

#define MINI_USER_TO_PLAY 2

class CLLKGameMan : public CGameMan

{

public:

CLLKGameMan();

virtual ~CLLKGameMan();

// 序列化函数

int Pack(char *pData);

int UnPack(const void *pData);

 

// 用户管理

BOOL AddUser(int UID, char *nickName, int score, int tid, int sid);

BOOL DelUser(int UID);

 

int GetUserCount();

int GetReadyUserCount();

 

BOOL StartGame(int nGameID = 1);

CScoreList EndGame(int nGameID = 1);

 

void InitGame();

int CheckGame();

int CalcScore(CScoreList &sl);

 

void SetUserState(int UID, int state);

public:

int m_state;

int m_UID[6];

char m_NickName[6][11];

int m_Score[6];

int m_userState[6];

CLLK m_llk[6];

};

 

#endif // !defined(AFX_LLKGAMEMAN_H__F6E46830_2429_4016_913A_8EC2CB188689__INCLUDED_)

 

 

 

// Packet.cpp: implementation of the CPacket class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Packet.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CPacket::CPacket()

{

m_nType = 0;

m_nVersion = 0;

m_nDataLen = 0;

m_pData = NULL;

}

 

CPacket::~CPacket()

{

if (m_pData != NULL)

{

delete m_pData;

m_pData = NULL;

}

}

 

int CPacket::Pack(char *pData)

{

COutStream cos;

int size = GetPackSize();

cos.Create(size);

// 先写长度

cos << size;

// 再写数据

cos << m_nType << m_nVersion << m_nDataLen;

cos.Write(m_pData, m_nDataLen);

 

// 最后COPY到缓冲

cos.CopyTo(pData);

return cos.GetSize();

}

 

int CPacket::UnPack(const char *pData)

{

if (pData == NULL)

{

return 0;

}

if (m_pData != NULL)

{

delete m_pData;

m_pData = NULL;

}

CInStream cis;

cis.Create(pData);

int packSize = 0;

cis >> packSize;

cis >> m_nType >> m_nVersion >> m_nDataLen;

if (m_nDataLen > 0)

{

m_pData = new char[m_nDataLen];

cis.Read(m_pData, m_nDataLen);

}

return packSize;

}

 

void CPacket::Make( int type, int version, int dataSize, const void *pData )

{

if (m_pData != NULL)

{

delete[] m_pData;

m_pData = NULL;

}

m_nType = type;

m_nVersion = version;

m_nDataLen = dataSize;

if (pData == NULL)

{

m_pData = NULL;

}

else

{

m_pData = new char[m_nDataLen];

memcpy(m_pData, pData, m_nDataLen);

}

}

 

int CPacket::GetDataSize()

{

COutStream cos;

cos.Create(10240);

cos << m_nType << m_nVersion << m_nDataLen;

cos.Write(m_pData, m_nDataLen);

return cos.GetSize();

}

 

int CPacket::GetPackSize()

{

return GetDataSize() + sizeof(int);

}

 

 

 

// Packet.h: interface for the CPacket class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_PACKET_H__F38AB289_53A5_4601_B49F_6D96B3AA79C9__INCLUDED_)

#define AFX_PACKET_H__F38AB289_53A5_4601_B49F_6D96B3AA79C9__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

 

class CPacket

{

public:

CPacket();

virtual ~CPacket();

int Pack(char *pData);

int UnPack(const char *pData);

int GetDataSize();

int GetPackSize();

 

void Make(int type, int version, int dataSize, const void *pData);

 

public:

int m_nType;

int m_nVersion;

int m_nDataLen;

char *m_pData;

};

 

#endif // !defined(AFX_PACKET_H__F38AB289_53A5_4601_B49F_6D96B3AA79C9__INCLUDED_)

 

 

 

// Room.cpp: implementation of the CRoom class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Room.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CRoom::CRoom()

{

}

 

CRoom::~CRoom()

{

}

 

 

 

 

// Room.h: interface for the CRoom class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_ROOM_H__AA23E442_C8AF_4D89_A280_C576C7137014__INCLUDED_)

#define AFX_ROOM_H__AA23E442_C8AF_4D89_A280_C576C7137014__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CRoom

{

public:

CRoom();

virtual ~CRoom();

BOOL AddUser(int UID);

BOOL DelUser(int UID);

 

private:

int m_nID;

int m_nGameID;

};

 

#endif // !defined(AFX_ROOM_H__AA23E442_C8AF_4D89_A280_C576C7137014__INCLUDED_)

 

 

 

// RoomList.cpp: implementation of the CRoomList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "RoomList.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CRoomList::CRoomList()

{

}

 

CRoomList::~CRoomList()

{

}

 

 

 

// RoomList.h: interface for the CRoomList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_ROOMLIST_H__723A5C9B_F1A8_4109_BAD5_94733038166C__INCLUDED_)

#define AFX_ROOMLIST_H__723A5C9B_F1A8_4109_BAD5_94733038166C__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CRoomList

{

public:

CRoomList();

virtual ~CRoomList();

};

 

#endif // !defined(AFX_ROOMLIST_H__723A5C9B_F1A8_4109_BAD5_94733038166C__INCLUDED_)

 

 

 

 

// RoomMan.cpp: implementation of the CRoomMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "RoomMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CRoomMan::CRoomMan()

{

}

 

CRoomMan::~CRoomMan()

{

}

 

 

 

// RoomMan.h: interface for the CRoomMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_ROOMMAN_H__3FEFB6D8_B7DC_4B7E_AD0A_8EE5CD2CF164__INCLUDED_)

#define AFX_ROOMMAN_H__3FEFB6D8_B7DC_4B7E_AD0A_8EE5CD2CF164__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CRoomMan

{

public:

CRoomMan();

virtual ~CRoomMan();

};

 

#endif // !defined(AFX_ROOMMAN_H__3FEFB6D8_B7DC_4B7E_AD0A_8EE5CD2CF164__INCLUDED_)

 

 

 

 

 

// ScoreList.cpp: implementation of the CScoreList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "ScoreList.h"

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CScoreList::CScoreList()

{

 

}

 

CScoreList::~CScoreList()

{

 

}

 

int CScoreList::Pack( void * pData )

{

COutStream cos;

int dataSize = 0;

int count = GetCount();

cos.Create(count*sizeof(SCORE_INFO)+sizeof(int)*2);

 

cos<<dataSize;

cos<<count;

for (int i=0;i<count;i++)

{

cos.Write(&m_vecScore.at(i), sizeof(SCORE_INFO));

}

dataSize = cos.GetSize() - sizeof(int);

*(int*)cos.GetHead() = dataSize;

cos.CopyTo(pData);

return dataSize + sizeof(int);

}

 

int CScoreList::UnPack( const void * pData )

{

m_vecScore.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

int count = 0;

cis>>dataSize>>count;

SCORE_INFO scoreInfo;

for (int i=0;i<count;i++)

{

cis.Read(&scoreInfo, sizeof(SCORE_INFO));

m_vecScore.push_back(scoreInfo);

}

return cis.GetSize();

}

 

void CScoreList::Add( SCORE_INFO& scoreInfo )

{

m_vecScore.push_back(scoreInfo);

}

 

BOOL CScoreList::Del( int uid, int gid )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

for (;begit != endit; ++begit)

{

if (begit->GameID == gid && begit->UID == uid)

{

m_vecScore.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

int CScoreList::GetCount()

{

return m_vecScore.size();

}

 

SCORE_INFO &CScoreList::GetScoreByIndex( int index )

{

return m_vecScore[index];

}

 

void CScoreList::Sort( int mode /*= 0*/ )

{

VEC_SCORE_INFO::iterator begit = m_vecScore.begin();

VEC_SCORE_INFO::iterator endit = m_vecScore.end();

VEC_SCORE_INFO::iterator tmpit = begit+1;

SCORE_INFO tsi;

int swapCount = 0;

do

{

swapCount = 0;

for (;begit != endit - 1; ++begit)

{

tmpit = begit+1;

if (begit->Score > tmpit->Score)

{

tsi = *begit;

*begit = *tmpit;

*tmpit = tsi;

swapCount++;

}

}

} while (swapCount != 0);

}

 

 

 

 

// ScoreList.h: interface for the CScoreList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_SCORELIST_H__4F23F332_9606_412C_AA2A_18EF83BF75A7__INCLUDED_)

#define AFX_SCORELIST_H__4F23F332_9606_412C_AA2A_18EF83BF75A7__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <vector>

using namespace std;

 

typedef struct _SCORE_INFO

{

int UID;

int GameID;

char NickName[11];

int Score;

}SCORE_INFO;

 

typedef vector<SCORE_INFO> VEC_SCORE_INFO;

 

class CScoreList  

{

public:

CScoreList();

virtual ~CScoreList();

 

int Pack(void * pData);

int UnPack(const void * pData);

 

void Add(SCORE_INFO& scoreInfo);

BOOL Del(int uid, int gid);

 

int GetCount();

SCORE_INFO &GetScoreByIndex(int index);

 

void Sort(int mode = 0);

 

private:

VEC_SCORE_INFO m_vecScore;

 

};

 

#endif // !defined(AFX_SCORELIST_H__4F23F332_9606_412C_AA2A_18EF83BF75A7__INCLUDED_)

 

 

 

 

#ifndef __SERVER_DEFINE_H_

#define __SERVER_DEFINE_H_

 

 

// 自定义协议类型定义

#define PTCS_NULL 0

#define PTC_LOGIN_ENTER 1

#define PTS_LOGIN_SUCC 2

#define PTS_LOGIN_FAIL 3

#define PTC_REG_ENTER 4

#define PTS_REG_SUCC 5

#define PTS_REG_FAIL 6

#define PTCS_CHECK_ONLINE 7

#define PTCS_GET_LOGIN_USER_INFO 8

 

#define PTC_SEAT_DOWN 9

#define PTS_SEAT_DOWN_SUCC 10

#define PTS_SEAT_DOWN_FAIL 11

 

#define PTC_LOOK_ON 12

#define PTS_LOOK_ON_SUCC 13

#define PTS_LOOK_ON_FAIL 14

 

#define PTCS_GET_TABLE_INFO 15

 

#define PTCS_EXIT 17

#define PTC_STAND_UP 18

 

#define PTCS_GET_USER_LIST 19

#define PTCS_GET_SCORE_TOP10 20

 

#define PTCS_GET_GAMEINFO 51

#define PTC_SEND_GAMEINFO 52

 

#define PTS_GAME_BEGIN 53

#define PTS_GAME_END 54

 

#define PTC_GAME_READY 55

 

//游戏与客户端通信代码

#define PTCS_GET_HWND 100

#define PTS_SHOW_WINDOW 101

 

//////////////////////////////////////////////////////////////////////////

// 错误码定义

#define EC_LOGIN_FAIL_NULL 1

#define EC_LOGIN_USER_NOT_EXIST 2

#define EC_LOGIN_PASS_ERROR 3

#define EC_LOGIN_USER_LOGINED 4

#define EC_REG_FAIL_NULL 5

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 登录信息

typedef struct _LOGIN_INFO

{

char userid[11];

char password[11];

}LOGIN_INFO;

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 客户端配置信息

typedef struct _CLIENT_SETTING

{

CString m_szServerIP;

UINT m_nServerPort;

}CLIENT_SETTING;

//////////////////////////////////////////////////////////////////////////

 

 

#endif //__SERVER_DEFINE_H_

 

 

 

 

// stdafx.h : include file for standard system include files,

//  or project specific include files that are used frequently, but

//      are changed infrequently

//

 

#ifndef __BASIC_STDAFX_H_

#define __BASIC_STDAFX_H_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

 

#include <afxwin.h>         // MFC core and standard components

#include <afxext.h>         // MFC extensions

#include <afxdisp.h>        // MFC Automation classes

#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls

#ifndef _AFX_NO_AFXCMN_SUPPORT

#include <afxcmn.h> // MFC support for Windows Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

 

#include "../Basic/InStream.h"

#include "../Basic/OutStream.h"

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // __BASIC_STDAFX_H_

 

 

 

// Table.cpp: implementation of the CTable class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Table.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

#include "LLKGameMan.h"

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTable::CTable()

{

m_nTableID = 0;

m_nTableState = GAME_NULL;

}

CTable::~CTable()

{

}

 

VOID CTable::Create(int nTableID, int nSeatCount /*= 6*/)

{

m_nTableID = nTableID;

for (int i = 0; i < 6; i++)

{

m_seat[i].Creat(m_nTableID, i);

}

}

 

BOOL CTable::AddUser(int UID, int SeatID)

{

if (m_seat[SeatID].m_nUID == 0)

{

m_seat[SeatID].m_nUID = UID;

return TRUE;

}

return FALSE;

}

 

BOOL CTable::DelUser(int UID)

{

for (int i = 0; i < 6; i++)

{

if (m_seat[i].m_nUID == UID)

{

m_seat[i].m_nUID = UID;

return TRUE;

}

}

return FALSE;

}

 

int CTable::Pack(char *pData)

{

COutStream cos;

cos.Create(512);

int dataSize = 0;

cos << dataSize;

cos << m_nTableID;

cos << m_nTableState;

cos.Write((char *) m_seat, sizeof(CSeat) * 6);

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

cos.CopyTo(pData);

return cos.GetSize();

}

 

int CTable::UnPack(const char *pData)

{

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

cis >> m_nTableID;

cis >> m_nTableState;

cis.Read((char *) m_seat, sizeof(CSeat) * 6);

return dataSize + sizeof(int);

}

 

CSeat & CTable::GetSeat(int SeatID)

{

return m_seat[SeatID];

}

 

BOOL CTable::StartGame()

{

m_nTableState = GAME_PLAYING;

for (int i=0;i<6;i++)

{

if (m_seat[i].m_nUID != 0)

{

m_seat[i].m_nState = GAME_PLAYING;

}

}

return TRUE;

}

 

BOOL CTable::EndGame()

{

m_nTableState = GAME_NULL;

for (int i=0;i<6;i++)

{

if (m_seat[i].m_nUID != 0)

{

m_seat[i].m_nState = GAME_NULL;

}

}

return TRUE;

}

 

int CTable::GetUserCount()

{

int count = 0;

for (int i=0; i<6; i++)

{

if (m_seat[i].m_nUID != 0)

{

count++;

}

}

return count;

}

CSeat::CSeat()

{

m_nTableID = 0;

m_nSeatID = 0;

m_nUID = 0;

m_nState = 0;

}

 

void CSeat::Creat(int nTableID, int nSeatID)

{

m_nTableID = nTableID;

m_nSeatID = nSeatID;

}

 

 

 

// Table.h: interface for the CTable class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLE_H__646A2362_1C47_41A3_91C4_751748CAB369__INCLUDED_)

#define AFX_TABLE_H__646A2362_1C47_41A3_91C4_751748CAB369__INCLUDED_

 

#include "UserIDList.h"

#include "Packet.h"

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

//#define TABLE_STATE_NOTHING 0

//#define TABLE_STATE_PLAYING 1

 

class CSeat

{

public:

CSeat();

void Creat(int nTableID, int nSeatID);

int m_nSeatID;

int m_nTableID;

int m_nUID;

int m_nState;

};

class CTable

{

public:

CTable();

virtual ~CTable();

 

//创建

VOID Create(int nTableID, int nSeatCount = 6);

 

//用户管理

BOOL AddUser(int UID, int SeatID);

BOOL DelUser(int UID);

 

//序列化函数

int Pack(char *pData);

int UnPack(const char *pData);

 

CSeat &GetSeat(int SeatID);

 

int GetUserCount();

 

BOOL StartGame();

BOOL EndGame();

 

public: //属性访问

int TableID() const

{

return m_nTableID;

}

void TableID(int val)

{

m_nTableID = val;

}

int TableState() const

{

return m_nTableState;

}

void TableState(int val)

{

m_nTableState = val;

}

 

private:

int m_nTableID;

int m_nTableState;

CSeat m_seat[6];

};

 

#endif // !defined(AFX_TABLE_H__646A2362_1C47_41A3_91C4_751748CAB369__INCLUDED_)

 

 

 

// TableIDList.cpp: implementation of the CTableIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableIDList.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableIDList::CTableIDList()

{

}

 

CTableIDList::~CTableIDList()

{

}

 

 

 

// TableIDList.h: interface for the CTableIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_)

#define AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CTableIDList

{

public:

CTableIDList();

virtual ~CTableIDList();

};

 

#endif // !defined(AFX_TABLEIDLIST_H__091DBAC5_129A_4387_A8AE_BA475D224548__INCLUDED_)

 

 

 

// TableList.cpp: implementation of the CTableList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableList.h"

#include "LLKGameMan.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableList::CTableList()

{

}

 

CTableList::~CTableList()

{

}

 

BOOL CTableList::AddUser(int UID, int nTableID, int nSeatID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit->AddUser(UID, nSeatID);

}

}

return FALSE;

}

 

BOOL CTableList::DelUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

// 如果该位置上的id是要删除的id 则删除

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nUID = 0;

// 删除之后 看此桌上的人数是不是为0 没人的话桌面状态初始化

if (begit->GetUserCount() == 0)

{

begit->TableState(GAME_NULL);

}

return TRUE;

}

}

 

}

return FALSE;

}

 

BOOL CTableList::SetUserState(int UID, int nState)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nState = nState;

return TRUE;

}

}

}

return TRUE;

}

 

BOOL CTableList::AddTable(CTable &table)

{

m_vecTable.push_back(table);

return TRUE;

}

 

BOOL CTableList::DelTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

m_vecTable.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

 

CTable * CTableList::GetTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit;

}

}

return NULL;

}

 

int CTableList::Pack(char *pData)

{

COutStream cos;

cos.Create();

int dataSize = 0;

cos << dataSize;

int tableCount = m_vecTable.size();

cos << tableCount;

for (int i = 0; i < tableCount; i++)

{

char buf[512] ={0};

int len = m_vecTable[i].Pack(buf);

cos.Write(buf, len);

}

 

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

 

return dataSize + sizeof(int);

}

 

int CTableList::UnPack(const char *pData)

{

m_vecTable.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

int tableCount = 0;

cis >> tableCount;

for (int i = 0; i < tableCount; i++)

{

CTable table;

const char *p = (const char *)cis.GetCurPtr();

int len = table.UnPack(p);

m_vecTable.push_back(table);

cis.MoveCurPtr(len);

}

return cis.GetSize();

}

 

int CTableList::GetTableCount()

{

return m_vecTable.size();

}

 

BOOL CTableList::HasUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

return TRUE;

}

}

}

return FALSE;

}

 

 

 

// TableList.cpp: implementation of the CTableList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableList.h"

#include "LLKGameMan.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableList::CTableList()

{

}

 

CTableList::~CTableList()

{

}

 

BOOL CTableList::AddUser(int UID, int nTableID, int nSeatID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit->AddUser(UID, nSeatID);

}

}

return FALSE;

}

 

BOOL CTableList::DelUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

// 如果该位置上的id是要删除的id 则删除

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nUID = 0;

// 删除之后 看此桌上的人数是不是为0 没人的话桌面状态初始化

if (begit->GetUserCount() == 0)

{

begit->TableState(GAME_NULL);

}

return TRUE;

}

}

 

}

return FALSE;

}

 

BOOL CTableList::SetUserState(int UID, int nState)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

begit->GetSeat(i).m_nState = nState;

return TRUE;

}

}

}

return TRUE;

}

 

BOOL CTableList::AddTable(CTable &table)

{

m_vecTable.push_back(table);

return TRUE;

}

 

BOOL CTableList::DelTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

m_vecTable.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

 

CTable * CTableList::GetTable(int nTableID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

if (begit->TableID() == nTableID)

{

return begit;

}

}

return NULL;

}

 

int CTableList::Pack(char *pData)

{

COutStream cos;

cos.Create();

int dataSize = 0;

cos << dataSize;

int tableCount = m_vecTable.size();

cos << tableCount;

for (int i = 0; i < tableCount; i++)

{

char buf[512] ={0};

int len = m_vecTable[i].Pack(buf);

cos.Write(buf, len);

}

 

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

 

cos.CopyTo(pData);

 

return dataSize + sizeof(int);

}

 

int CTableList::UnPack(const char *pData)

{

m_vecTable.clear();

CInStream cis;

cis.Create(pData);

int dataSize = 0;

cis >> dataSize;

int tableCount = 0;

cis >> tableCount;

for (int i = 0; i < tableCount; i++)

{

CTable table;

const char *p = (const char *)cis.GetCurPtr();

int len = table.UnPack(p);

m_vecTable.push_back(table);

cis.MoveCurPtr(len);

}

return cis.GetSize();

}

 

int CTableList::GetTableCount()

{

return m_vecTable.size();

}

 

BOOL CTableList::HasUser(int UID)

{

VEC_TABLE::iterator begit = m_vecTable.begin();

VEC_TABLE::iterator endit = m_vecTable.end();

 

for (; begit != endit; ++begit)

{

for (int i = 0; i < 6; i++)

{

if (begit->GetSeat(i).m_nUID == UID)

{

return TRUE;

}

}

}

return FALSE;

}

 

 

 

 

// TableMan.cpp: implementation of the CTableMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "TableMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CTableMan::CTableMan()

{

}

 

CTableMan::~CTableMan()

{

}

 

BOOL CTableMan::AddTable(CTable &table)

{

return m_tablelist.AddTable(table);

}

 

BOOL CTableMan::DelTable(int nTableID)

{

return m_tablelist.DelTable(nTableID);

}

 

BOOL CTableMan::AddUser(int UID, int nTableID, int nSeatID)

{

return m_tablelist.AddUser(UID, nTableID, nSeatID);

}

 

BOOL CTableMan::DelUser(int UID)

{

return m_tablelist.DelUser(UID);

}

 

BOOL CTableMan::SetUserState(int UID, int nState)

{

return m_tablelist.SetUserState(UID, nState);

}

 

int CTableMan::Pack(char *pData)

{

return m_tablelist.Pack(pData);

}

 

int CTableMan::UnPack(const char *pData)

{

return m_tablelist.UnPack(pData);

}

 

CTable * CTableMan::GetTable(int nTableID)

{

return m_tablelist.GetTable(nTableID);

}

 

int CTableMan::GetTableCount()

{

return m_tablelist.GetTableCount();

}

 

BOOL CTableMan::HasUser(int UID)

{

return m_tablelist.HasUser(UID);

}

 

BOOL CTableMan::StartGame( int nTableID /*= 1*/ )

{

CTable * pTable = GetTable(nTableID);

pTable->StartGame();

return TRUE;

}

 

BOOL CTableMan::EndGame( int nTableID /*= 1*/ )

{

CTable * pTable = GetTable(nTableID);

pTable->EndGame();

return TRUE;

}

 

 

 

 

// TableMan.h: interface for the CTableMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_TABLEMAN_H__6E3AD82B_25ED_4A8A_B02E_F05369FAF24D__INCLUDED_)

#define AFX_TABLEMAN_H__6E3AD82B_25ED_4A8A_B02E_F05369FAF24D__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "TableList.h"

 

class CTableMan

{

public:

CTableMan();

virtual ~CTableMan();

BOOL AddTable(CTable &table);

BOOL DelTable(int nTableID);

 

BOOL AddUser(int UID, int nTableID, int nSeatID);

BOOL DelUser(int UID);

 

BOOL HasUser(int UID);

 

BOOL SetUserState(int UID, int nState);

BOOL StartGame(int nTableID = 1);

BOOL EndGame(int nTableID = 1);

 

CTable *GetTable(int nTableID);

int GetTableCount();

int Pack(char *pData);

int UnPack(const char *pData);

public:

CTableList m_tablelist;

};

 

#endif // !defined(AFX_TABLEMAN_H__6E3AD82B_25ED_4A8A_B02E_F05369FAF24D__INCLUDED_)

 

 

 

// User.cpp: implementation of the CUser class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "User.h"

 

#include <winsock2.h>

#include "../Basic/OutStream.h"

#include "../Basic/InStream.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

int CUser::MAX_PACK_SIZE = sizeof(int) * 10 +

  sizeof(sockaddr) +

  100;

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUser::CUser()

{

m_nID = 0;

m_szName.Empty();

m_szNickname.Empty();

m_szPassword.Empty();

m_nSex = SEX_BAOMI;

m_szBirthday.Empty();

m_szPhone.Empty();

m_nState = STATE_OFFLINE;

m_nFaceID = 0;

// 在线状态的信息

ZeroMemory(&m_addr, sizeof(sockaddr));

m_nGameState = GAME_STATE_NOTHING;

m_nRoomID = 0;

m_nTableID = 0;

m_nSeatID = 0;

 

m_nLLKScore = 0;

}

 

CUser::~CUser()

{

}

 

//////////////////////////////////////////////////////////////////////////

// 用户信息打包

// 参数:pData 存放用户打包信息的地址

// 返回:包的大小

int CUser::Pack(char *pData)

{

// 申请buf

COutStream cos;

cos.Create(MAX_PACK_SIZE);

int dataSize = 0;

// 先写大小 为0 最后修改

cos << dataSize;

// 再写数据

cos << m_nID << m_szName << m_szNickname << m_szPassword << m_nSex

<< m_szBirthday << m_nState << m_nFaceID;

cos.Write(&m_addr, sizeof(sockaddr));

cos << m_nGameState << m_nRoomID << m_nTableID << m_nSeatID << m_nLLKScore;

 

int packSize = cos.GetSize();

// 写入长度

*(int *) cos.GetHead() = packSize - sizeof(int);

 

// 向缓冲写入

cos.CopyTo(pData);

return packSize;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 解包

// 参数:pData 包数据的地址 DataSize 包数据的大小

// 返回:读取包的长度 包括长度变量

int CUser::UnPack( const void *pData )

{

CInStream cis;

cis.Create(pData);

int DataSize = 0;

cis >> DataSize;

cis >> m_nID >> m_szName >> m_szNickname >> m_szPassword >> m_nSex

>> m_szBirthday >> m_nState >> m_nFaceID;

cis.Read(&m_addr, sizeof(sockaddr));

cis >> m_nGameState >> m_nRoomID >> m_nTableID >> m_nSeatID >> m_nLLKScore;

 

return DataSize + sizeof(int);

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到打包后数据的大小

int CUser::GetPackSize()

{

return sizeof(int) + GetDataSize();

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 得到数据大小

int CUser::GetDataSize()

{

// 先计算数据的大小

int dataSize = 0;

dataSize += sizeof(int); // m_nID

dataSize += sizeof(int) + m_szName.GetLength() + 1;

dataSize += sizeof(int) + m_szNickname.GetLength() + 1;

dataSize += sizeof(int) + m_szPassword.GetLength() + 1;

dataSize += sizeof(int); //m_nSex

dataSize += sizeof(int) + m_szBirthday.GetLength() + 1;

dataSize += sizeof(int) + m_szPhone.GetLength() + 1;

dataSize += sizeof(int); //m_nState;

dataSize += sizeof(int); //m_nFaceID;

 

// 在线状态的信息

dataSize += sizeof(sockaddr); //m_addr;

dataSize += sizeof(int); //m_nGameState;

dataSize += sizeof(int); //m_nRoomID;

dataSize += sizeof(int); //m_nTableID;

dataSize += sizeof(int); //m_nSeatID;

 

//以下是模拟打包返回长度 效率问题不使用

/*

COutStream cos;

cos.Create(1024);

cos << m_nID << m_szName << m_szNickname << m_szPassword << m_nSex

<< m_szBirthday << m_nState << m_nFaceID;

cos.Write(&m_addr, sizeof(sockaddr));

cos << m_nGameState << m_nRoomID << m_nTableID << m_nSeatID;

return cos.GetSize();

 

*/

return dataSize;

}

//////////////////////////////////////////////////////////////////////////

 

 

//////////////////////////////////////////////////////////////////////////

// 地址的对比函数

// 参数:要比较的两个地址指针

// 返回:同则返回TRUE

BOOL CUser::AddrCmp(const sockaddr *addr1, const sockaddr *addr2)

{

for (int i = 0; i < sizeof(sockaddr); i++)

{

if (*((char *) (addr1) + i) != *((char *) (addr2) + i))

{

return FALSE;

}

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

 

 

 

 

// User.h: interface for the CUser class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USER_H__49D2C842_4BDA_42CB_8E66_562823E19F5A__INCLUDED_)

#define AFX_USER_H__49D2C842_4BDA_42CB_8E66_562823E19F5A__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <WINSOCK2.H>

class CUser

{

public:

static  int MAX_PACK_SIZE;

public:

enum

{

SEX_BAOMI = 0,

SEX_MALE = 1,

SEX_FAMALE = 2

};

enum

{

STATE_OFFLINE = 0,

STATE_ONLINE = 1

};

enum

{

GAME_STATE_NOTHING = 0,

GAME_STATE_SEATDOWN = 1,

GAME_STATE_READY = 2,

GAME_STATE_PLAY = 3

};

public:

CUser();

virtual ~CUser();

int Pack(char *pData);

int UnPack(const void *pData);

int GetPackSize();

int GetDataSize();

 

 

public:

int ID() const

{

return m_nID;

}

void ID(int val)

{

m_nID = val;

}

CString Name() const

{

return m_szName;

}

void Name(CString val)

{

m_szName = val;

}

CString Nickname() const

{

return m_szNickname;

}

void Nickname(CString val)

{

m_szNickname = val;

}

CString Password() const

{

return m_szPassword;

}

void Password(CString val)

{

m_szPassword = val;

}

int Sex() const

{

return m_nSex;

}

void Sex(int val)

{

m_nSex = val;

}

CString Birthday() const

{

return m_szBirthday;

}

void Birthday(CString val)

{

m_szBirthday = val;

}

CString Phone() const

{

return m_szPhone;

}

void Phone(CString val)

{

m_szPhone = val;

}

int State() const

{

return m_nState;

}

void State(int val)

{

m_nState = val;

}

int FaceID() const

{

return m_nFaceID;

}

void FaceID(int val)

{

m_nFaceID = val;

}

sockaddr Addr() const

{

return m_addr;

}

void Addr(sockaddr val)

{

m_addr = val;

}

int GameState() const

{

return m_nGameState;

}

void GameState(int val)

{

m_nGameState = val;

}

int RoomID() const

{

return m_nRoomID;

}

void RoomID(int val)

{

m_nRoomID = val;

}

int TableID() const

{

return m_nTableID;

}

void TableID(int val)

{

m_nTableID = val;

}

 

int SeatID() const

{

return m_nSeatID;

}

void SeatID(int val)

{

m_nSeatID = val;

}

int LLKScore() const

{

return m_nLLKScore;

}

void LLKScore(int val)

{

m_nLLKScore = val;

}

 

public:

friend class CUserList;

static BOOL AddrCmp(const sockaddr *addr1, const sockaddr *addr2);

private:

// 基本信息

int m_nID;

CString m_szName;

CString m_szNickname;

CString m_szPassword;

int m_nSex;

CString m_szBirthday;

CString m_szPhone;

int m_nState;

int m_nFaceID;

 

// 在线状态的信息

sockaddr m_addr;

int m_nGameState;

int m_nRoomID;

int m_nTableID;

int m_nSeatID;

 

// 游戏积分

int m_nLLKScore;

};

 

#endif // !defined(AFX_USER_H__49D2C842_4BDA_42CB_8E66_562823E19F5A__INCLUDED_)

 

 

 

 

// UserIDList.cpp: implementation of the CUserIDList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserIDList.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserIDList::CUserIDList()

{

}

 

CUserIDList::~CUserIDList()

{

}

 

BOOL CUserIDList::AddUser(int UID)

{

VEC_USERID::iterator begit = m_vecUserID.begin();

VEC_USERID::iterator endit = m_vecUserID.end();

 

for (; begit != endit; ++begit)

{

if (*begit == UID)

{

return FALSE;

}

}

m_vecUserID.push_back(UID);

return TRUE;

}

 

BOOL CUserIDList::DelUser(int UID)

{

VEC_USERID::iterator begit = m_vecUserID.begin();

VEC_USERID::iterator endit = m_vecUserID.end();

 

for (; begit != endit; ++begit)

{

if (*begit == UID)

{

m_vecUserID.erase(begit);

return TRUE;

}

}

return FALSE;

}

 

CUser * CUserIDList::GetUser(int index, CUserMan *pUserMan)

{

return pUserMan->GetUser(m_vecUserID[index]);

}

 

 

 

 

 

// UserIDList.h: interface for the CUserIDList class.

// CUserIDList 是对CUserList的映射 可以保证数据的同一性 无冗余

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USERIDLIST_H__AA2F05ED_5985_4343_A70B_8BF47BAC52BC__INCLUDED_)

#define AFX_USERIDLIST_H__AA2F05ED_5985_4343_A70B_8BF47BAC52BC__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "UserMan.h"

#include <vector>

using namespace std;

 

class CUserMan;

 

typedef vector<int> VEC_USERID;

 

class CUserIDList

{

public:

CUserIDList();

virtual ~CUserIDList();

BOOL AddUser(int UID);

BOOL DelUser(int UID);

CUser *GetUser(int index, CUserMan *pUserMan);

private:

VEC_USERID m_vecUserID;

};

 

#endif // !defined(AFX_USERIDLIST_H__AA2F05ED_5985_4343_A70B_8BF47BAC52BC__INCLUDED_)

 

 

// UserList.cpp: implementation of the CUserList class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserList.h"

#include "../Basic/OutStream.h"

#include "../Basic/InStream.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserList::CUserList()

{

}

 

CUserList::~CUserList()

{

}

 

BOOL CUserList::AddUser(CUser &user)

{

MAP_USER::_Pairib ret = m_mapUser.insert(MAP_USER::value_type(user.m_nID,

user));

if (ret.second == true)

{

return TRUE;

}

else

{

return FALSE;

}

}

 

BOOL CUserList::DelUser(int UID)

{

int ret = m_mapUser.erase(UID);

if (ret == 1)

{

return TRUE;

}

else

{

return FALSE;

}

}

 

CUser * CUserList::GetUser(int UID)

{

MAP_USER::iterator itRet = m_mapUser.find(UID);

if (itRet == m_mapUser.end())

{

return NULL;

}

else

{

return &itRet->second;

}

}

 

 

CUser * CUserList::GetUserByIndex(int index)

{

if (index < 0 || index >= GetUserCount())

{

return NULL;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

int i = 0;

for (; begiter != enditer; ++begiter)

{

if (i == index)

{

return &begiter->second;

}

i++;

}

 

return NULL;

}

 

int CUserList::GetUserIDByAddr(const sockaddr &addr)

{

MAP_USER::iterator it;

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

if (CUser::AddrCmp(&addr, &it->second.m_addr))

{

return it->first;

}

}

return 0;

}

 

BOOL CUserList::HasUser(int UID)

{

CUser *pUser = GetUser(UID);

if (pUser == NULL)

{

return FALSE;

}

else

{

return TRUE;

}

}

 

int CUserList::GetUserCount()

{

return m_mapUser.size();

}

 

void CUserList::Empty()

{

m_mapUser.clear();

}

 

int CUserList::Pack(char *pData)

{

int userCount = GetUserCount();

COutStream cos;

cos.Create(CUser::MAX_PACK_SIZE * userCount);

int dataSize = 0;

cos << dataSize;

cos << userCount;

 

MAP_USER::iterator it;

char *buf = new char[CUser::MAX_PACK_SIZE];

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

//清空缓冲

ZeroMemory(buf, CUser::MAX_PACK_SIZE);

//打包函数已经把大小写入了 所以无需再写长度了

int len = it->second.Pack(buf);

cos.Write(buf, len);

}

cos.CopyTo(pData);

dataSize = cos.GetSize() - sizeof(int);

*(int *) cos.GetHead() = dataSize;

delete[] buf;

return dataSize + sizeof(int) ;

}

 

int CUserList::UnPack(const char *pData)

{

if (pData == NULL)

{

return 0;

}

CInStream cis;

cis.Create(pData);

int DataSize = 0;

cis >> DataSize;

Empty();

 

int userCount = 0;

cis >> userCount;

int packSize = 0;

for (int i = 0; i < userCount; i++)

{

CUser user;

packSize = user.UnPack(cis.GetCurPtr());

cis.MoveCurPtr(packSize);

m_mapUser.insert(MAP_USER::value_type(user.m_nID, user));

}

 

return cis.GetSize();

}

 

int CUserList::GetPackSize()

{

return GetDataSize() + sizeof(int);

}

 

int CUserList::GetDataSize()

{

int DataSize = 0;

DataSize += sizeof(int); //用户个数存放

 

MAP_USER::iterator it;

for (it = m_mapUser.begin(); it != m_mapUser.end(); it++)

{

DataSize += it->second.GetPackSize(); //数据包大小 已包含数据大小

}

return DataSize;

}

 

CUser * CUserList::GetUserByAddr( const sockaddr &addr )

{

if (GetUserCount() == 0)

{

return NULL;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

for (; begiter != enditer; ++begiter)

{

if (CUser::AddrCmp(&begiter->second.m_addr, &addr))

{

return &begiter->second;

}

}

 

return NULL;

}

 

void CUserList::AddScore( int UID, int score )

{

if (GetUserCount() == 0)

{

return ;

}

MAP_USER::iterator begiter = m_mapUser.begin();   

MAP_USER::iterator enditer = m_mapUser.end();   

for (; begiter != enditer; ++begiter)

{

if (begiter->second.m_nID == UID)

{

begiter->second.m_nLLKScore+=score;

}

}

 

return ;

}

 

 

 

// UserList.h: interface for the CUserList class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USERLIST_H__A1C3DB85_079E_4FF6_A61D_4138CD93BCBA__INCLUDED_)

#define AFX_USERLIST_H__A1C3DB85_079E_4FF6_A61D_4138CD93BCBA__INCLUDED_

 

#pragma warning(disable:4786)

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include "User.h"

 

#include <map>

using namespace std;

typedef map<int, CUser> MAP_USER;

class CUserList

{

public:

CUserList();

virtual ~CUserList();

BOOL AddUser(CUser &user); //往列表中添加用户

BOOL DelUser(int UID); //删除用户

CUser *GetUser(int UID); //得到用户信息

CUser *GetUserByIndex(int index); //使用索引得到用户信息

CUser *GetUserByAddr(const sockaddr &addr); //从地址得到用户信息

int GetUserCount(); //得到用户数量

 

int GetUserIDByAddr(const sockaddr &addr); //通过地址得到id

BOOL HasUser(int UID); //判断是否存在某用户

void Empty(); //清空用户信息

 

void AddScore(int UID, int score);

 

//打包相关函数

int Pack(char *pData); //打包

int UnPack(const char *pData); //解包

int GetPackSize(); //得到包大小

int GetDataSize(); //得到数据所占的大小

 

public:

MAP_USER m_mapUser;

};

 

#endif // !defined(AFX_USERLIST_H__A1C3DB85_079E_4FF6_A61D_4138CD93BCBA__INCLUDED_)

 

 

 

 

// UserMan.cpp: implementation of the CUserMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UserMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CUserMan::CUserMan()

{

}

 

CUserMan::~CUserMan()

{

}

 

BOOL CUserMan::AddUser( CUser &user )

{

return m_userlist.AddUser(user);

}

 

BOOL CUserMan::HasUser(int UID)

{

return m_userlist.HasUser(UID);

}

 

BOOL CUserMan::DelUser(int UID)

{

return m_userlist.DelUser(UID);

}

 

BOOL CUserMan::SetUserState(int UID, int state)

{

CUser *pUser = m_userlist.GetUser(UID);

if (pUser == NULL)

{

return FALSE;

}

else

{

pUser->State(state);

}

return TRUE;

}

 

CUser * CUserMan::GetUser(int UID)

{

return m_userlist.GetUser(UID);

}

 

int CUserMan::GetUserID(const sockaddr &addr)

{

return m_userlist.GetUserIDByAddr(addr);

}

 

CUserList CUserMan::GetUserList(int mode /*= 0*/, WPARAM wParam /*= 0*/)

{

return m_userlist;

}

 

BOOL CUserMan::AddUserIDList(CUserIDList *pUserIDList)

{

SET_CUSERIDLIST::_Pairib retPair = m_setUserIDList.insert(SET_CUSERIDLIST::value_type(pUserIDList));

if (retPair.second == false)

{

return FALSE;

}

else

{

return TRUE;

}

}

 

void CUserMan::DelUserIDList(CUserIDList *pUserIDList)

{

SET_CUSERIDLIST::iterator begit = m_setUserIDList.begin();

SET_CUSERIDLIST::iterator endit = m_setUserIDList.end();

 

for (; begit != endit; ++begit)

{

if (*begit == pUserIDList)

{

m_setUserIDList.erase(begit);

break;

}

}

}

 

int CUserMan::Pack(char *pData)

{

return m_userlist.Pack(pData);

}

 

int CUserMan::UnPack(const char *pData)

{

return m_userlist.UnPack(pData);

}

 

int CUserMan::GetUserCount()

{

return m_userlist.GetUserCount();

}

 

// sockaddr CUserMan::GetUserAddr(int UID)

// {

// return m_userlist.GetUser(UID)->Addr();

// }

 

CUser * CUserMan::GetUserByIndex(int index)

{

return m_userlist.GetUserByIndex(index);

}

 

CUser * CUserMan::GetUserByAddr( const sockaddr &addr )

{

return m_userlist.GetUserByAddr(addr);

}

 

void CUserMan::AddScore( int UID, int score )

{

m_userlist.AddScore(UID, score);

}

 

 

 

 

// UserMan.h: interface for the CUserMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_USERMAN_H__CCBDF347_5FBC_4D2D_A07C_C72F5A9BEEC5__INCLUDED_)

#define AFX_USERMAN_H__CCBDF347_5FBC_4D2D_A07C_C72F5A9BEEC5__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "UserList.h"

#include "UserIDList.h"

#include <set>

using namespace std;

 

class CUserIDList;

 

typedef set<CUserIDList*> SET_CUSERIDLIST;

 

//////////////////////////////////////////////////////////////////////////

// 用户管理类

class CUserMan

{

public:

CUserMan();

virtual ~CUserMan();

BOOL AddUser(CUser &user); //添加用户 用户登陆后处理

BOOL DelUser(int UID); //删除用户 用户退出

BOOL SetUserState(int UID, int state); //设置状态

BOOL HasUser(int UID); //检测是否存在用户

 

CUser *GetUser(int UID); //得到用户信息的指针

CUser *GetUserByIndex(int index); //通过索引得到用户

CUser *GetUserByAddr(const sockaddr &addr); //通过地址得到用户信息指针

 

int GetUserID(const sockaddr &addr); //通过地址得到用户id

int GetUserCount(); //得到用户数量

// sockaddr GetUserAddr(int UID); //得到用户地址

CUserList GetUserList(int mode = 0, WPARAM wParam = 0); //根据某种条件查找用户 默认返回所有用户

void AddScore(int UID, int score);

 

 

int Pack(char *pData);

int UnPack(const char *pData);

 

// UserIDList的管理

BOOL AddUserIDList(CUserIDList *pUserIDList);

void DelUserIDList(CUserIDList *pUserIDList);

 

public:

CUserList m_userlist;

SET_CUSERIDLIST m_setUserIDList;

};

//////////////////////////////////////////////////////////////////////////

 

#endif // !defined(AFX_USERMAN_H__CCBDF347_5FBC_4D2D_A07C_C72F5A9BEEC5__INCLUDED_)

 

 

 

 

// VirtualButton.cpp: implementation of the CVirtualButton class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "VirtualButton.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CVirtualButton::CVirtualButton(): m_Rect(0, 0, 0, 0)

{

m_hwndParent = NULL;

m_ID = 0;

m_pBmp = NULL;

m_cmd = 0;

 

m_isBtnDown = FALSE;

m_isOnMove = FALSE;

}

 

CVirtualButton::CVirtualButton(const CVirtualButton & vb )

{

m_hwndParent = vb.m_hwndParent;

m_ID = vb.m_ID;

m_Rect = vb.m_Rect;

m_pBmp = vb.m_pBmp;

m_cmd = vb.m_cmd;

 

m_isBtnDown = vb.m_isBtnDown;

m_isOnMove = vb.m_isOnMove;

}

CVirtualButton::~CVirtualButton()

{

 

}

 

CVirtualButton::operator=(const CVirtualButton &vb )

{

m_hwndParent = vb.m_hwndParent;

m_ID = vb.m_ID;

m_Rect = vb.m_Rect;

m_pBmp = vb.m_pBmp;

m_cmd = vb.m_cmd;

 

m_isBtnDown = vb.m_isBtnDown;

m_isOnMove = vb.m_isOnMove;

}

 

void CVirtualButton::Create( HWND hWnd, int id, CRect &rect, CBitmap *pBmp, int cmd )

{

m_hwndParent = hWnd;

m_ID = id;

m_Rect = rect;

m_pBmp = pBmp;

m_cmd = cmd;

}

 

BOOL CVirtualButton::OnMouseMove( CPoint point )

{

if (m_Rect.PtInRect(point))

{

m_isOnMove = TRUE;

return TRUE;

}

else

{

m_isOnMove = FALSE;

return FALSE;

}

}

 

BOOL CVirtualButton::OnLButtonDown( CPoint point )

{

if (m_Rect.PtInRect(point))

{

m_isBtnDown = TRUE;

return TRUE;

}

else

{

m_isBtnDown = FALSE;

return FALSE;

}

}

 

BOOL CVirtualButton::OnLButtonUp( CPoint point )

{

int bRet = FALSE;

if (m_isBtnDown && m_Rect.PtInRect(point))

{

::SendMessage(m_hwndParent, WM_COMMAND, m_cmd, 0);

bRet = TRUE;

}

m_isBtnDown = FALSE;

return FALSE;

}

 

void CVirtualButton::OnPaint( CDC *pDestDC, CDC * pBufDC )

{

if (m_pBmp == NULL)

{

return;

}

pBufDC->SelectObject(m_pBmp);

int x = 0;

int y = 0;

 

if (m_isBtnDown)

{

x = m_Rect.Width()*2;

}

else if (m_isOnMove)

{

x = m_Rect.Width();

}

pDestDC->BitBlt(m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height(), pBufDC, x, y, SRCCOPY);

}

 

void CVirtualButton::OnMainWinKillFocus()

{

m_isBtnDown = FALSE;

m_isOnMove = FALSE;

}

 

 

 

 

// VirtualButton.h: interface for the CVirtualButton class.

// 用于游戏里的按钮绘制

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_VIRTUALBUTTON_H__4CE87721_3410_4E6D_A23A_34E894570D27__INCLUDED_)

#define AFX_VIRTUALBUTTON_H__4CE87721_3410_4E6D_A23A_34E894570D27__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CVirtualButtonMan;

 

class CVirtualButton  

{

public:

enum{

VB_NULL = 0,

VB_ONMOVE = 1,

VB_ONDOWN = 2,

VB_ONUP = 3

};

public:

CVirtualButton();

CVirtualButton(const CVirtualButton & vb);

virtual ~CVirtualButton();

void Create(HWND hWnd, int id, CRect &rect, CBitmap *pBmp, int cmd);

BOOL OnMouseMove(CPoint point);

BOOL OnLButtonDown(CPoint point);

BOOL OnLButtonUp(CPoint point);

void OnMainWinKillFocus();

 

void OnPaint(CDC *pDestDC, CDC * pBufDC);

 

operator =(const CVirtualButton &vb);

friend CVirtualButtonMan;

 

public:

HWND m_hwndParent; //主窗口句柄

int m_ID; //唯一标识

BOOL m_isBtnDown;

BOOL m_isOnMove;

CRect m_Rect; //范围

CBitmap *m_pBmp; //关联的图片

int m_cmd; //ON_COMMOND消息类型 用于向主窗口发送消息实现功能

 

};

 

#endif // !defined(AFX_VIRTUALBUTTON_H__4CE87721_3410_4E6D_A23A_34E894570D27__INCLUDED_)

 

 

 

 

//  VirtualButtonMan.cpp: implementation of the CVirtualButtonMan class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "VirtualButtonMan.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CVirtualButtonMan::CVirtualButtonMan()

{

 

}

 

CVirtualButtonMan::~CVirtualButtonMan()

{

 

}

 

void CVirtualButtonMan::AddBtn(HWND hwnd, int id, CRect &rect, CBitmap *pBmp, int cmd)

{

CVirtualButton vb;

vb.Create(hwnd, id, rect, pBmp, cmd);

m_vecVB.push_back(vb);

}

 

void CVirtualButtonMan::AddBtn( CVirtualButton &vb )

{

m_vecVB.push_back(vb);

}

 

void CVirtualButtonMan::DelBtn( int id )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->m_ID == id)

{

m_vecVB.erase(begit);

}

}

}

 

BOOL CVirtualButtonMan::OnMouseMove( CPoint &point )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->OnMouseMove(point))

{

return TRUE;

}

}

return FALSE;

}

 

BOOL CVirtualButtonMan::OnLButtonDown( CPoint point )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->OnLButtonDown(point))

{

return TRUE;

}

}

return FALSE;

}

 

BOOL CVirtualButtonMan::OnLButtonUp( CPoint point )

{

int bRet = FALSE;

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

if (begit->OnLButtonUp(point))

{

bRet = TRUE;

}

}

return bRet;

}

 

void CVirtualButtonMan::OnPaint( CDC *pDestDC, CDC *pBufDC )

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

begit->OnPaint(pDestDC, pBufDC);

}

}

 

void CVirtualButtonMan::OnMainWinKillFocus()

{

VEC_VB::iterator begit = m_vecVB.begin();

VEC_VB::iterator endit = m_vecVB.end();

 

for (;begit != endit;++begit)

{

begit->OnMainWinKillFocus();

}

}

 

 

 

// VirtualButtonMan.h: interface for the CVirtualButtonMan class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_VIRTUALBUTTONMAN_H__421D9ABF_941E_43D5_BA96_04AC043339A0__INCLUDED_)

#define AFX_VIRTUALBUTTONMAN_H__421D9ABF_941E_43D5_BA96_04AC043339A0__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "VirtualButton.h"

#include <vector>

using namespace std;

 

class CVirtualButton;

 

typedef vector<CVirtualButton> VEC_VB;

 

class CVirtualButtonMan  

{

public:

CVirtualButtonMan();

virtual ~CVirtualButtonMan();

void AddBtn(HWND hwnd, int id, CRect &rect, CBitmap *pBmp, int cmd);

void AddBtn(CVirtualButton &vb);

void DelBtn(int id);

 

BOOL OnMouseMove(CPoint &point);

BOOL OnLButtonDown(CPoint point);

BOOL OnLButtonUp(CPoint point);

void OnPaint(CDC *pDestDC, CDC *pBufDC);

void OnMainWinKillFocus();

private:

VEC_VB m_vecVB;

 

};

 

#endif // !defined(AFX_VIRTUALBUTTONMAN_H__421D9ABF_941E_43D5_BA96_04AC043339A0__INCLUDED_)

 

 

 

 

// WMLink.cpp: implementation of the CWMLink class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "WMLink.h"

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CWMLink::CWMLink()

{

m_myHwnd = NULL;

m_yourHwnd = NULL;

}

 

CWMLink::~CWMLink()

{

 

}

 

void CWMLink::Create( HWND myHwnd, HWND youHwnd )

{

m_myHwnd = myHwnd;

m_yourHwnd = youHwnd;

}

 

BOOL CWMLink::Send( DWORD nType, DWORD nSize, LPVOID pData )

{

COPYDATASTRUCT cds;

cds.dwData = nType;

cds.cbData = nSize;

cds.lpData = pData;

return ::SendMessage(m_yourHwnd, WM_COPYDATA, (WPARAM)m_myHwnd, (LPARAM)&cds);

}

 

BOOL CWMLink::Post( DWORD nType, DWORD nSize, LPVOID pData )

{

COPYDATASTRUCT cds;

cds.dwData = nType;

cds.cbData = nSize;

cds.lpData = pData;

return ::PostMessage(m_yourHwnd, WM_COPYDATA, (WPARAM)m_myHwnd, (LPARAM)&cds);

}

 

 

 

 

 

// WMLink.h: interface for the CWMLink class.

// 基于窗口的连接通讯 点对点的 方便游戏客户端有大厅通讯

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_)

#define AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

class CWMLink

{

public:

CWMLink();

virtual ~CWMLink();

virtual void Create(HWND myHwnd, HWND youHwnd);

virtual BOOL Send(DWORD nType, DWORD nSize, LPVOID pData);

virtual BOOL Post(DWORD nType, DWORD nSize, LPVOID pData);

 

virtual INT OnRecv(CWnd *pWnd, COPYDATASTRUCT *pCopyData) = 0;

 

virtual void SetMyHwnd(HWND val)

{

m_myHwnd = val;

}

virtual void SetYourHwnd(HWND val)

{

m_yourHwnd = val;

}

 

protected:

HWND m_myHwnd;

 

HWND m_yourHwnd;

};

 

#endif // !defined(AFX_WMLINK_H__CE375E9B_3E63_43C4_A1F2_A49FEE4B2D99__INCLUDED_)