Files
wnmj/Servers/服务器组件/游戏服务器/DistributeManager.cpp

483 lines
11 KiB
C++
Raw Normal View History

2026-02-13 14:34:15 +08:00
#include "StdAfx.h"
#include "DistributeManager.h"
//////////////////////////////////////////////////////////////////////////////////
//<2F>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>
tagDistributeNode * CDistributeNodePool::m_pHeadOfFreeList=NULL;
const int CDistributeNodePool::BLOCK_SIZE = 20;
//////////////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
CDistributeNodePool::CDistributeNodePool()
{
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CDistributeNodePool::~CDistributeNodePool()
{
if(m_pHeadOfFreeList!=NULL)
{
tagDistributeNode * pDistributeNode=m_pHeadOfFreeList;
while(pDistributeNode!=NULL)
{
//<2F><>ȫ<EFBFBD>ͷ<EFBFBD>
m_pHeadOfFreeList = pDistributeNode->pNextDistributeNode;
SafeDelete(pDistributeNode);
pDistributeNode=m_pHeadOfFreeList;
}
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagDistributeNode * CDistributeNodePool::AllocNode()
{
//<2F><>ȡͷ<C8A1><CDB7><EFBFBD><EFBFBD>
tagDistributeNode *pDistributeNode = m_pHeadOfFreeList;
if(pDistributeNode!=NULL)
m_pHeadOfFreeList = pDistributeNode->pNextDistributeNode;
else
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
for(int nIndex=0;nIndex<BLOCK_SIZE;nIndex++)
{
tagDistributeNode * pNewBlock = new tagDistributeNode;
pNewBlock->pNextDistributeNode=m_pHeadOfFreeList;
m_pHeadOfFreeList=pNewBlock;
}
//<2F><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>
pDistributeNode = m_pHeadOfFreeList;
m_pHeadOfFreeList=pDistributeNode->pNextDistributeNode;
}
return pDistributeNode;
}
//<2F>ͷŽ<CDB7><C5BD><EFBFBD>
VOID CDistributeNodePool::FreeNode(void * pNode)
{
//<2F><EFBFBD><E9BBB9><EFBFBD><EFBFBD>
tagDistributeNode * pDeadNode = static_cast<tagDistributeNode*>(pNode);
pDeadNode->pNextDistributeNode = m_pHeadOfFreeList;
m_pHeadOfFreeList = pDeadNode;
pNode=NULL;
return;
}
//////////////////////////////////////////////////////////////////////////////////
//<2F><><EFBFBD><EFBFBD><ECBAAF>
CDistributeManager::CDistributeManager()
{
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_pHeadNode=NULL;
m_wNodeCount=0;
m_wAndroidCount=0;
m_wRealCount=0;
m_cbDistributeRule=0;
m_dwSequence = 0;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CDistributeManager::~CDistributeManager()
{
RemoveAll();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL CDistributeManager::InsertDistributeNode(const tagDistributeInfo & DistributeInfo)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>
if(SearchNode(DistributeInfo.pIServerUserItem)!=NULL) return false;
//ͷ<><CDB7><EFBFBD>ж<EFBFBD>
if(m_pHeadNode==NULL)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_pHeadNode = m_DistributeNodePool.AllocNode();
ASSERT(m_pHeadNode!=NULL);
if(m_pHeadNode==NULL) return false;
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_pHeadNode->pNextDistributeNode=NULL;
m_pHeadNode->pNextSameTableNode=NULL;
m_pHeadNode->pPrepDistributeNode=NULL;
CopyMemory(&m_pHeadNode->DistributeInfo,&DistributeInfo,sizeof(DistributeInfo));
m_pHeadNode->DistributeInfo.pPertainNode=m_pHeadNode;
m_pHeadNode->DistributeInfo.dwSequence = m_dwSequence;
}
else
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagDistributeNode * pDistributeNode = m_DistributeNodePool.AllocNode();
ASSERT(pDistributeNode!=NULL);
if(pDistributeNode==NULL) return false;
//<2F><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>
pDistributeNode->pNextDistributeNode=NULL;
pDistributeNode->pPrepDistributeNode=NULL;
pDistributeNode->pNextSameTableNode=NULL;
CopyMemory(&pDistributeNode->DistributeInfo,&DistributeInfo,sizeof(DistributeInfo));
pDistributeNode->DistributeInfo.pPertainNode=pDistributeNode;
//ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagDistributeNode * pMoveNode=NULL;
if((m_cbDistributeRule&DISTRIBUTE_LAST_TABLE)==0)
{
//<2F><><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
pMoveNode=m_pHeadNode;
while(pMoveNode!=NULL)
{
if(pMoveNode->DistributeInfo.wLastTableID==pDistributeNode->DistributeInfo.wLastTableID &&
pDistributeNode->DistributeInfo.wLastTableID!=INVALID_TABLE)
break;
pMoveNode=pMoveNode->pNextDistributeNode;
}
}
//<2F><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>
if(pMoveNode!=NULL)
{
//ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pDistributeNode->pNextSameTableNode=pMoveNode->pNextSameTableNode;
pDistributeNode->pPrepDistributeNode=pMoveNode;
pMoveNode->pNextSameTableNode=pDistributeNode;
}
else
{
//<2F><>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
if(m_pHeadNode->pNextDistributeNode!=NULL)
{
m_pHeadNode->pNextDistributeNode->pPrepDistributeNode=pDistributeNode;
pDistributeNode->pNextDistributeNode=m_pHeadNode->pNextDistributeNode;
}
pDistributeNode->pPrepDistributeNode=m_pHeadNode;
m_pHeadNode->pNextDistributeNode=pDistributeNode;
}
pDistributeNode->DistributeInfo.dwSequence = m_dwSequence;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
if (DistributeInfo.pIServerUserItem->IsAndroidUser())
{
++m_wAndroidCount;
}
else
{
++m_wRealCount;
}
++m_wNodeCount;
m_dwSequence++;
return true;
}
//<2F>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>
VOID CDistributeManager::RemoveDistributeNode(const IServerUserItem * pIServerUserItem)
{
//<2F><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD>
tagDistributeNode *pDistributeNode=SearchNode(pIServerUserItem);
if(pDistributeNode!=NULL)
RemoveDistributeNode(pDistributeNode);
return;
}
//<2F>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>
VOID CDistributeManager::RemoveDistributeNode(tagDistributeNode * pDistributeNode)
{
//<2F><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>
if(pDistributeNode==NULL) return;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagDistributeNode *pPrepNode=pDistributeNode->pPrepDistributeNode;
tagDistributeNode *pNextNode=pDistributeNode->pNextDistributeNode;
tagDistributeNode *pNextSameTableNode=pDistributeNode->pNextSameTableNode;
//ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(pPrepNode!=NULL)
{
if(pNextNode!=NULL)
{
//ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
if(pNextSameTableNode!=NULL)
{
pPrepNode->pNextDistributeNode=pNextSameTableNode;
pNextSameTableNode->pPrepDistributeNode=pPrepNode;
pNextSameTableNode->pNextDistributeNode=pNextNode;
}
else
{
pPrepNode->pNextDistributeNode=pNextNode;
pNextNode->pPrepDistributeNode=pPrepNode;
}
}
else
{
if(pNextSameTableNode!=NULL)
{
//<2F><>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
if(pPrepNode->pNextSameTableNode==pDistributeNode)
pPrepNode->pNextSameTableNode=pNextSameTableNode;
//ͬIP<49><50><EFBFBD><EFBFBD>
if(pPrepNode->pNextDistributeNode==pDistributeNode)
pPrepNode->pNextDistributeNode=pNextSameTableNode;
pNextSameTableNode->pPrepDistributeNode=pPrepNode;
}
else
{
//<2F><>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
if(pPrepNode->pNextDistributeNode==pDistributeNode)
pPrepNode->pNextDistributeNode=NULL;
//ͬIP<49><50><EFBFBD><EFBFBD>
if(pPrepNode->pNextSameTableNode==pDistributeNode)
pPrepNode->pNextSameTableNode=NULL;
}
}
}
else
{
if(pNextNode!=NULL)
{
if(pNextSameTableNode!=NULL)
{
//<2F><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>
pNextSameTableNode->pPrepDistributeNode=NULL;
pNextSameTableNode->pNextDistributeNode=pNextNode;
//<2F><><EFBFBD>ñ<EFBFBD>ͷ
m_pHeadNode=pNextSameTableNode;
}
else
{
pNextNode->pPrepDistributeNode=NULL;
//<2F><><EFBFBD>ñ<EFBFBD>ͷ
m_pHeadNode=pNextNode;
}
}
else
{
if(pNextSameTableNode!=NULL)
{
//<2F><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>
pNextSameTableNode->pPrepDistributeNode=NULL;
pNextSameTableNode->pNextDistributeNode=NULL;
//<2F><><EFBFBD>ñ<EFBFBD>ͷ
m_pHeadNode=pNextSameTableNode;
}
else
m_pHeadNode=NULL;
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
if(pDistributeNode->DistributeInfo.pIServerUserItem->IsAndroidUser())
--m_wAndroidCount;
else
--m_wRealCount;
--m_wNodeCount;
//<2F><>ȫ<EFBFBD>ͷ<EFBFBD>
m_DistributeNodePool.FreeNode(pDistributeNode);
}
//<2F>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD>
VOID CDistributeManager::RemoveAll()
{
//<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
while(m_pHeadNode!=NULL) RemoveDistributeNode(m_pHeadNode);
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
m_pHeadNode=NULL;
m_wNodeCount=0;
m_wAndroidCount=0;
m_wRealCount=0;
return;
}
//ִ<>з<EFBFBD><D0B7><EFBFBD>
WORD CDistributeManager::PerformDistribute(CDistributeInfoArray & DistributeInfoArray,WORD wNeedCount)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagDistributeNode * pMoveNode=m_pHeadNode;
if(pMoveNode!=NULL)
{
DistributeInfoArray.Add(pMoveNode->DistributeInfo);
pMoveNode=pMoveNode->pNextDistributeNode;
}
//<2F><>ȡ<EFBFBD>û<EFBFBD>
while(pMoveNode!=NULL)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL bFirstSuccess=TRUE;
//<2F>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD>
if (DistributeInfoArray.GetCount() > 0 && DistributeInfoArray[0].wDistribute != pMoveNode->DistributeInfo.wDistribute)
{
bFirstSuccess = FALSE;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (bFirstSuccess == TRUE && (DistributeInfoArray.GetCount() == wNeedCount - 1) &&
FilterRuleIsAllAndroid(DistributeInfoArray, pMoveNode->DistributeInfo.pIServerUserItem))
{
bFirstSuccess = FALSE;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҹ<EFBFBD><D2B9><EFBFBD>
if (bFirstSuccess == TRUE && (m_cbDistributeRule&DISTRIBUTE_ADJACENT) == 0 &&
FilterRuleAdjacent(DistributeInfoArray, pMoveNode->DistributeInfo.dwSequence))
{
bFirstSuccess = FALSE;
}
//ͬIP<49><50><EFBFBD><EFBFBD>
if(bFirstSuccess==TRUE && (m_cbDistributeRule&DISTRIBUTE_SAME_ADDRESS)==0 &&
FilterRuleExitsIPAddr(DistributeInfoArray,pMoveNode->DistributeInfo.dwClientAddr)==TRUE)
{
bFirstSuccess=FALSE;
//<2F><><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagDistributeNode * pSameTableNode=pMoveNode->pNextSameTableNode;
while(pSameTableNode!=NULL)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL bSecondSuccess=TRUE;
//<2F>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD>
if (DistributeInfoArray.GetCount() > 0 && DistributeInfoArray[0].wDistribute != pMoveNode->DistributeInfo.wDistribute)
{
bSecondSuccess = FALSE;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (bFirstSuccess == TRUE && (DistributeInfoArray.GetCount() == wNeedCount - 1) &&
FilterRuleIsAllAndroid(DistributeInfoArray, pSameTableNode->DistributeInfo.pIServerUserItem))
{
bFirstSuccess = FALSE;
}
//ͬIP<49><50><EFBFBD><EFBFBD>
if (bSecondSuccess == TRUE && FilterRuleExitsIPAddr(DistributeInfoArray, pMoveNode->DistributeInfo.dwClientAddr) == TRUE)
{
bSecondSuccess = FALSE;
}
//<2F><>ȡ<EFBFBD>ɹ<EFBFBD>
if(bSecondSuccess==TRUE)
{
DistributeInfoArray.Add(pMoveNode->DistributeInfo);
break;
}
pSameTableNode=pSameTableNode->pNextSameTableNode;
}
}
//<2F><>ȡ<EFBFBD>ɹ<EFBFBD>
if(bFirstSuccess==TRUE) DistributeInfoArray.Add(pMoveNode->DistributeInfo);
//<2F><>ǰ<EFBFBD>ƽ<EFBFBD>
pMoveNode=pMoveNode->pNextDistributeNode;
//<2F>ɹ<EFBFBD><C9B9>ж<EFBFBD>
if(DistributeInfoArray.GetCount()==wNeedCount) break;
}
return (WORD)DistributeInfoArray.GetCount();
}
//<2F><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD>
tagDistributeNode * CDistributeManager::SearchNode(const IServerUserItem * const pIServerUserItem)
{
if(m_pHeadNode==NULL) return NULL;
//<2F><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD>
tagDistributeNode *pMoveNode=m_pHeadNode;
tagDistributeNode *pNextSameTableNode=NULL;
//<2F><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD>
while(pMoveNode!=NULL)
{
pNextSameTableNode=pMoveNode;
while(pNextSameTableNode!=NULL)
{
//<2F>ӿ<EFBFBD><D3BF>ж<EFBFBD>
if(pNextSameTableNode->DistributeInfo.pIServerUserItem==pIServerUserItem)
return pNextSameTableNode;
//<2F><>ǰ<EFBFBD>ƽ<EFBFBD>
pNextSameTableNode=pNextSameTableNode->pNextSameTableNode;
}
//<2F><>ǰ<EFBFBD>ƽ<EFBFBD>
pMoveNode=pMoveNode->pNextDistributeNode;
}
return NULL;
}
//IPַͬ
BOOL CDistributeManager::FilterRuleExitsIPAddr(const CDistributeInfoArray & DistributeInfoArray,DWORD dwClientAddr)
{
//<2F><><EFBFBD><EFBFBD>ͬIP
for(INT_PTR nIndex=0;nIndex<DistributeInfoArray.GetCount();nIndex++)
{
if(DistributeInfoArray[nIndex].dwClientAddr==dwClientAddr)
return TRUE;
}
return FALSE;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL CDistributeManager::FilterRuleIsAllAndroid(const CDistributeInfoArray & DistributeInfoArray,IServerUserItem * const pIServerUserItem)
{
//<2F><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>
if(pIServerUserItem==NULL || DistributeInfoArray.GetCount()==0) return FALSE;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
WORD wAndroidCount=0;
//ͳ<>ƻ<EFBFBD><C6BB><EFBFBD>
for(INT_PTR nIndex=0;nIndex<DistributeInfoArray.GetCount();nIndex++)
{
if(DistributeInfoArray[nIndex].pIServerUserItem->IsAndroidUser()==true)
++wAndroidCount;
}
return (wAndroidCount==DistributeInfoArray.GetCount()) && pIServerUserItem->IsAndroidUser();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL CDistributeManager::FilterRuleAdjacent(const CDistributeInfoArray & DistributeInfoArray, DWORD dwSequence)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++)
{
tagDistributeInfo distributeInfo = DistributeInfoArray[nIndex];
if ((distributeInfo.dwSequence == dwSequence + 1) || (distributeInfo.dwSequence == dwSequence - 1))
{
return TRUE;
}
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////////////////