团队项目
2016-05-20 12:09 萝卜占坑一蹲一坑 阅读(14086) 评论(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++是一个功能强大的可视化软件开发工具。自1993年Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。虽然微软公司推出了 Visual C++.NET(Visual C++7.0),但它的应用有很大的局限性,只适用于Windows 2000、Windows XP和Windows NT4.0。所以实际中,更多的是以Visual C++6.0为平台。
Visual C++6.0由Microsoft开发, 它不仅是一个C++ 编译器,而且是一个基于Windows操作系统的可视化集成开发环境(integrated development environment,IDE)。Visual C++6.0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导Class Wizard等开发工具。 这些组件通过一个名为Developer Studio的组件集成为和谐的开发环境。Microsoft的主力软件产品。Visual C++是一个功能强大的可视化软件开发工具。自1993年Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。虽然微软公司推出了Visual C++.NET(Visual C++7.0),但它的应用的很大的局限性,只适用于Windows 2000,Windows XP和Windows NT4.0。所以实际中,更多的是以Visual C++6.0为平台。
Visual C++6.0以拥有“语法高亮”,自动编译功能以及高级除错功能而著称。比如,它允许用户进行远程调试,单步执行等。还有允许用户在调试期间重新编译被修改的代码,而不必重新启动正在调试的程序。其编译及创建预编译头文件(stdafx.h)、最小重建功能及累加连结(link)著称。这些特征明显缩短程序编辑、编译及连结的时间花费,在大型软件计划上尤其显著。
1.2 MFC
MFC:MFC是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数,VC++是微软公司开发的c/c++的集成开发环境。
从理论上来讲,MFC也不是专用于Visual C++,Borland C++,C++Builder和Symantec C++同样可以处理MFC。同时,用Visual C++编写代码也并不意味着一定要用MFC,只要愿意,用Visual C++来编写SDK程序,或者使用STL,ATL,一样没有限制。不过,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);
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 将SOCKET与IOCP绑定
// 参数: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.
// 对完成端口的封装
/* 类说明
2009年7月19日版本
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_)