#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; nIndex < BLOCK_SIZE; nIndex++) { tagDistributeNode * pNewBlock = new tagDistributeNode; pNewBlock->pNextDistributeNode = 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; nIndex < m_SameTableBuffer.GetCount(); nIndex++) { SafeDelete(m_SameTableBuffer[nIndex]); } //移除元素 m_SameTableBuffer.RemoveAll(); m_SameTableActive.RemoveAll(); } //插入结点 BOOL CDistributeManager::InsertDistributeNode(const tagDistributeInfo & DistributeInfo) { //查找用户 if (SearchNode(DistributeInfo.pIServerUserItem) != NULL) 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; 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; //安全释放 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); //获取用户 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 == 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; nIndex < m_SameTableActive.GetCount(); nIndex++) { if (m_SameTableActive[nIndex] == pSameTableInfo) { m_SameTableActive.RemoveAt(nIndex); break; } } } //查找结点 tagDistributeNode * CDistributeManager::SearchNode(const IServerUserItem * const pIServerUserItem) { if (m_pHeadNode == NULL) return NULL; //设置变量 tagDistributeNode *pMoveNode = m_pHeadNode; //查找结点 while (pMoveNode != NULL) { //接口判断 if (pMoveNode->DistributeInfo.pIServerUserItem == pIServerUserItem) return pMoveNode; //向前推进 pMoveNode = pMoveNode->pNextDistributeNode; } return NULL; } //IP同址 BOOL CDistributeManager::FilterRuleExitsIPAddr(const CDistributeInfoArray & DistributeInfoArray, DWORD dwClientAddr) { //查找同IP for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++) { if (DistributeInfoArray[nIndex].dwClientAddr == dwClientAddr) return TRUE; } return FALSE; } //机器过滤 BOOL CDistributeManager::FilterRuleIsAllAndroid(const CDistributeInfoArray & DistributeInfoArray, IServerUserItem * const pIServerUserItem) { //参数校验 if (pIServerUserItem == NULL || DistributeInfoArray.GetCount() == 0) return FALSE; //变量定义 WORD wAndroidCount = 0; //统计机器 for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++) { if (DistributeInfoArray[nIndex].pIServerUserItem->IsAndroidUser() == 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; nIndex < DistributeInfoArray.GetCount(); nIndex++) { pSameTableInfo = GetUserSameTableInfo(DistributeInfoArray[nIndex].pIServerUserItem->GetUserID()); if (pSameTableInfo != NULL) { for (WORD i = 0; i < pSameTableInfo->wPlayerCount; i++) { if (pSameTableInfo->wPlayerIDSet[i] == dwUserID) return TRUE; } } } return FALSE; } //////////////////////////////////////////////////////////////////////////////////