诸暨麻将添加redis
您不能選擇超過 %s 個話題 話題必須以字母或數字為開頭,可包含連接號 ('-') 且最長為 35 個字
 
 
 
 
 
 

472 行
13 KiB

  1. #include "StdAfx.h"
  2. #include "DistributeManager.h"
  3. //////////////////////////////////////////////////////////////////////////////////
  4. //内存管理
  5. tagDistributeNode * CDistributeNodePool::m_pHeadOfFreeList = NULL;
  6. const int CDistributeNodePool::BLOCK_SIZE = 20;
  7. //常量定义
  8. #define DISTRIBUTE_WAIT_TIMESTAMP 10 //等待时间戳
  9. //////////////////////////////////////////////////////////////////////////////////
  10. //构造函数
  11. CDistributeNodePool::CDistributeNodePool()
  12. {
  13. }
  14. //析构函数
  15. CDistributeNodePool::~CDistributeNodePool()
  16. {
  17. if (m_pHeadOfFreeList != NULL)
  18. {
  19. tagDistributeNode * pDistributeNode = m_pHeadOfFreeList;
  20. while (pDistributeNode != NULL)
  21. {
  22. //安全释放
  23. m_pHeadOfFreeList = pDistributeNode->pNextDistributeNode;
  24. SafeDelete(pDistributeNode);
  25. pDistributeNode = m_pHeadOfFreeList;
  26. }
  27. }
  28. }
  29. //分配结点
  30. tagDistributeNode * CDistributeNodePool::AllocNode()
  31. {
  32. //获取头结点
  33. tagDistributeNode *pDistributeNode = m_pHeadOfFreeList;
  34. if (pDistributeNode != NULL)
  35. m_pHeadOfFreeList = pDistributeNode->pNextDistributeNode;
  36. else
  37. {
  38. //分配大块内存
  39. for (int nIndex = 0; nIndex < BLOCK_SIZE; nIndex++)
  40. {
  41. tagDistributeNode * pNewBlock = new tagDistributeNode;
  42. pNewBlock->pNextDistributeNode = m_pHeadOfFreeList;
  43. m_pHeadOfFreeList = pNewBlock;
  44. }
  45. //设置结点
  46. pDistributeNode = m_pHeadOfFreeList;
  47. m_pHeadOfFreeList = pDistributeNode->pNextDistributeNode;
  48. }
  49. return pDistributeNode;
  50. }
  51. //释放结点
  52. VOID CDistributeNodePool::FreeNode(void * pNode)
  53. {
  54. //归还结点
  55. tagDistributeNode * pDeadNode = static_cast<tagDistributeNode*>(pNode);
  56. pDeadNode->pNextDistributeNode = m_pHeadOfFreeList;
  57. m_pHeadOfFreeList = pDeadNode;
  58. pNode = NULL;
  59. return;
  60. }
  61. //////////////////////////////////////////////////////////////////////////////////
  62. //构造函数
  63. CDistributeManager::CDistributeManager()
  64. {
  65. //设置变量
  66. m_pHeadNode = NULL;
  67. m_wNodeCount = 0;
  68. m_wAndroidCount = 0;
  69. m_wRealCount = 0;
  70. m_cbDistributeRule = 0;
  71. //设置字典
  72. m_SameTableMap.InitHashTable(10003);
  73. }
  74. //析构函数
  75. CDistributeManager::~CDistributeManager()
  76. {
  77. //移除节点
  78. RemoveAll();
  79. //释放对象
  80. m_SameTableBuffer.Append(m_SameTableActive);
  81. for (INT_PTR nIndex = 0; nIndex < m_SameTableBuffer.GetCount(); nIndex++)
  82. {
  83. SafeDelete(m_SameTableBuffer[nIndex]);
  84. }
  85. //移除元素
  86. m_SameTableBuffer.RemoveAll();
  87. m_SameTableActive.RemoveAll();
  88. }
  89. //插入结点
  90. BOOL CDistributeManager::InsertDistributeNode(const tagDistributeInfo & DistributeInfo)
  91. {
  92. //查找用户
  93. if (SearchNode(DistributeInfo.pIServerUserItem) != NULL) return true;
  94. //头部判断
  95. if (m_pHeadNode == NULL)
  96. {
  97. //分配结点
  98. m_pHeadNode = m_DistributeNodePool.AllocNode();
  99. ASSERT(m_pHeadNode != NULL);
  100. if (m_pHeadNode == NULL) return false;
  101. //设置变量
  102. m_pHeadNode->pNextDistributeNode = NULL;
  103. m_pHeadNode->pPrepDistributeNode = NULL;
  104. CopyMemory(&m_pHeadNode->DistributeInfo, &DistributeInfo, sizeof(DistributeInfo));
  105. m_pHeadNode->DistributeInfo.pPertainNode = m_pHeadNode;
  106. }
  107. else
  108. {
  109. //分配结点
  110. tagDistributeNode * pDistributeNode = m_DistributeNodePool.AllocNode();
  111. ASSERT(pDistributeNode != NULL);
  112. if (pDistributeNode == NULL) return false;
  113. //设置结点
  114. pDistributeNode->pNextDistributeNode = NULL;
  115. pDistributeNode->pPrepDistributeNode = NULL;
  116. CopyMemory(&pDistributeNode->DistributeInfo, &DistributeInfo, sizeof(DistributeInfo));
  117. pDistributeNode->DistributeInfo.pPertainNode = pDistributeNode;
  118. //表头结点
  119. if (m_pHeadNode->pNextDistributeNode != NULL)
  120. {
  121. m_pHeadNode->pNextDistributeNode->pPrepDistributeNode = pDistributeNode;
  122. pDistributeNode->pNextDistributeNode = m_pHeadNode->pNextDistributeNode;
  123. }
  124. pDistributeNode->pPrepDistributeNode = m_pHeadNode;
  125. m_pHeadNode->pNextDistributeNode = pDistributeNode;
  126. }
  127. //更新数目
  128. if (DistributeInfo.pIServerUserItem->IsAndroidUser())
  129. ++m_wAndroidCount;
  130. else
  131. ++m_wRealCount;
  132. ++m_wNodeCount;
  133. return true;
  134. }
  135. //移除结点
  136. VOID CDistributeManager::RemoveDistributeNode(const IServerUserItem * pIServerUserItem)
  137. {
  138. //查找结点
  139. tagDistributeNode *pDistributeNode = SearchNode(pIServerUserItem);
  140. if (pDistributeNode != NULL)
  141. RemoveDistributeNode(pDistributeNode);
  142. return;
  143. }
  144. //移除结点
  145. VOID CDistributeManager::RemoveDistributeNode(tagDistributeNode * pDistributeNode)
  146. {
  147. //参数校验
  148. if (pDistributeNode == NULL) return;
  149. //查找用户
  150. if (SearchNode(pDistributeNode->DistributeInfo.pIServerUserItem) == NULL) return;
  151. //变量定义
  152. tagDistributeNode *pPrepNode = pDistributeNode->pPrepDistributeNode;
  153. tagDistributeNode *pNextNode = pDistributeNode->pNextDistributeNode;
  154. //删除结点
  155. if (pPrepNode != NULL)
  156. {
  157. if (pNextNode != NULL)
  158. {
  159. pPrepNode->pNextDistributeNode = pNextNode;
  160. pNextNode->pPrepDistributeNode = pPrepNode;
  161. }
  162. else
  163. {
  164. //表头链接
  165. if (pPrepNode->pNextDistributeNode == pDistributeNode)
  166. pPrepNode->pNextDistributeNode = NULL;
  167. }
  168. }
  169. else
  170. {
  171. if (pNextNode != NULL)
  172. {
  173. pNextNode->pPrepDistributeNode = NULL;
  174. //重置表头
  175. m_pHeadNode = pNextNode;
  176. }
  177. else
  178. {
  179. m_pHeadNode = NULL;
  180. }
  181. }
  182. //更新数目
  183. if (pDistributeNode->DistributeInfo.pIServerUserItem->IsAndroidUser())
  184. --m_wAndroidCount;
  185. else
  186. --m_wRealCount;
  187. --m_wNodeCount;
  188. //安全释放
  189. m_DistributeNodePool.FreeNode(pDistributeNode);
  190. }
  191. //移除结点
  192. VOID CDistributeManager::RemoveAll()
  193. {
  194. //释放内存
  195. while (m_pHeadNode != NULL) RemoveDistributeNode(m_pHeadNode);
  196. //重置变量
  197. m_pHeadNode = NULL;
  198. m_wNodeCount = 0;
  199. m_wAndroidCount = 0;
  200. m_wRealCount = 0;
  201. return;
  202. }
  203. //执行分组
  204. WORD CDistributeManager::PerformDistribute(CDistributeInfoArray & DistributeInfoArray, WORD wNeedCount)
  205. {
  206. //定义变量
  207. tagDistributeNode * pMoveNode = NULL;
  208. tagDistributeNode * pMoveStartNode = NULL;
  209. if (m_pHeadNode != NULL && m_wNodeCount > 1)
  210. {
  211. pMoveNode = m_pHeadNode;
  212. WORD wRandNodeIndex = rand() % m_wNodeCount;
  213. while (wRandNodeIndex-- > 0)
  214. {
  215. if (pMoveNode == NULL)
  216. {
  217. pMoveNode = m_pHeadNode;
  218. break;
  219. }
  220. pMoveNode = pMoveNode->pNextDistributeNode;
  221. }
  222. //设置变量
  223. if (pMoveNode != NULL) pMoveStartNode = pMoveNode;
  224. }
  225. //
  226. if (pMoveNode == NULL) return 0;
  227. //获取时间戳
  228. DWORD dwCurrentStamp = (DWORD)time(NULL);
  229. //获取用户
  230. do
  231. {
  232. //定义变量
  233. BOOL bFirstSuccess = TRUE;
  234. //等待时间
  235. if (dwCurrentStamp - pMoveNode->DistributeInfo.dwInsertStamp< DISTRIBUTE_WAIT_TIMESTAMP)
  236. bFirstSuccess = FALSE;
  237. //等级过滤
  238. if (DistributeInfoArray.GetCount()>0 && DistributeInfoArray[0].wDistribute != pMoveNode->DistributeInfo.wDistribute)
  239. bFirstSuccess = FALSE;
  240. //机器过滤
  241. if (bFirstSuccess == TRUE && DistributeInfoArray.GetCount() == wNeedCount - 1 &&
  242. FilterRuleIsAllAndroid(DistributeInfoArray, pMoveNode->DistributeInfo.pIServerUserItem))
  243. bFirstSuccess = FALSE;
  244. //同IP过滤
  245. if (bFirstSuccess == TRUE && (m_cbDistributeRule&DISTRIBUTE_SAME_ADDRESS) == 0 &&
  246. FilterRuleExitsIPAddr(DistributeInfoArray, pMoveNode->DistributeInfo.dwClientAddr) == TRUE)
  247. bFirstSuccess = FALSE;
  248. //同桌过滤
  249. if (bFirstSuccess == TRUE && (m_cbDistributeRule&DISTRIBUTE_LAST_TABLE) == 0 &&
  250. FilterRuleIsLastSameTable(DistributeInfoArray, pMoveNode->DistributeInfo.pIServerUserItem->GetUserID()) == TRUE)
  251. bFirstSuccess = FALSE;
  252. //获取成功
  253. if (bFirstSuccess == TRUE) DistributeInfoArray.Add(pMoveNode->DistributeInfo);
  254. //向前推进
  255. pMoveNode = pMoveNode->pNextDistributeNode;
  256. if (pMoveNode == NULL) pMoveNode = m_pHeadNode;
  257. //成功判断
  258. if (DistributeInfoArray.GetCount() == wNeedCount) break;
  259. } while (pMoveNode && pMoveNode != pMoveStartNode);
  260. return (WORD)DistributeInfoArray.GetCount();
  261. }
  262. //获取信息
  263. tagSameTableInfo * CDistributeManager::GetUserSameTableInfo(DWORD dwUserID)
  264. {
  265. //变量定义
  266. tagSameTableInfo * pSameTableInfo;
  267. if (m_SameTableMap.Lookup(dwUserID, pSameTableInfo) == FALSE)
  268. {
  269. pSameTableInfo = ActiveSameTableInfo();
  270. m_SameTableMap[dwUserID] = pSameTableInfo;
  271. }
  272. return pSameTableInfo;
  273. }
  274. //移除信息
  275. VOID CDistributeManager::RemoveUserSameTableInfo(DWORD dwUserID)
  276. {
  277. //变量定义
  278. tagSameTableInfo * pSameTableInfo;
  279. if (m_SameTableMap.Lookup(dwUserID, pSameTableInfo) == TRUE)
  280. {
  281. //移除信息
  282. m_SameTableMap.RemoveKey(dwUserID);
  283. RemoveSameTableInfo(pSameTableInfo);
  284. }
  285. }
  286. //激活对象
  287. tagSameTableInfo * CDistributeManager::ActiveSameTableInfo()
  288. {
  289. //查找缓冲
  290. if (m_SameTableBuffer.GetCount() > 0)
  291. {
  292. tagSameTableInfo * pSameTableInfo = m_SameTableBuffer.GetAt(0);
  293. m_SameTableBuffer.RemoveAt(0);
  294. m_SameTableActive.Add(pSameTableInfo);
  295. return pSameTableInfo;
  296. }
  297. //创建对象
  298. try
  299. {
  300. //创建对象
  301. tagSameTableInfo * pSameTableInfo = new tagSameTableInfo;
  302. if (pSameTableInfo == NULL) throw(TEXT("内存不足,对象创建失败!"));
  303. //设置对象
  304. ZeroMemory(pSameTableInfo, sizeof(tagSameTableInfo));
  305. m_SameTableActive.Add(pSameTableInfo);
  306. return pSameTableInfo;
  307. }
  308. catch (...)
  309. {
  310. ASSERT(FALSE);
  311. }
  312. return NULL;
  313. }
  314. //移除对象
  315. VOID CDistributeManager::RemoveSameTableInfo(tagSameTableInfo * pSameTableInfo)
  316. {
  317. ZeroMemory(pSameTableInfo, sizeof(tagSameTableInfo));
  318. m_SameTableBuffer.Add(pSameTableInfo);
  319. //查找对象
  320. for (INT_PTR nIndex = 0; nIndex < m_SameTableActive.GetCount(); nIndex++)
  321. {
  322. if (m_SameTableActive[nIndex] == pSameTableInfo)
  323. {
  324. m_SameTableActive.RemoveAt(nIndex);
  325. break;
  326. }
  327. }
  328. }
  329. //查找结点
  330. tagDistributeNode * CDistributeManager::SearchNode(const IServerUserItem * const pIServerUserItem)
  331. {
  332. if (m_pHeadNode == NULL) return NULL;
  333. //设置变量
  334. tagDistributeNode *pMoveNode = m_pHeadNode;
  335. //查找结点
  336. while (pMoveNode != NULL)
  337. {
  338. //接口判断
  339. if (pMoveNode->DistributeInfo.pIServerUserItem == pIServerUserItem)
  340. return pMoveNode;
  341. //向前推进
  342. pMoveNode = pMoveNode->pNextDistributeNode;
  343. }
  344. return NULL;
  345. }
  346. //IP同址
  347. BOOL CDistributeManager::FilterRuleExitsIPAddr(const CDistributeInfoArray & DistributeInfoArray, DWORD dwClientAddr)
  348. {
  349. //查找同IP
  350. for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++)
  351. {
  352. if (DistributeInfoArray[nIndex].dwClientAddr == dwClientAddr)
  353. return TRUE;
  354. }
  355. return FALSE;
  356. }
  357. //机器过滤
  358. BOOL CDistributeManager::FilterRuleIsAllAndroid(const CDistributeInfoArray & DistributeInfoArray, IServerUserItem * const pIServerUserItem)
  359. {
  360. //参数校验
  361. if (pIServerUserItem == NULL || DistributeInfoArray.GetCount() == 0) return FALSE;
  362. //变量定义
  363. WORD wAndroidCount = 0;
  364. //统计机器
  365. for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++)
  366. {
  367. if (DistributeInfoArray[nIndex].pIServerUserItem->IsAndroidUser() == true)
  368. ++wAndroidCount;
  369. }
  370. return (wAndroidCount == DistributeInfoArray.GetCount()) && pIServerUserItem->IsAndroidUser();
  371. }
  372. //上局同桌
  373. BOOL CDistributeManager::FilterRuleIsLastSameTable(const CDistributeInfoArray & DistributeInfoArray, DWORD dwUserID)
  374. {
  375. //参数校验
  376. if (DistributeInfoArray.GetCount() == 0) return FALSE;
  377. //变量定义
  378. tagSameTableInfo * pSameTableInfo = NULL;
  379. for (INT_PTR nIndex = 0; nIndex < DistributeInfoArray.GetCount(); nIndex++)
  380. {
  381. pSameTableInfo = GetUserSameTableInfo(DistributeInfoArray[nIndex].pIServerUserItem->GetUserID());
  382. if (pSameTableInfo != NULL)
  383. {
  384. for (WORD i = 0; i < pSameTableInfo->wPlayerCount; i++)
  385. {
  386. if (pSameTableInfo->wPlayerIDSet[i] == dwUserID) return TRUE;
  387. }
  388. }
  389. }
  390. return FALSE;
  391. }
  392. //////////////////////////////////////////////////////////////////////////////////