#include "StdAfx.h" #include "DistributeManager.h" ////////////////////////////////////////////////////////////////////////////////// //内存管理 tagDistributeNode * CDistributeNodePool::m_pHeadOfFreeList=NULL; const int CDistributeNodePool::BLOCK_SIZE = 20; //常量定义 #define DISTRIBUTE_WAIT_TIMESTAMP 10 //等待时间戳 ////////////////////////////////////////////////////////////////////////////////// //构造函数 CDistributeNodePool::CDistributeNodePool() { } //析构函数 CDistributeNodePool::~CDistributeNodePool() { if(m_pHeadOfFreeList!=NULL) { tagDistributeNode * pDistributeNode=m_pHeadOfFreeList; while(pDistributeNode!=NULL) { //安全释放 m_pHeadOfFreeList = pDistributeNode->pNextDistributeNode; SafeDelete(pDistributeNode); pDistributeNode=m_pHeadOfFreeList; } } } //分配结点 tagDistributeNode * CDistributeNodePool::AllocNode() { //获取头结点 tagDistributeNode *pDistributeNode = m_pHeadOfFreeList; if(pDistributeNode!=NULL) m_pHeadOfFreeList = pDistributeNode->pNextDistributeNode; else { //分配大块内存 for(int nIndex=0;nIndexpNextDistributeNode=m_pHeadOfFreeList; m_pHeadOfFreeList=pNewBlock; } //设置结点 pDistributeNode = m_pHeadOfFreeList; m_pHeadOfFreeList=pDistributeNode->pNextDistributeNode; } return pDistributeNode; } //释放结点 VOID CDistributeNodePool::FreeNode(void * pNode) { //归还结点 tagDistributeNode * pDeadNode = static_cast(pNode); pDeadNode->pNextDistributeNode = m_pHeadOfFreeList; m_pHeadOfFreeList = pDeadNode; pNode=NULL; return; } ////////////////////////////////////////////////////////////////////////////////// //构造函数 CDistributeManager::CDistributeManager() { //设置变量 m_pHeadNode=NULL; m_wNodeCount=0; m_wAndroidCount=0; m_wRealCount=0; m_cbDistributeRule=0; //设置字典 m_SameTableMap.InitHashTable(10003); } //析构函数 CDistributeManager::~CDistributeManager() { //移除节点 RemoveAll(); //释放对象 m_SameTableBuffer.Append(m_SameTableActive); for(INT_PTR nIndex=0;nIndexGetNickName(), pMeServerUserItem->GetUserStatus(), m_wAndroidCount, m_wRealCount, m_wNodeCount); CTraceService::TraceString(szDescribe, TraceLevel_Warning); #endif return true; } //头部判断 if(m_pHeadNode==NULL) { //分配结点 m_pHeadNode = m_DistributeNodePool.AllocNode(); ASSERT(m_pHeadNode!=NULL); if(m_pHeadNode==NULL) return false; //设置变量 m_pHeadNode->pNextDistributeNode=NULL; m_pHeadNode->pPrepDistributeNode=NULL; CopyMemory(&m_pHeadNode->DistributeInfo,&DistributeInfo,sizeof(DistributeInfo)); m_pHeadNode->DistributeInfo.pPertainNode=m_pHeadNode; } else { //分配结点 tagDistributeNode * pDistributeNode = m_DistributeNodePool.AllocNode(); ASSERT(pDistributeNode!=NULL); if(pDistributeNode==NULL) return false; //设置结点 pDistributeNode->pNextDistributeNode=NULL; pDistributeNode->pPrepDistributeNode=NULL; CopyMemory(&pDistributeNode->DistributeInfo,&DistributeInfo,sizeof(DistributeInfo)); pDistributeNode->DistributeInfo.pPertainNode=pDistributeNode; //表头结点 if(m_pHeadNode->pNextDistributeNode!=NULL) { m_pHeadNode->pNextDistributeNode->pPrepDistributeNode=pDistributeNode; pDistributeNode->pNextDistributeNode=m_pHeadNode->pNextDistributeNode; } pDistributeNode->pPrepDistributeNode=m_pHeadNode; m_pHeadNode->pNextDistributeNode=pDistributeNode; } //更新数目 if(DistributeInfo.pIServerUserItem->IsAndroidUser()) ++m_wAndroidCount; else ++m_wRealCount; ++m_wNodeCount; // 日志; #if _DEBUG IServerUserItem* pMeServerUserItem = DistributeInfo.pIServerUserItem; //构造提示; TCHAR szDescribe[128] = TEXT(""); _sntprintf_s(szDescribe, CountArray(szDescribe), TEXT("player [%s] InsertDistributeNode, GetUserStatus:[%d]. m_wAndroidCount=%d, m_wRealCount=%d, m_wNodeCount=%d."), pMeServerUserItem->GetNickName(), pMeServerUserItem->GetUserStatus(), m_wAndroidCount, m_wRealCount, m_wNodeCount); CTraceService::TraceString(szDescribe, TraceLevel_Warning); #endif return true; } //移除结点 VOID CDistributeManager::RemoveDistributeNode(const IServerUserItem * pIServerUserItem) { //查找结点 tagDistributeNode *pDistributeNode=SearchNode(pIServerUserItem); if(pDistributeNode!=NULL) RemoveDistributeNode(pDistributeNode); return; } //移除结点 VOID CDistributeManager::RemoveDistributeNode(tagDistributeNode * pDistributeNode) { //参数校验 if(pDistributeNode==NULL) return; //查找用户 if(SearchNode(pDistributeNode->DistributeInfo.pIServerUserItem)==NULL) return; //变量定义 tagDistributeNode *pPrepNode=pDistributeNode->pPrepDistributeNode; tagDistributeNode *pNextNode=pDistributeNode->pNextDistributeNode; //删除结点 if(pPrepNode!=NULL) { if(pNextNode!=NULL) { pPrepNode->pNextDistributeNode=pNextNode; pNextNode->pPrepDistributeNode=pPrepNode; } else { //表头链接 if(pPrepNode->pNextDistributeNode==pDistributeNode) pPrepNode->pNextDistributeNode=NULL; } } else { if(pNextNode!=NULL) { pNextNode->pPrepDistributeNode=NULL; //重置表头 m_pHeadNode=pNextNode; } else { m_pHeadNode=NULL; } } //更新数目 if(pDistributeNode->DistributeInfo.pIServerUserItem->IsAndroidUser()) --m_wAndroidCount; else --m_wRealCount; --m_wNodeCount; // 日志; #if _DEBUG IServerUserItem* pMeServerUserItem = pDistributeNode->DistributeInfo.pIServerUserItem; //构造提示; TCHAR szDescribe[128] = TEXT(""); _sntprintf_s(szDescribe, CountArray(szDescribe), TEXT("player [%s] RemoveDistributeNode, GetUserStatus:[%d]. m_wAndroidCount=%d, m_wRealCount=%d, m_wNodeCount=%d."), pMeServerUserItem->GetNickName(), pMeServerUserItem->GetUserStatus(), m_wAndroidCount, m_wRealCount, m_wNodeCount); CTraceService::TraceString(szDescribe, TraceLevel_Warning); #endif //安全释放 m_DistributeNodePool.FreeNode(pDistributeNode); } //移除结点 VOID CDistributeManager::RemoveAll() { //释放内存 while(m_pHeadNode!=NULL) RemoveDistributeNode(m_pHeadNode); //重置变量 m_pHeadNode=NULL; m_wNodeCount=0; m_wAndroidCount=0; m_wRealCount=0; return; } //执行分组 WORD CDistributeManager::PerformDistribute(CDistributeInfoArray & DistributeInfoArray,WORD wNeedCount) { //定义变量 tagDistributeNode * pMoveNode=NULL; tagDistributeNode * pMoveStartNode=NULL; if(m_pHeadNode!=NULL && m_wNodeCount>1) { pMoveNode = m_pHeadNode; WORD wRandNodeIndex=rand()%m_wNodeCount; while(wRandNodeIndex-->0) { if(pMoveNode==NULL) { pMoveNode = m_pHeadNode; break; } pMoveNode = pMoveNode->pNextDistributeNode; } //设置变量 if(pMoveNode!=NULL) pMoveStartNode = pMoveNode; } // if(pMoveNode==NULL) return 0; //获取时间戳 DWORD dwCurrentStamp = (DWORD)time(NULL); //先让正常玩家组队; bool bAllRealPlayer = (m_wRealCount >= wNeedCount); WORD wNeedAndroidNum = 0; if (!bAllRealPlayer) { wNeedAndroidNum = wNeedCount - m_wRealCount; } //找出正在玩家; do { //定义变量 BOOL bFirstSuccess = TRUE; //等待时间 if (dwCurrentStamp - pMoveNode->DistributeInfo.dwInsertStamp < DISTRIBUTE_WAIT_TIMESTAMP) bFirstSuccess = FALSE; //机器人过滤; IServerUserItem * pIServerUserItem = pMoveNode->DistributeInfo.pIServerUserItem; if (pIServerUserItem->IsAndroidUser() == true) break; //等级过滤 if (DistributeInfoArray.GetCount() > 0 && DistributeInfoArray[0].wDistribute != pMoveNode->DistributeInfo.wDistribute) bFirstSuccess = FALSE; //机器过滤 if (bFirstSuccess == TRUE && DistributeInfoArray.GetCount() == wNeedCount - 1 && FilterRuleIsAllAndroid(DistributeInfoArray, pMoveNode->DistributeInfo.pIServerUserItem)) bFirstSuccess = FALSE; //同IP过滤 if (bFirstSuccess == TRUE && (m_cbDistributeRule&DISTRIBUTE_SAME_ADDRESS) == 0 && FilterRuleExitsIPAddr(DistributeInfoArray, pMoveNode->DistributeInfo.dwClientAddr) == TRUE) bFirstSuccess = FALSE; //同桌过滤 if (bFirstSuccess == TRUE && (m_cbDistributeRule&DISTRIBUTE_LAST_TABLE) == 0 && FilterRuleIsLastSameTable(DistributeInfoArray, pMoveNode->DistributeInfo.pIServerUserItem->GetUserID()) == TRUE) bFirstSuccess = FALSE; //获取成功 if (bFirstSuccess == TRUE) DistributeInfoArray.Add(pMoveNode->DistributeInfo); //向前推进 pMoveNode = pMoveNode->pNextDistributeNode; if (pMoveNode == NULL) pMoveNode = m_pHeadNode; //成功判断 if (DistributeInfoArray.GetCount() >= wNeedCount) break; } while (pMoveNode && pMoveNode != pMoveStartNode); //成功判断 if (DistributeInfoArray.GetCount() >= wNeedCount) { return (WORD)DistributeInfoArray.GetCount(); } //获取用户; do { //定义变量 BOOL bFirstSuccess=TRUE; //等待时间 if(dwCurrentStamp-pMoveNode->DistributeInfo.dwInsertStamp< DISTRIBUTE_WAIT_TIMESTAMP) bFirstSuccess=FALSE; //等级过滤 if(DistributeInfoArray.GetCount()>0 && DistributeInfoArray[0].wDistribute!=pMoveNode->DistributeInfo.wDistribute) bFirstSuccess=FALSE; //机器人过滤;(先让真正的玩家匹配); if (bFirstSuccess && bAllRealPlayer && (pMoveNode->DistributeInfo.pIServerUserItem != NULL) && pMoveNode->DistributeInfo.pIServerUserItem->IsAndroidUser()) bFirstSuccess = FALSE; if (bFirstSuccess && !bAllRealPlayer && GetAndroidNum(DistributeInfoArray) >= wNeedAndroidNum ) { bFirstSuccess = FALSE; bAllRealPlayer = true; wNeedAndroidNum = 0; } //机器过滤 if(bFirstSuccess==TRUE && DistributeInfoArray.GetCount()==wNeedCount-1 && FilterRuleIsAllAndroid(DistributeInfoArray,pMoveNode->DistributeInfo.pIServerUserItem)) bFirstSuccess=FALSE; //同IP过滤 if(bFirstSuccess==TRUE && (m_cbDistributeRule&DISTRIBUTE_SAME_ADDRESS)==0 && FilterRuleExitsIPAddr(DistributeInfoArray,pMoveNode->DistributeInfo.dwClientAddr)==TRUE) bFirstSuccess=FALSE; //同桌过滤 if(bFirstSuccess==TRUE && (m_cbDistributeRule&DISTRIBUTE_LAST_TABLE)==0 && FilterRuleIsLastSameTable(DistributeInfoArray,pMoveNode->DistributeInfo.pIServerUserItem->GetUserID())==TRUE) bFirstSuccess=FALSE; //获取成功 if(bFirstSuccess==TRUE) DistributeInfoArray.Add(pMoveNode->DistributeInfo); //向前推进 pMoveNode=pMoveNode->pNextDistributeNode; if(pMoveNode==NULL) pMoveNode = m_pHeadNode; //成功判断 if(DistributeInfoArray.GetCount()==wNeedCount) break; }while(pMoveNode && pMoveNode!=pMoveStartNode); return (WORD)DistributeInfoArray.GetCount(); } //获取信息 tagSameTableInfo * CDistributeManager::GetUserSameTableInfo(DWORD dwUserID) { //变量定义 tagSameTableInfo * pSameTableInfo; if(m_SameTableMap.Lookup(dwUserID,pSameTableInfo)==FALSE) { pSameTableInfo = ActiveSameTableInfo(); m_SameTableMap[dwUserID] = pSameTableInfo; } return pSameTableInfo; } //移除信息 VOID CDistributeManager::RemoveUserSameTableInfo(DWORD dwUserID) { //变量定义 tagSameTableInfo * pSameTableInfo; if(m_SameTableMap.Lookup(dwUserID,pSameTableInfo)==TRUE) { //移除信息 m_SameTableMap.RemoveKey(dwUserID); RemoveSameTableInfo(pSameTableInfo); } } //激活对象 tagSameTableInfo * CDistributeManager::ActiveSameTableInfo() { //查找缓冲 if(m_SameTableBuffer.GetCount()>0) { tagSameTableInfo * pSameTableInfo = m_SameTableBuffer.GetAt(0); m_SameTableBuffer.RemoveAt(0); m_SameTableActive.Add(pSameTableInfo); return pSameTableInfo; } //创建对象 try { //创建对象 tagSameTableInfo * pSameTableInfo = new tagSameTableInfo; if(pSameTableInfo==NULL) throw(TEXT("内存不足,对象创建失败!")); //设置对象 ZeroMemory(pSameTableInfo,sizeof(tagSameTableInfo)); m_SameTableActive.Add(pSameTableInfo); return pSameTableInfo; } catch(...) { ASSERT(FALSE); } return NULL; } //移除对象 VOID CDistributeManager::RemoveSameTableInfo(tagSameTableInfo * pSameTableInfo) { ZeroMemory(pSameTableInfo,sizeof(tagSameTableInfo)); m_SameTableBuffer.Add(pSameTableInfo); //查找对象 for(INT_PTR nIndex=0;nIndexDistributeInfo.pIServerUserItem==pIServerUserItem) return pMoveNode; //向前推进 pMoveNode=pMoveNode->pNextDistributeNode; } return NULL; } //IP同址 BOOL CDistributeManager::FilterRuleExitsIPAddr(const CDistributeInfoArray & DistributeInfoArray,DWORD dwClientAddr) { //查找同IP for(INT_PTR nIndex=0;nIndexIsAndroidUser()==true) ++wAndroidCount; } return (wAndroidCount==DistributeInfoArray.GetCount()) && pIServerUserItem->IsAndroidUser(); } //上局同桌 BOOL CDistributeManager::FilterRuleIsLastSameTable(const CDistributeInfoArray & DistributeInfoArray,DWORD dwUserID) { //参数校验 if(DistributeInfoArray.GetCount()==0) return FALSE; //变量定义 tagSameTableInfo * pSameTableInfo=NULL; for(INT_PTR nIndex=0;nIndexGetUserID()); if(pSameTableInfo!=NULL) { for(WORD i=0;iwPlayerCount;i++) { if(pSameTableInfo->wPlayerIDSet[i]==dwUserID) return TRUE; } } } return FALSE; } WORD CDistributeManager::GetAndroidNum(const CDistributeInfoArray & DistributeInfoArray) { //变量定义; WORD wAndroidCount = 0; INT_PTR nSize = DistributeInfoArray.GetCount(); //统计机器 for (INT_PTR nIndex = 0; nIndex < nSize; nIndex++) { if (DistributeInfoArray[nIndex].pIServerUserItem->IsAndroidUser() == true) ++wAndroidCount; } return wAndroidCount; } //////////////////////////////////////////////////////////////////////////////////