诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1189 line
36 KiB

  1. #include "StdAfx.h"
  2. #include "AndroidUserManager.h"
  3. //////////////////////////////////////////////////////////////////////////////////
  4. //常量定义
  5. #define ANDROID_LOGON_COUNT 32 //登录数目
  6. #define ADNDROID_PLAY_DRAW 10 //游戏局数
  7. #define ANDROID_UNLOAD_TIME 30*60 //不加载时间
  8. #define ANDROID_UNIN_TIME 10*60 //不进入时间
  9. //时间标识
  10. #define IDI_ANDROID_IN (IDI_REBOT_MODULE_START+0) //进入时间
  11. #define IDI_ANDROID_OUT (IDI_REBOT_MODULE_START+MAX_BATCH) //退出时间
  12. #define IDI_ANDROID_PULSE (IDI_REBOT_MODULE_START+2*MAX_BATCH)//脉冲时间
  13. //机器时间
  14. #define TIME_ANDROID_INOUT 15L //登录时间
  15. #define TIME_ANDROID_PULSE 1L //脉冲时间
  16. #define TIME_LOAD_ANDROID_INFO 900L //加载用户
  17. #define TIME_ANDROID_REPOSE_TIME 1800L //服务时间
  18. //////////////////////////////////////////////////////////////////////////////////
  19. //构造函数
  20. CAndroidUserManager::CAndroidUserManager()
  21. {
  22. //系统参数
  23. m_pGameParameter = NULL;
  24. m_pGameServiceAttrib = NULL;
  25. m_pGameServiceOption = NULL;
  26. //组件接口
  27. m_pITimerEngine = NULL;
  28. m_pIServerUserManager = NULL;
  29. m_pIGameServiceManager = NULL;
  30. m_pITCPNetworkEngineEvent = NULL;
  31. //配置变量
  32. m_dwMinSitInterval = 0;
  33. m_dwMaxSitInterval = 0;
  34. m_bServiceContinue = false;
  35. m_wAutoAndroidCount = ANDROID_LOGON_COUNT;
  36. //库存变量
  37. m_wStockCount = 0;
  38. ZeroMemory(&m_AndroidItemConfig, sizeof(m_AndroidItemConfig));
  39. //设置索引
  40. m_AndroidUserItemMap.InitHashTable(PRIME_ANDROID_USER);
  41. m_AndroidUserItemMap.RemoveAll();
  42. return;
  43. }
  44. //析构函数
  45. CAndroidUserManager::~CAndroidUserManager()
  46. {
  47. //清理断言
  48. ASSERT(m_AndroidUserItemMap.GetCount() == 0L);
  49. ASSERT(m_AndroidParameterArray.GetCount() == 0L);
  50. ASSERT(m_AndroidUserItemArray.GetCount() == 0L);
  51. ASSERT(m_AndroidUserItemBuffer.GetCount() == 0L);
  52. return;
  53. }
  54. //接口查询
  55. VOID * CAndroidUserManager::QueryInterface(REFGUID Guid, DWORD dwQueryVer)
  56. {
  57. QUERYINTERFACE(IAndroidUserManager, Guid, dwQueryVer);
  58. QUERYINTERFACE_IUNKNOWNEX(IAndroidUserManager, Guid, dwQueryVer);
  59. return NULL;
  60. }
  61. //启动服务
  62. bool CAndroidUserManager::StartService()
  63. {
  64. //启动时间
  65. m_pITimerEngine->SetTimer(IDI_ANDROID_PULSE, TIME_ANDROID_PULSE * 1000L, TIMES_INFINITY, 0);
  66. return true;
  67. }
  68. //停止服务
  69. bool CAndroidUserManager::ConcludeService()
  70. {
  71. //删除存储
  72. for (INT_PTR i = 0; i < m_AndroidUserItemArray.GetCount(); i++)
  73. {
  74. SafeRelease(m_AndroidUserItemArray[i]);
  75. }
  76. //删除存储
  77. for (INT_PTR i = 0; i < m_AndroidParameterArray.GetCount(); i++)
  78. {
  79. SafeDelete(m_AndroidParameterArray[i]);
  80. }
  81. //清理数组
  82. m_AndroidUserItemMap.RemoveAll();
  83. m_AndroidParameterArray.RemoveAll();
  84. m_AndroidUserItemArray.RemoveAll();
  85. m_AndroidUserItemBuffer.RemoveAll();
  86. //库存用户
  87. m_wStockCount = 0;
  88. ZeroMemory(&m_AndroidItemConfig, sizeof(m_AndroidItemConfig));
  89. return true;
  90. }
  91. //配置组件
  92. bool CAndroidUserManager::InitAndroidUser(tagAndroidUserParameter & AndroidUserParameter)
  93. {
  94. //服务配置
  95. m_bServiceContinue = AndroidUserParameter.bServiceContinue;
  96. m_dwMinSitInterval = AndroidUserParameter.dwMinSitInterval;
  97. m_dwMaxSitInterval = AndroidUserParameter.dwMaxSitInterval;
  98. //设置变量
  99. m_pGameParameter = AndroidUserParameter.pGameParameter;
  100. m_pGameServiceAttrib = AndroidUserParameter.pGameServiceAttrib;
  101. m_pGameServiceOption = AndroidUserParameter.pGameServiceOption;
  102. //组件接口
  103. m_pITimerEngine = AndroidUserParameter.pITimerEngine;
  104. m_pIServerUserManager = AndroidUserParameter.pIServerUserManager;
  105. m_pIGameServiceManager = AndroidUserParameter.pIGameServiceManager;
  106. m_pITCPNetworkEngineEvent = AndroidUserParameter.pITCPNetworkEngineEvent;
  107. return true;
  108. }
  109. //移除参数
  110. bool CAndroidUserManager::RemoveAndroidParameter(DWORD dwBatchID)
  111. {
  112. //获取参数
  113. tagAndroidParameterEx * pAndroidParameter = GetAndroidParameter(dwBatchID);
  114. if (pAndroidParameter == NULL) return false;
  115. //获取时间
  116. SYSTEMTIME SystemTime;
  117. GetLocalTime(&SystemTime);
  118. DWORD dwTodayTickCount = GetTodayTickCount(SystemTime);
  119. //调整参数
  120. pAndroidParameter->bIsValided = false;
  121. pAndroidParameter->AndroidParameter.dwLeaveTime = dwTodayTickCount;
  122. //获取索引
  123. WORD wParameterIndex = GetAndroidParameterIndex(pAndroidParameter);
  124. if (wParameterIndex == INVALID_WORD) return true;
  125. //关闭定时器
  126. m_pITimerEngine->KillTimer(IDI_ANDROID_IN + wParameterIndex);
  127. //删掉库存
  128. for (int i = m_wStockCount - 1; i >= 0; i--)
  129. {
  130. //批次判断
  131. if (m_AndroidItemConfig[i].pAndroidParameter != &pAndroidParameter->AndroidParameter) continue;
  132. //删除存存
  133. m_wStockCount--;
  134. m_AndroidItemConfig[i] = m_AndroidItemConfig[m_wStockCount];
  135. }
  136. //加载判断
  137. if (pAndroidParameter->bIsLoadAndroid == false)
  138. {
  139. //释放资源
  140. SafeDelete(pAndroidParameter);
  141. m_AndroidParameterArray[wParameterIndex] = NULL;
  142. return true;
  143. }
  144. //开启定时器
  145. m_pITimerEngine->SetTimer(IDI_ANDROID_OUT + wParameterIndex, TIME_ANDROID_INOUT * 1000L, TIMES_INFINITY, (WPARAM)pAndroidParameter);
  146. return true;
  147. }
  148. //设置参数
  149. bool CAndroidUserManager::AddAndroidParameter(tagAndroidParameter AndroidParameter[], WORD wParameterCount)
  150. {
  151. //变量定义
  152. tagAndroidParameterEx * pAndroidParameter = NULL;
  153. for (WORD wIndex = 0; wIndex < wParameterCount; wIndex++)
  154. {
  155. //数目限制
  156. if (m_AndroidParameterArray.GetCount() >= MAX_BATCH) break;
  157. //设置资源
  158. pAndroidParameter = GetAndroidParameter(AndroidParameter[wIndex].dwBatchID);
  159. if (pAndroidParameter == NULL)
  160. {
  161. //申请资源
  162. pAndroidParameter = new tagAndroidParameterEx();
  163. if (pAndroidParameter == NULL) return false;
  164. //设置变量
  165. pAndroidParameter->bIsValided = true;
  166. pAndroidParameter->bIsLoadAndroid = false;
  167. //变量定义
  168. bool bVacancyExist = false;
  169. //查找空缺
  170. for (INT_PTR nIndex = 0; nIndex < m_AndroidParameterArray.GetCount(); nIndex++)
  171. {
  172. if (m_AndroidParameterArray[nIndex] == NULL)
  173. {
  174. bVacancyExist = true;
  175. m_AndroidParameterArray[nIndex] = pAndroidParameter;
  176. break;
  177. }
  178. }
  179. //不存在空缺
  180. if (bVacancyExist == false)
  181. {
  182. m_AndroidParameterArray.Add(pAndroidParameter);
  183. }
  184. }
  185. //拷贝数据
  186. CopyMemory(pAndroidParameter, &AndroidParameter[wIndex], sizeof(tagAndroidParameter));
  187. }
  188. return true;
  189. }
  190. //插入机器
  191. bool CAndroidUserManager::InsertAndroidInfo(tagAndroidAccountsInfo AndroidAccountsInfo[], WORD wAndroidCount, DWORD dwBatchID)
  192. {
  193. //获取参数
  194. tagAndroidParameterEx * pAndroidParameter = GetAndroidParameter(dwBatchID);
  195. if (pAndroidParameter == NULL) return false;
  196. //记录库存
  197. CAndroidUserItem * pAndroidUserItem = NULL;
  198. WORD wStockCount = m_wStockCount;
  199. bool bAndroidExist = false;
  200. //添加新机器
  201. for (WORD wIndex = 0; wIndex < wAndroidCount; wIndex++)
  202. {
  203. //设置变量
  204. bAndroidExist = false;
  205. //从库存中查找
  206. for (WORD wItem = 0; wItem < wStockCount; wItem++)
  207. {
  208. if (m_AndroidItemConfig[wIndex].AndroidAccountsInfo.dwUserID == AndroidAccountsInfo[wIndex].dwUserID)
  209. {
  210. bAndroidExist = true;
  211. break;
  212. }
  213. }
  214. //存在判断
  215. if (bAndroidExist == true) continue;
  216. //从映射中查找
  217. if (m_AndroidUserItemMap.Lookup(AndroidAccountsInfo[wIndex].dwUserID, pAndroidUserItem) == TRUE)
  218. {
  219. continue;
  220. }
  221. //添加机器
  222. m_AndroidItemConfig[m_wStockCount].AndroidAccountsInfo = AndroidAccountsInfo[wIndex];
  223. m_AndroidItemConfig[m_wStockCount].pAndroidParameter = &pAndroidParameter->AndroidParameter;
  224. //增加库存
  225. m_wStockCount++;
  226. }
  227. //获取索引
  228. WORD wParameterIndex = GetAndroidParameterIndex(pAndroidParameter);
  229. if (wParameterIndex == INVALID_WORD) return true;
  230. //开启定时器
  231. m_pITimerEngine->KillTimer(IDI_ANDROID_IN + wParameterIndex);
  232. m_pITimerEngine->SetTimer(IDI_ANDROID_IN + wParameterIndex, TIME_ANDROID_INOUT * 1000L, TIMES_INFINITY, (WPARAM)pAndroidParameter);
  233. return true;
  234. }
  235. //删除机器
  236. bool CAndroidUserManager::DeleteAndroidUserItem(DWORD dwAndroidID, bool bStockRetrieve)
  237. {
  238. //获取对象
  239. WORD wIndex = LOWORD(dwAndroidID);
  240. CAndroidUserItem * pAndroidUserItem = GetAndroidUserItem(wIndex);
  241. //对象效验
  242. //ASSERT((pAndroidUserItem!=NULL)&&(pAndroidUserItem->m_wRoundID==HIWORD(dwAndroidID)));
  243. if ((pAndroidUserItem == NULL) || (pAndroidUserItem->m_wRoundID != HIWORD(dwAndroidID))) return false;
  244. //关闭事件
  245. try
  246. {
  247. m_pITCPNetworkEngineEvent->OnEventTCPNetworkShut(dwAndroidID, 0, 0L);
  248. }
  249. catch (...)
  250. {
  251. //错误断言
  252. ASSERT(FALSE);
  253. }
  254. //机器配置
  255. tagAndroidItemConfig AndroidItemConfig = pAndroidUserItem->m_AndroidItemConfig;
  256. //删除对象
  257. FreeAndroidUserItem(pAndroidUserItem->GetUserID());
  258. //库存回收
  259. if (bStockRetrieve == true)
  260. {
  261. InsertAndroidInfo(&AndroidItemConfig.AndroidAccountsInfo, 1, AndroidItemConfig.pAndroidParameter->dwBatchID);
  262. }
  263. return true;
  264. }
  265. //查找机器
  266. IAndroidUserItem * CAndroidUserManager::SearchAndroidUserItem(DWORD dwUserID, DWORD dwContextID)
  267. {
  268. //查找机器
  269. CAndroidUserItem * pAndroidUserItem = NULL;
  270. m_AndroidUserItemMap.Lookup(dwUserID, pAndroidUserItem);
  271. //机器判断
  272. if (pAndroidUserItem != NULL)
  273. {
  274. WORD wRoundID = pAndroidUserItem->m_wRoundID;
  275. WORD wAndroidIndex = pAndroidUserItem->m_wAndroidIndex;
  276. if (MAKELONG(wAndroidIndex, wRoundID) == dwContextID) return pAndroidUserItem;
  277. }
  278. return NULL;
  279. }
  280. //创建机器
  281. IAndroidUserItem * CAndroidUserManager::CreateAndroidUserItem(tagAndroidItemConfig & AndroidItemConfig)
  282. {
  283. //效验参数
  284. ASSERT(AndroidItemConfig.AndroidAccountsInfo.dwUserID != 0L);
  285. if (AndroidItemConfig.AndroidAccountsInfo.dwUserID == 0L) return NULL;
  286. //创建对象
  287. CAndroidUserItem * pAndroidUserItem = ActiveAndroidUserItem(AndroidItemConfig);
  288. if (pAndroidUserItem == NULL) return NULL;
  289. //属性变量
  290. WORD wRoundID = pAndroidUserItem->m_wRoundID;
  291. WORD wAndroidIndex = pAndroidUserItem->m_wAndroidIndex;
  292. //连接模拟
  293. try
  294. {
  295. if (m_pITCPNetworkEngineEvent->OnEventTCPNetworkBind(MAKELONG(wAndroidIndex, wRoundID), 0L) == false)
  296. {
  297. throw 0;
  298. }
  299. }
  300. catch (...)
  301. {
  302. //错误断言
  303. ASSERT(FALSE);
  304. //释放用户
  305. FreeAndroidUserItem(AndroidItemConfig.AndroidAccountsInfo.dwUserID);
  306. return NULL;
  307. }
  308. //变量定义
  309. CMD_GR_LogonUserID LogonUserID;
  310. ZeroMemory(&LogonUserID, sizeof(LogonUserID));
  311. //版本信息
  312. LogonUserID.dwPlazaVersion = VERSION_PLAZA;
  313. LogonUserID.dwFrameVersion = VERSION_FRAME;
  314. LogonUserID.dwProcessVersion = m_pGameServiceAttrib->dwClientVersion;
  315. //用户信息
  316. LogonUserID.dwUserID = AndroidItemConfig.AndroidAccountsInfo.dwUserID;
  317. lstrcpyn(LogonUserID.szPassword, AndroidItemConfig.AndroidAccountsInfo.szPassword, CountArray(LogonUserID.szPassword));
  318. LogonUserID.wKindID = m_pGameServiceOption->wKindID;
  319. //构造数据
  320. TCP_Command Command;
  321. Command.wMainCmdID = MDM_GR_LOGON;
  322. Command.wSubCmdID = SUB_GR_LOGON_USERID;
  323. //消息处理
  324. try
  325. {
  326. //发送数据
  327. if (m_pITCPNetworkEngineEvent->OnEventTCPNetworkRead(MAKELONG(wAndroidIndex, wRoundID), Command, &LogonUserID, sizeof(LogonUserID)) == false)
  328. {
  329. throw 0;
  330. }
  331. }
  332. catch (...)
  333. {
  334. //错误断言
  335. ASSERT(FALSE);
  336. //删除机器
  337. DeleteAndroidUserItem(MAKELONG(wAndroidIndex, wRoundID), false);
  338. return NULL;
  339. }
  340. return pAndroidUserItem;
  341. }
  342. //脉冲事件
  343. bool CAndroidUserManager::OnEventTimerPulse(DWORD dwTimerID, WPARAM dwBindParameter)
  344. {
  345. //进入处理
  346. if (dwTimerID >= IDI_ANDROID_IN && dwTimerID < IDI_ANDROID_IN + MAX_BATCH)
  347. {
  348. //获取时间
  349. SYSTEMTIME SystemTime;
  350. GetLocalTime(&SystemTime);
  351. DWORD dwTodayTickCount = GetTodayTickCount(SystemTime);
  352. //获取参数
  353. tagAndroidParameter * pAndroidParameter = (tagAndroidParameter *)dwBindParameter;
  354. if (pAndroidParameter == NULL)
  355. {
  356. //关闭定时器
  357. m_pITimerEngine->KillTimer(dwTimerID);
  358. return true;
  359. }
  360. //变量定义
  361. bool bAllowAndroidAttend = CServerRule::IsAllowAndroidAttend(m_pGameServiceOption->dwServerRule);
  362. bool bAllowAndroidSimulate = CServerRule::IsAllowAndroidSimulate(m_pGameServiceOption->dwServerRule);
  363. //成功标识
  364. bool bLogonSuccessed = false;
  365. //登录处理
  366. if ((bAllowAndroidAttend == true) || (bAllowAndroidSimulate == true))
  367. {
  368. //寻找机器
  369. for (WORD i = 0; i < m_wStockCount; i++)
  370. {
  371. //批次判断
  372. if (m_AndroidItemConfig[i].pAndroidParameter != pAndroidParameter) continue;
  373. //模拟判断
  374. if ((m_pGameServiceOption->wServerType&GAME_GENRE_MATCH)
  375. && (pAndroidParameter->dwServiceMode&ANDROID_SIMULATE) != 0
  376. && (pAndroidParameter->dwServiceMode&ANDROID_PASSIVITY) == 0
  377. && (pAndroidParameter->dwServiceMode&ANDROID_INITIATIVE) == 0)
  378. {
  379. continue;
  380. }
  381. //创建机器
  382. if (CreateAndroidUserItem(m_AndroidItemConfig[i]) != NULL)
  383. {
  384. //删除存存
  385. m_wStockCount--;
  386. bLogonSuccessed = true;
  387. m_AndroidItemConfig[i] = m_AndroidItemConfig[m_wStockCount];
  388. break;
  389. }
  390. }
  391. }
  392. //关闭定时器
  393. m_pITimerEngine->KillTimer(dwTimerID);
  394. //定时器处理
  395. if (bLogonSuccessed == true)
  396. {
  397. //计算流逝时间
  398. DWORD dwElapse = pAndroidParameter->dwEnterMinInterval + rand() % (pAndroidParameter->dwEnterMaxInterval - pAndroidParameter->dwEnterMinInterval + 1);
  399. if (dwElapse == 0) dwElapse = TIME_ANDROID_INOUT;
  400. //设置定时器
  401. m_pITimerEngine->SetTimer(dwTimerID, dwElapse * 1000L, TIMES_INFINITY, dwBindParameter);
  402. }
  403. else
  404. {
  405. //剩余时间
  406. DWORD dwRemaindTime = BatchServiceRemaindTime(pAndroidParameter, dwTodayTickCount);
  407. if (dwRemaindTime <= ANDROID_UNIN_TIME)
  408. {
  409. //设置定时器
  410. m_pITimerEngine->SetTimer(IDI_ANDROID_OUT + (dwTimerID - IDI_ANDROID_IN), TIME_ANDROID_INOUT * 1000L, TIMES_INFINITY, dwBindParameter);
  411. CString str;
  412. str.Format(TEXT("本批次机器人开始退出, 批次ID=%d"), pAndroidParameter->dwBatchID);
  413. CTraceService::TraceString(str, TraceLevel_Info);
  414. }
  415. else
  416. {
  417. //设置定时器
  418. m_pITimerEngine->SetTimer(dwTimerID, TIME_ANDROID_INOUT * 1000L, TIMES_INFINITY, dwBindParameter);
  419. }
  420. }
  421. return true;
  422. }
  423. //退出处理
  424. if (dwTimerID >= IDI_ANDROID_OUT && dwTimerID < IDI_ANDROID_OUT + MAX_BATCH)
  425. {
  426. //变量定义
  427. DWORD dwUserID = 0L;
  428. INT_PTR nActiveCount = m_AndroidUserItemMap.GetCount();
  429. POSITION Position = m_AndroidUserItemMap.GetStartPosition();
  430. //获取时间
  431. SYSTEMTIME SystemTime;
  432. GetLocalTime(&SystemTime);
  433. DWORD dwTodayTickCount = GetTodayTickCount(SystemTime);
  434. //获取参数
  435. tagAndroidParameterEx * pAndroidParameter = (tagAndroidParameterEx *)dwBindParameter;
  436. if (pAndroidParameter == NULL)
  437. {
  438. //关闭定时器
  439. m_pITimerEngine->KillTimer(dwTimerID);
  440. return true;
  441. }
  442. //时间判断
  443. if (BatchServiceRemaindTime(&pAndroidParameter->AndroidParameter, dwTodayTickCount) > 0)
  444. {
  445. return true;
  446. }
  447. //变量定义
  448. bool bLogoutSuccessed = false;
  449. //退出处理
  450. while (Position != NULL)
  451. {
  452. //获取对象
  453. CAndroidUserItem * pAndroidUserItem = NULL;
  454. m_AndroidUserItemMap.GetNextAssoc(Position, dwUserID, pAndroidUserItem);
  455. //退出判断
  456. if (pAndroidUserItem->m_pIServerUserItem != NULL &&
  457. pAndroidUserItem->GetAndroidParameter() == &pAndroidParameter->AndroidParameter)
  458. {
  459. //变量定义
  460. IServerUserItem * pIServerUserItem = pAndroidUserItem->m_pIServerUserItem;
  461. //服务状态
  462. BYTE cbUserStatus = pIServerUserItem->GetUserStatus();
  463. if ((cbUserStatus != US_FREE) && (cbUserStatus != US_SIT))
  464. {
  465. if (bLogoutSuccessed == false)
  466. {
  467. bLogoutSuccessed = true;
  468. pAndroidUserItem->m_wAndroidAction |= ANDROID_WAITLEAVE;
  469. }
  470. continue;
  471. }
  472. //删除用户
  473. WORD wRoundID = pAndroidUserItem->m_wRoundID;
  474. WORD wAndroidIndex = pAndroidUserItem->m_wAndroidIndex;
  475. DeleteAndroidUserItem(MAKELONG(wAndroidIndex, wRoundID), false);
  476. //设置变量
  477. bLogoutSuccessed = true;
  478. break;
  479. }
  480. }
  481. //关闭定时器
  482. m_pITimerEngine->KillTimer(dwTimerID);
  483. //定时器处理
  484. if (bLogoutSuccessed == true)
  485. {
  486. //计算流逝时间
  487. DWORD dwElapse = pAndroidParameter->AndroidParameter.dwLeaveMinInterval + rand() % (pAndroidParameter->AndroidParameter.dwLeaveMaxInterval - pAndroidParameter->AndroidParameter.dwLeaveMinInterval + 1);
  488. if (dwElapse == 0) dwElapse = TIME_ANDROID_INOUT;
  489. //设置定时器
  490. m_pITimerEngine->SetTimer(dwTimerID, dwElapse * 1000L, TIMES_INFINITY, dwBindParameter);
  491. }
  492. else
  493. {
  494. if (pAndroidParameter->bIsValided == false)
  495. {
  496. //计算索引
  497. WORD wParameterIndex = (WORD)(dwTimerID - IDI_ANDROID_OUT);
  498. if (wParameterIndex == GetAndroidParameterIndex(pAndroidParameter))
  499. {
  500. //释放资源
  501. SafeDelete(m_AndroidParameterArray[wParameterIndex]);
  502. m_AndroidParameterArray[wParameterIndex] = NULL;
  503. CString str;
  504. str.Format(TEXT("本批次机器人全部退出,该批次将被删除, 批次ID=%d"), pAndroidParameter->AndroidParameter.dwBatchID);
  505. CTraceService::TraceString(str, TraceLevel_Info);
  506. }
  507. }
  508. else
  509. {
  510. //恢复标识
  511. pAndroidParameter->bIsLoadAndroid = false;
  512. CString str;
  513. str.Format(TEXT("本批次机器人全部退出, 批次ID=%d"), pAndroidParameter->AndroidParameter.dwBatchID);
  514. CTraceService::TraceString(str, TraceLevel_Info);
  515. }
  516. }
  517. return true;
  518. }
  519. //用户脉冲
  520. if (dwTimerID == IDI_ANDROID_PULSE)
  521. {
  522. //变量定义
  523. DWORD dwUserID = 0L;
  524. CAndroidUserItem * pAndroidUserItem = NULL;
  525. POSITION Position = m_AndroidUserItemMap.GetStartPosition();
  526. //用户处理
  527. while (Position != NULL)
  528. {
  529. //获取对象
  530. m_AndroidUserItemMap.GetNextAssoc(Position, dwUserID, pAndroidUserItem);
  531. //时间处理
  532. try
  533. {
  534. //ASSERT(pAndroidUserItem!=NULL);
  535. if (pAndroidUserItem->m_pIServerUserItem != NULL) pAndroidUserItem->OnTimerPulse(dwTimerID, dwBindParameter);
  536. }
  537. catch (...)
  538. {
  539. ASSERT(FALSE);
  540. DeleteAndroidUserItem(MAKELONG(pAndroidUserItem->m_wAndroidIndex, pAndroidUserItem->m_wRoundID), true);
  541. }
  542. }
  543. return true;
  544. }
  545. return false;
  546. }
  547. //加载机器
  548. bool CAndroidUserManager::GetAndroidLoadInfo(DWORD & dwBatchID, DWORD & dwLoadCount)
  549. {
  550. //数目判断
  551. if (m_AndroidParameterArray.GetCount() == 0) return false;
  552. //获取时间
  553. SYSTEMTIME SystemTime;
  554. GetLocalTime(&SystemTime);
  555. DWORD dwTodayTickCount = GetTodayTickCount(SystemTime);
  556. //变量定义
  557. tagAndroidParameterEx * pAndroidParameter = NULL;
  558. DWORD dwRemaindTime;
  559. //退出处理
  560. for (INT_PTR nIndex = 0; nIndex < m_AndroidParameterArray.GetCount(); nIndex++)
  561. {
  562. //获取对象
  563. pAndroidParameter = m_AndroidParameterArray[nIndex];
  564. if (pAndroidParameter == NULL) continue;
  565. //加载判断
  566. if (pAndroidParameter->bIsLoadAndroid == true) continue;
  567. //剩余时间
  568. dwRemaindTime = BatchServiceRemaindTime(&pAndroidParameter->AndroidParameter, dwTodayTickCount);
  569. //加载机器
  570. if (dwRemaindTime > ANDROID_UNLOAD_TIME)
  571. {
  572. //设置标识
  573. pAndroidParameter->bIsLoadAndroid = true;
  574. //设置参数
  575. dwBatchID = pAndroidParameter->AndroidParameter.dwBatchID;
  576. dwLoadCount = __min(pAndroidParameter->AndroidParameter.dwAndroidCount, dwRemaindTime / pAndroidParameter->AndroidParameter.dwEnterMaxInterval);
  577. return true;
  578. }
  579. }
  580. return false;
  581. }
  582. //用户状况
  583. WORD CAndroidUserManager::GetAndroidUserInfo(tagAndroidUserInfo & AndroidUserInfo, DWORD dwServiceMode)
  584. {
  585. //获取时间
  586. SYSTEMTIME SystemTime;
  587. GetLocalTime(&SystemTime);
  588. DWORD dwTodayTickCount = GetTodayTickCount(SystemTime);
  589. //设置变量
  590. ZeroMemory(&AndroidUserInfo, sizeof(AndroidUserInfo));
  591. //变量定义
  592. DWORD dwTimeMask = (1L << SystemTime.wHour);
  593. POSITION Position = m_AndroidUserItemMap.GetStartPosition();
  594. //枚举对象
  595. while (Position != NULL)
  596. {
  597. //获取对象
  598. DWORD dwUserID = 0L;
  599. CAndroidUserItem * pAndroidUserItem = NULL;
  600. m_AndroidUserItemMap.GetNextAssoc(Position, dwUserID, pAndroidUserItem);
  601. //效验参数
  602. ASSERT((dwUserID != 0L) && (pAndroidUserItem != NULL));
  603. if ((dwUserID == 0L) || (pAndroidUserItem == NULL)) break;
  604. //绑定判断
  605. if (pAndroidUserItem->m_pIServerUserItem == NULL) continue;
  606. //变量定义
  607. IServerUserItem * pIServerUserItem = pAndroidUserItem->m_pIServerUserItem;
  608. tagAndroidParameter * pAndroidParameter = pAndroidUserItem->GetAndroidParameter();
  609. //离开判断
  610. if (pAndroidUserItem->m_bWaitLeave == true) continue;
  611. //模式判断
  612. if ((pAndroidParameter->dwServiceMode&dwServiceMode) == 0L) continue;
  613. //离开判断
  614. if (!m_bServiceContinue && BatchServiceRemaindTime(pAndroidParameter, dwTodayTickCount) == 0) continue;
  615. //休息时间
  616. DWORD dwCurrTime = (DWORD)time(NULL);
  617. if ((pAndroidUserItem->m_dwStandupTickCount + pAndroidUserItem->m_dwReposeTickCount) > dwCurrTime) continue;
  618. //状态判断
  619. switch (pIServerUserItem->GetUserStatus())
  620. {
  621. case US_FREE:
  622. {
  623. ASSERT(AndroidUserInfo.wFreeUserCount < CountArray(AndroidUserInfo.pIAndroidUserFree));
  624. AndroidUserInfo.pIAndroidUserFree[AndroidUserInfo.wFreeUserCount++] = pAndroidUserItem;
  625. break;
  626. }
  627. case US_SIT:
  628. case US_READY:
  629. {
  630. ASSERT(AndroidUserInfo.wSitdownUserCount < CountArray(AndroidUserInfo.pIAndroidUserSitdown));
  631. AndroidUserInfo.pIAndroidUserSitdown[AndroidUserInfo.wSitdownUserCount++] = pAndroidUserItem;
  632. break;
  633. }
  634. case US_PLAYING:
  635. case US_OFFLINE:
  636. {
  637. ASSERT(AndroidUserInfo.wPlayUserCount < CountArray(AndroidUserInfo.pIAndroidUserPlay));
  638. AndroidUserInfo.pIAndroidUserPlay[AndroidUserInfo.wPlayUserCount++] = pAndroidUserItem;
  639. break;
  640. }
  641. }
  642. };
  643. return AndroidUserInfo.wFreeUserCount + AndroidUserInfo.wPlayUserCount + AndroidUserInfo.wSitdownUserCount;
  644. }
  645. //发送数据
  646. bool CAndroidUserManager::SendDataToClient(WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize)
  647. {
  648. //发送数据
  649. for (INT_PTR i = 0; i < m_AndroidUserItemArray.GetCount(); i++)
  650. {
  651. //获取对象
  652. CAndroidUserItem * pAndroidUserItem = m_AndroidUserItemArray[i];
  653. //状态判断
  654. if (pAndroidUserItem->m_pIServerUserItem == NULL) continue;
  655. if (pAndroidUserItem->m_AndroidItemConfig.AndroidAccountsInfo.dwUserID == 0L) continue;
  656. //消息处理
  657. try
  658. {
  659. if (pAndroidUserItem->OnSocketRead(wMainCmdID, wSubCmdID, pData, wDataSize) == false)
  660. {
  661. throw 0;
  662. }
  663. }
  664. catch (...)
  665. {
  666. //错误断言
  667. ASSERT(FALSE);
  668. //断开用户
  669. WORD wRoundID = pAndroidUserItem->m_wRoundID;
  670. WORD wAndroidIndex = pAndroidUserItem->m_wAndroidIndex;
  671. DeleteAndroidUserItem(MAKELONG(wAndroidIndex, wRoundID), true);
  672. }
  673. }
  674. return true;
  675. }
  676. //发送数据
  677. bool CAndroidUserManager::SendDataToClient(DWORD dwAndroidID, WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize)
  678. {
  679. //获取对象
  680. WORD wIndex = LOWORD(dwAndroidID);
  681. CAndroidUserItem * pAndroidUserItem = GetAndroidUserItem(wIndex);
  682. //对象效验
  683. //ASSERT((pAndroidUserItem!=NULL)&&(pAndroidUserItem->m_wRoundID==HIWORD(dwAndroidID)));
  684. if ((pAndroidUserItem == NULL) || (pAndroidUserItem->m_wRoundID != HIWORD(dwAndroidID))) return false;
  685. //消息处理
  686. try
  687. {
  688. if (pAndroidUserItem->OnSocketRead(wMainCmdID, wSubCmdID, pData, wDataSize) == false)
  689. {
  690. ASSERT(FALSE);
  691. throw 0;
  692. }
  693. }
  694. catch (...)
  695. {
  696. ASSERT(FALSE);
  697. DeleteAndroidUserItem(dwAndroidID, true);
  698. }
  699. return true;
  700. }
  701. //发送数据
  702. bool CAndroidUserManager::SendDataToServer(DWORD dwAndroidID, WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize)
  703. {
  704. //构造数据
  705. TCP_Command Command;
  706. Command.wSubCmdID = wSubCmdID;
  707. Command.wMainCmdID = wMainCmdID;
  708. //消息处理
  709. try
  710. {
  711. if (m_pITCPNetworkEngineEvent->OnEventTCPNetworkRead(dwAndroidID, Command, pData, wDataSize) == false)
  712. {
  713. throw 0;
  714. }
  715. }
  716. catch (...)
  717. {
  718. ASSERT(FALSE);
  719. DeleteAndroidUserItem(dwAndroidID, true);
  720. }
  721. return true;
  722. }
  723. //获取对象
  724. CAndroidUserItem * CAndroidUserManager::GetAndroidUserItem(WORD wIndex)
  725. {
  726. //效验索引
  727. ASSERT(wIndex >= INDEX_ANDROID);
  728. if (wIndex < INDEX_ANDROID) return NULL;
  729. //效验索引
  730. ASSERT((wIndex - INDEX_ANDROID) < m_AndroidUserItemArray.GetCount());
  731. if (((wIndex - INDEX_ANDROID) >= m_AndroidUserItemArray.GetCount())) return NULL;
  732. //获取对象
  733. WORD wBufferIndex = wIndex - INDEX_ANDROID;
  734. CAndroidUserItem * pAndroidUserItem = m_AndroidUserItemArray[wBufferIndex];
  735. return pAndroidUserItem;
  736. }
  737. //释放对象
  738. VOID CAndroidUserManager::FreeAndroidUserItem(DWORD dwUserID)
  739. {
  740. //效验参数
  741. ASSERT(dwUserID != 0);
  742. if (dwUserID == 0) return;
  743. //变量定义
  744. CAndroidUserItem * pAndroidUserItem = NULL;
  745. m_AndroidUserItemMap.Lookup(dwUserID, pAndroidUserItem);
  746. //对象判断
  747. if (pAndroidUserItem == NULL)
  748. {
  749. ASSERT(FALSE);
  750. return;
  751. }
  752. //复位对象
  753. pAndroidUserItem->RepositUserItem();
  754. //设置索引
  755. m_AndroidUserItemMap.RemoveKey(dwUserID);
  756. m_AndroidUserItemBuffer.Add(pAndroidUserItem);
  757. return;
  758. }
  759. //获取参数
  760. tagAndroidParameterEx * CAndroidUserManager::GetAndroidParameter(DWORD dwBatchID)
  761. {
  762. //查找数组
  763. for (INT_PTR nIndex = 0; nIndex < m_AndroidParameterArray.GetCount(); nIndex++)
  764. {
  765. if (m_AndroidParameterArray[nIndex] == NULL) continue;
  766. if (m_AndroidParameterArray[nIndex]->AndroidParameter.dwBatchID == dwBatchID)
  767. {
  768. return m_AndroidParameterArray[nIndex];
  769. }
  770. }
  771. return NULL;
  772. }
  773. //获取索引
  774. WORD CAndroidUserManager::GetAndroidParameterIndex(tagAndroidParameterEx * pAndroidParameter)
  775. {
  776. //参数校验
  777. if (pAndroidParameter == NULL) return INVALID_WORD;
  778. //查找数组
  779. for (INT_PTR nIndex = 0; nIndex < m_AndroidParameterArray.GetCount(); nIndex++)
  780. {
  781. if (m_AndroidParameterArray[nIndex] == pAndroidParameter)
  782. {
  783. return (WORD)nIndex;
  784. }
  785. }
  786. return INVALID_WORD;
  787. }
  788. //转换时间
  789. DWORD CAndroidUserManager::GetTodayTickCount(SYSTEMTIME & SystemTime)
  790. {
  791. return SystemTime.wHour * 3600 + SystemTime.wMinute * 60 + SystemTime.wSecond;
  792. }
  793. //剩余时间
  794. DWORD CAndroidUserManager::BatchServiceRemaindTime(tagAndroidParameter * pAndroidParameter, DWORD dwTodayTickCount)
  795. {
  796. //参数校验
  797. ASSERT(pAndroidParameter != NULL);
  798. if (pAndroidParameter == NULL) return 0;
  799. //变量定义
  800. DWORD dwEnterTime, dwLeaveTime;
  801. DWORD dwRemaindTime = 0;
  802. //设置变量
  803. dwEnterTime = pAndroidParameter->dwEnterTime;
  804. dwLeaveTime = pAndroidParameter->dwLeaveTime;
  805. //计算时间
  806. if (dwLeaveTime > dwEnterTime)
  807. {
  808. if (dwTodayTickCount >= dwEnterTime && dwTodayTickCount < dwLeaveTime)
  809. {
  810. dwRemaindTime = dwLeaveTime - dwTodayTickCount;
  811. }
  812. }
  813. else if (dwLeaveTime < dwEnterTime)
  814. {
  815. //第一天
  816. if (dwTodayTickCount >= dwEnterTime)
  817. {
  818. dwRemaindTime = dwLeaveTime + 24 * 3600 - dwTodayTickCount;
  819. }
  820. //第二天
  821. if (dwTodayTickCount < dwLeaveTime)
  822. {
  823. dwRemaindTime = dwLeaveTime - dwTodayTickCount;
  824. }
  825. }
  826. return dwRemaindTime;
  827. }
  828. //等待时间
  829. DWORD CAndroidUserManager::BatchServiceAwaitTime(tagAndroidParameter * pAndroidParameter, DWORD dwTodayTickCount)
  830. {
  831. //参数校验
  832. ASSERT(pAndroidParameter != NULL);
  833. if (pAndroidParameter == NULL) return 0;
  834. if (((tagAndroidParameterEx *)pAndroidParameter)->bIsLoadAndroid == false) return -1;
  835. //变量定义
  836. DWORD dwEnterTime, dwLeaveTime;
  837. //设置变量
  838. dwEnterTime = pAndroidParameter->dwEnterTime;
  839. dwLeaveTime = pAndroidParameter->dwLeaveTime;
  840. //计算时间
  841. if (dwEnterTime < dwLeaveTime)
  842. {
  843. if (dwTodayTickCount < dwEnterTime)
  844. {
  845. return dwEnterTime - dwTodayTickCount;
  846. }
  847. }
  848. else
  849. {
  850. if (dwTodayTickCount<dwEnterTime && dwTodayTickCount>dwLeaveTime)
  851. {
  852. return dwEnterTime - dwTodayTickCount;
  853. }
  854. }
  855. return 0;
  856. }
  857. //激活对象
  858. CAndroidUserItem * CAndroidUserManager::ActiveAndroidUserItem(tagAndroidItemConfig & AndroidItemConfig)
  859. {
  860. //变量定义
  861. CAndroidUserItem * pAndroidUserItem = NULL;
  862. INT_PTR nFreeItemCount = m_AndroidUserItemBuffer.GetCount();
  863. //获取对象
  864. if (nFreeItemCount > 0)
  865. {
  866. //获取对象
  867. INT_PTR nItemPostion = nFreeItemCount - 1;
  868. pAndroidUserItem = m_AndroidUserItemBuffer[nItemPostion];
  869. //删除数组
  870. m_AndroidUserItemBuffer.RemoveAt(nItemPostion);
  871. }
  872. //创建对象
  873. if (pAndroidUserItem == NULL)
  874. {
  875. //数目判断
  876. if (m_AndroidUserItemArray.GetCount() >= MAX_ANDROID)
  877. {
  878. ASSERT(FALSE);
  879. return NULL;
  880. }
  881. try
  882. {
  883. //变量定义
  884. IAndroidUserItemSink * pIAndroidUserItemSink = NULL;
  885. //创建陪玩
  886. if (CServerRule::IsAllowAndroidAttend(m_pGameServiceOption->dwServerRule) == true)
  887. {
  888. pIAndroidUserItemSink = (IAndroidUserItemSink *)m_pIGameServiceManager->CreateAndroidUserItemSink(IID_IAndroidUserItemSink, VER_IAndroidUserItemSink);
  889. }
  890. //创建对象
  891. try
  892. {
  893. pAndroidUserItem = new CAndroidUserItem;
  894. }
  895. catch (...)
  896. {
  897. //错误断言
  898. ASSERT(FALSE);
  899. //删除对象
  900. SafeRelease(pIAndroidUserItemSink);
  901. }
  902. //错误判断
  903. if (pAndroidUserItem == NULL)
  904. {
  905. //错误断言
  906. ASSERT(FALSE);
  907. //删除对象
  908. SafeRelease(pIAndroidUserItemSink);
  909. return NULL;
  910. }
  911. //设置用户
  912. if ((pIAndroidUserItemSink != NULL) && (pIAndroidUserItemSink->Initialization(pAndroidUserItem) == false))
  913. {
  914. //错误断言
  915. ASSERT(FALSE);
  916. //删除对象
  917. SafeRelease(pAndroidUserItem);
  918. SafeRelease(pIAndroidUserItemSink);
  919. return NULL;
  920. }
  921. //设置数组
  922. WORD wCurrentIndex = (WORD)m_AndroidUserItemArray.Add(pAndroidUserItem);
  923. //配置变量
  924. pAndroidUserItem->m_dwMinSitInterval = m_dwMinSitInterval;
  925. pAndroidUserItem->m_dwMaxSitInterval = m_dwMaxSitInterval;
  926. //设置接口
  927. pAndroidUserItem->m_wAndroidIndex = wCurrentIndex + INDEX_ANDROID;
  928. pAndroidUserItem->m_pIServerUserManager = m_pIServerUserManager;
  929. pAndroidUserItem->m_pIAndroidUserItemSink = pIAndroidUserItemSink;
  930. pAndroidUserItem->m_pIAndroidUserManager = QUERY_ME_INTERFACE(IAndroidUserManager);
  931. }
  932. catch (...)
  933. {
  934. ASSERT(FALSE);
  935. return NULL;
  936. }
  937. }
  938. //游戏局数
  939. if ((AndroidItemConfig.pAndroidParameter->dwSwitchMinInnings != 0L) && (AndroidItemConfig.pAndroidParameter->dwSwitchMaxInnings != 0L))
  940. {
  941. //变量定义
  942. DWORD dwSwitchMinInnings = AndroidItemConfig.pAndroidParameter->dwSwitchMinInnings;
  943. DWORD dwSwitchMaxInnings = AndroidItemConfig.pAndroidParameter->dwSwitchMaxInnings;
  944. //调整局数
  945. if ((dwSwitchMaxInnings - dwSwitchMinInnings) > 0L)
  946. pAndroidUserItem->m_AndroidService.dwSwitchTableInnings = dwSwitchMinInnings + rand() % (dwSwitchMaxInnings - dwSwitchMinInnings);
  947. else
  948. pAndroidUserItem->m_AndroidService.dwSwitchTableInnings = dwSwitchMinInnings;
  949. }
  950. else
  951. pAndroidUserItem->m_AndroidService.dwSwitchTableInnings = 0;
  952. //服务类型
  953. if (pAndroidUserItem->m_pIAndroidUserItemSink == NULL && (AndroidItemConfig.pAndroidParameter->dwServiceMode&ANDROID_SIMULATE) != 0)
  954. AndroidItemConfig.pAndroidParameter->dwServiceMode = ANDROID_SIMULATE;
  955. //设置变量
  956. pAndroidUserItem->m_AndroidItemConfig = AndroidItemConfig;
  957. //设置索引
  958. m_AndroidUserItemMap[AndroidItemConfig.AndroidAccountsInfo.dwUserID] = pAndroidUserItem;
  959. return pAndroidUserItem;
  960. }
  961. //强制起立
  962. VOID CAndroidUserManager::ForceAndroidUserItemStandup(CAndroidUserItem * pAndroidUserItem)
  963. {
  964. //校验参数
  965. ASSERT(pAndroidUserItem != NULL);
  966. if (pAndroidUserItem == NULL) return;
  967. //属性变量
  968. WORD wRoundID = pAndroidUserItem->m_wRoundID;
  969. WORD wAndroidIndex = pAndroidUserItem->m_wAndroidIndex;
  970. //构造结构
  971. CMD_GR_UserStandUp UserStandUp;
  972. UserStandUp.cbForceLeave = true;
  973. UserStandUp.wTableID = pAndroidUserItem->m_pIServerUserItem->GetTableID();
  974. UserStandUp.wChairID = pAndroidUserItem->m_pIServerUserItem->GetChairID();
  975. //发送数据
  976. SendDataToServer(MAKELONG(wAndroidIndex, wRoundID), MDM_GR_USER, SUB_GR_USER_STANDUP, &UserStandUp, sizeof(UserStandUp));
  977. return;
  978. }
  979. //////////////////////////////////////////////////////////////////////////////////