ChannelMgr.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:44k
源码类别:

模拟服务器

开发平台:

C/C++

  1. // ChannelMgr.cpp: implementation of the CChannelMgr class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Global.h"
  6. #include "ChannelMgr.h"
  7. #include "S3Relay.h"
  8. #include "time.h"
  9. #include "malloc.h"
  10. #include <list>
  11. #include <map>
  12. /////////////////////////////////////////////////////
  13. static const size_t MAX_SENTLEN = 256;
  14. static const char NUMBER_CHARS[] = "0123456789";
  15. static const char NULL_STR[] = "";
  16. /////////////////////////////////////////////////////
  17. const char file_channcfg[] = "relay_channcfg.ini";
  18. const char sec_system[] = "system";
  19. const char key_nameGM[] = "nameGM";
  20. const char key_charEsc[] = "charEsc";
  21. const char key_charSplt[] = "charSplt";
  22. const char key_defCost[] = "defCost";
  23. const char sec_team[] = "team";
  24. const char sec_faction[] = "faction";
  25. const char sec_tong[] = "tong";
  26. const char sec_screen[] = "screen";
  27. const char sec_broadcast[] = "broadcast";
  28. const char key_escSpec[] = "escSpec";
  29. const char key_minID[] = "minID";
  30. const char key_maxID[] = "maxID";
  31. const char file_relaychann[] = "relay_channel.ini";
  32. const char key_cost[] = "cost";
  33. //////////////////////////////////////////////////////////////////////
  34. // Construction/Destruction
  35. //////////////////////////////////////////////////////////////////////
  36. CChannelMgr::CChannelMgr()
  37. : m_lastChannID(0), m_channidGM(-1),
  38. m_chChannEsc(0), m_chChannSplt(0),
  39. m_chChannTEAM(0), m_chChannFAC(0), m_chChannTONG(0), m_chChannSCRN(0),
  40. m_minTeamID(0), m_maxTeamID(-1), m_minFacID(0), m_maxFacID(-1), m_minTongID(0), m_maxTongID(-1),
  41. m_defCost(0),
  42. m_costTeam(0), m_costFac(0), m_costTong(0), m_costScrn(0), m_costBc(0)
  43. {
  44. }
  45. CChannelMgr::~CChannelMgr()
  46. {
  47. }
  48. BOOL CChannelMgr::Initialize()
  49. {
  50. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  51. m_chChannEsc  = gGetPrivateProfileCharEx(sec_system, key_charEsc, file_channcfg, defCHANN_esc);
  52. m_chChannSplt = gGetPrivateProfileCharEx(sec_system, key_charSplt, file_channcfg, defCHANN_splt);
  53. m_chChannTEAM = gGetPrivateProfileCharEx(sec_team, key_escSpec, file_channcfg, defCHANN_TEAM);
  54. m_chChannFAC  = gGetPrivateProfileCharEx(sec_faction, key_escSpec, file_channcfg, defCHANN_FAC);
  55. m_chChannTONG = gGetPrivateProfileCharEx(sec_tong, key_escSpec, file_channcfg, defCHANN_TONG);
  56. m_chChannSCRN = gGetPrivateProfileCharEx(sec_screen, key_escSpec, file_channcfg, defCHANN_SCRN);
  57. m_chChannBC   = gGetPrivateProfileCharEx(sec_broadcast, key_escSpec, file_channcfg, defCHANN_BC);
  58. m_minTeamID = gGetPrivateProfileIntEx(sec_team, key_minID, file_channcfg, 0);
  59. m_maxTeamID = gGetPrivateProfileIntEx(sec_team, key_maxID, file_channcfg, -1);
  60. m_minFacID = gGetPrivateProfileIntEx(sec_faction, key_minID, file_channcfg, 0);
  61. m_maxFacID = gGetPrivateProfileIntEx(sec_faction, key_maxID, file_channcfg, -1);
  62. m_minTongID = gGetPrivateProfileIntEx(sec_tong, key_minID, file_channcfg, 0);
  63. m_maxTongID = gGetPrivateProfileIntEx(sec_tong, key_maxID, file_channcfg, -1);
  64. m_defCost = (BYTE)gGetPrivateProfileIntEx(sec_system, key_defCost, file_channcfg, 0);
  65. m_costTeam = (BYTE)gGetPrivateProfileIntEx(sec_team, key_cost, file_channcfg, (INT)(UINT)m_defCost);
  66. m_costFac  = (BYTE)gGetPrivateProfileIntEx(sec_faction, key_cost, file_channcfg, (INT)(UINT)m_defCost);
  67. m_costTong = (BYTE)gGetPrivateProfileIntEx(sec_tong, key_cost, file_channcfg, (INT)(UINT)m_defCost);
  68. m_costScrn = (BYTE)gGetPrivateProfileIntEx(sec_screen, key_cost, file_channcfg, (INT)(UINT)m_defCost);
  69. m_costBc   = (BYTE)gGetPrivateProfileIntEx(sec_broadcast, key_cost, file_channcfg, (INT)(UINT)m_defCost);
  70. std::_tstring nameChannGM = gGetPrivateProfileStringEx(sec_system, key_nameGM, file_channcfg);
  71. if (!nameChannGM.empty())
  72. {
  73. //create the channel
  74. m_channidGM = GenChannID();
  75. if (m_channidGM == DWORD(-1))
  76. return FALSE;
  77. m_mapChann2ID[nameChannGM] = m_channidGM;
  78. CHANNINFO& rChannInfo = m_mapChannid2Info[m_channidGM];
  79. rChannInfo.god = TRUE;
  80. rChannInfo.stock = TRUE;
  81. rChannInfo.channname = nameChannGM;
  82. rChannInfo.gmuse = FALSE;
  83. rChannInfo.gmsub = FALSE;
  84. rChannInfo.cost = (BYTE)gGetPrivateProfileIntEx(nameChannGM.c_str(), key_cost, file_relaychann, (INT)(UINT)m_defCost);
  85. rTRACE("Create Channel: [Stock, GM] <%08X> %s", m_channidGM, nameChannGM.c_str());
  86. }
  87. const std::vector<std::_tstring>& rVecChann = gGetPrivateProfileSectionNamesEx(file_relaychann);
  88. for (std::vector<std::_tstring>::const_iterator it = rVecChann.begin(); it != rVecChann.end(); it++)
  89. {
  90. std::_tstring channname = *it;
  91. assert(!channname.empty());
  92. if (_tstring_equal()(channname, nameChannGM)) //gm, created already
  93. continue;
  94. DWORD channid = GenChannID();
  95. if (channid == DWORD(-1))
  96. return FALSE;
  97. m_mapChann2ID[channname] = channid;
  98. CHANNINFO& rChannInfo = m_mapChannid2Info[channid];
  99. rChannInfo.god = FALSE;
  100. rChannInfo.stock = TRUE;
  101. rChannInfo.channname = channname;
  102. rChannInfo.gmuse = FALSE;
  103. rChannInfo.gmsub = FALSE;
  104. rChannInfo.cost = (BYTE)gGetPrivateProfileIntEx(channname.c_str(), key_cost, file_relaychann, (INT)(UINT)m_defCost);
  105. rTRACE("Create Channel: [Stock] <%08X> %s", channid, channname.c_str());
  106. }
  107. return TRUE;
  108. }
  109. BOOL CChannelMgr::Uninitialize()
  110. {
  111. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  112. m_mapChann2ID.clear();
  113. m_mapChannid2Info.clear();
  114. m_defCost = 0;
  115. m_costTeam = 0;
  116. m_costFac  = 0;
  117. m_costTong = 0;
  118. m_costScrn = 0;
  119. m_costBc   = 0;
  120. m_channidGM = -1;
  121. m_chChannEsc = 0;
  122. m_chChannSplt = 0;
  123. m_chChannTEAM = 0;
  124. m_chChannFAC = 0;
  125. m_chChannSCRN = 0;
  126. m_chChannBC = 0;
  127. m_minTeamID = 0;
  128. m_maxTeamID = -1;
  129. m_minFacID = 0;
  130. m_maxFacID = -1;
  131. m_minTongID = 0;
  132. m_maxTongID = -1;
  133. return TRUE;
  134. }
  135. DWORD CChannelMgr::GenChannID()
  136. {
  137. //assert(m_lockChannel._IsWriting());
  138. if (m_lastChannID != DWORD(-1))
  139. return m_lastChannID++;
  140. //no base idle, then search idle
  141. DWORD id = 0;
  142. for (CHANNID2INFOMAP::iterator it = m_mapChannid2Info.begin(); it != m_mapChannid2Info.end(); it++)
  143. {
  144. if ((*it).first != id)
  145. return id;
  146. id ++;
  147. }
  148. return id;
  149. }
  150. std::_tstring CChannelMgr::GetChannelName(DWORD channelid, BOOL adv)
  151. {
  152. DUMMY_AUTOLOCKREAD(m_lockChannel);
  153. CHANNID2INFOMAP::const_iterator it = m_mapChannid2Info.find(channelid);
  154. if (it == m_mapChannid2Info.end())
  155. return NULL_STR;
  156. std::_tstring channname = (*it).second.channname;
  157. return adv ? channname : ReduceChannelName(channname);
  158. }
  159. DWORD CChannelMgr::GetChannelID(const std::_tstring& channname, DWORD advIP)
  160. {
  161. std::_tstring advChannName = advIP == 0 ? channname : MakeChannelName(channname, advIP);
  162. if (advChannName.empty())
  163. return -1;
  164. DUMMY_AUTOLOCKREAD(m_lockChannel);
  165. CHANN2IDMAP::iterator it = m_mapChann2ID.find(advChannName);
  166. if (it == m_mapChann2ID.end())
  167. return -1;
  168. return (*it).second;
  169. }
  170. BOOL CChannelMgr::IsSubscribed(DWORD ip, unsigned long param, DWORD channid)
  171. {
  172. DUMMY_AUTOLOCKREAD(m_lockChannel);
  173. CHANNID2INFOMAP::iterator itChannid = m_mapChannid2Info.find(channid);
  174. if (itChannid == m_mapChannid2Info.end())
  175. return FALSE;
  176. CHANNINFO& rChannInfo = (*itChannid).second;
  177. IP2PLAYERSMAP::iterator itIP = rChannInfo.mapIp2Players.find(ip);
  178. if (itIP == rChannInfo.mapIp2Players.end())
  179. return FALSE;
  180. PLAYERSMAP& rPlayers = (*itIP).second;
  181. PLAYERSMAP::iterator itRole = rPlayers.find(param);
  182. if (itRole == rPlayers.end())
  183. return FALSE;
  184. PLAYERINFO& rInfo = (*itRole).second;
  185. return rInfo.subed;
  186. }
  187. BOOL CChannelMgr::GmSubscribe(DWORD channid)
  188. {
  189. if (channid == -1)
  190. return FALSE;
  191. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  192. if (channid == m_channidGM)
  193. return TRUE;
  194. CHANNID2INFOMAP::iterator it = m_mapChannid2Info.find(channid);
  195. if (it == m_mapChannid2Info.end())
  196. return FALSE;
  197. CHANNINFO& rChannInfo = (*it).second;
  198. if (!rChannInfo.gmuse)
  199. return FALSE;
  200. rChannInfo.gmsub = TRUE;
  201. return TRUE;
  202. }
  203. BOOL CChannelMgr::GmUnsubscribe(DWORD channid)
  204. {
  205. if (channid == m_channidGM)
  206. return FALSE;
  207. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  208. CHANNID2INFOMAP::iterator it = m_mapChannid2Info.find(channid);
  209. if (it == m_mapChannid2Info.end())
  210. return FALSE;
  211. CHANNINFO& rChannInfo = (*it).second;
  212. if (!rChannInfo.gmuse)
  213. return FALSE;
  214. rChannInfo.gmsub = FALSE;
  215. return TRUE;
  216. }
  217. BOOL CChannelMgr::IsGmSubscribed(DWORD channid)
  218. {
  219. if (channid == m_channidGM)
  220. return TRUE;
  221. DUMMY_AUTOLOCKREAD(m_lockChannel);
  222. CHANNID2INFOMAP::iterator it = m_mapChannid2Info.find(channid);
  223. if (it == m_mapChannid2Info.end())
  224. return FALSE;
  225. CHANNINFO& rChannInfo = (*it).second;
  226. return rChannInfo.gmsub;
  227. }
  228. BOOL CChannelMgr::GmQueryChannelID(const std::_tstring& channel, BOOL force)
  229. {
  230. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  231. DWORD theChannID = -1;
  232. BYTE cost = 0;
  233. CHANN2IDMAP::iterator it = m_mapChann2ID.find(channel);
  234. if (it != m_mapChann2ID.end())
  235. {//channel exist
  236. DWORD channid = (*it).second;
  237. CHANNINFO& rChannInfo = m_mapChannid2Info[channid];
  238. rChannInfo.gmuse = TRUE;
  239. theChannID = channid;
  240. cost = rChannInfo.cost;
  241. }
  242. else
  243. {
  244. if (force)
  245. {
  246. //erase the channel
  247. DWORD channid = GenChannID();
  248. if (channid != DWORD(-1))
  249. {
  250. m_mapChann2ID[channel] = channid;
  251. CHANNINFO& rChannInfo = m_mapChannid2Info[channid];
  252. rChannInfo.god = FALSE;
  253. rChannInfo.stock = FALSE;
  254. rChannInfo.channname = channel;
  255. rChannInfo.gmuse = TRUE;
  256. rChannInfo.gmsub = FALSE;
  257. rChannInfo.cost = GainPreCost(channel);
  258. rTRACE("GM Create Channel: <%08X> %s", channid, channel.c_str());
  259. theChannID = channid;
  260. cost = rChannInfo.cost;
  261. }
  262. }
  263. }
  264. {{
  265. size_t pckgsize = sizeof(RELAY_ASKWAY_DATA) + sizeof(PLAYERCOMM_NOTIFYCHANNELID);
  266. RELAY_ASKWAY_DATA* pAskWayData = (RELAY_ASKWAY_DATA*)_alloca(pckgsize);
  267. pAskWayData->ProtocolFamily = pf_relay;
  268. pAskWayData->ProtocolID = relay_c2c_askwaydata;
  269. pAskWayData->nFromIP = 0;
  270. pAskWayData->nFromRelayID = -1;
  271. pAskWayData->seekRelayCount = 0;
  272. pAskWayData->seekMethod = rm_gm;
  273. pAskWayData->wMethodDataLength = 0;
  274. pAskWayData->routeDateLength = sizeof(PLAYERCOMM_NOTIFYCHANNELID);
  275. PLAYERCOMM_NOTIFYCHANNELID* pPlayerCommNotiChannID = (PLAYERCOMM_NOTIFYCHANNELID*)(pAskWayData + 1);
  276. pPlayerCommNotiChannID->ProtocolFamily = pf_playercommunity;
  277. pPlayerCommNotiChannID->ProtocolID = playercomm_s2c_notifychannelid;
  278. strcpy(pPlayerCommNotiChannID->channel, channel.c_str());
  279. pPlayerCommNotiChannID->channelid = theChannID;
  280. pPlayerCommNotiChannID->cost = cost;
  281. g_RootClient.SendPackage(pAskWayData, pckgsize);
  282. }}
  283. return TRUE;
  284. }
  285. BOOL CChannelMgr::GmFreeChannID(DWORD channid)
  286. {
  287. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  288. CHANNID2INFOMAP::iterator it = m_mapChannid2Info.find(channid);
  289. if (it == m_mapChannid2Info.end())
  290. return FALSE;
  291. CHANNINFO& rChannInfo = (*it).second;
  292. //ensure
  293. assert(!rChannInfo.gmsub);
  294. rChannInfo.gmsub = FALSE;
  295. rChannInfo.gmuse = FALSE;
  296. if (!rChannInfo.stock
  297. && rChannInfo.mapIp2Players.empty())
  298. {
  299. rTRACE("GM Destroy Channel: <%08X> %s", channid, rChannInfo.channname.c_str());
  300. m_mapChann2ID.erase(rChannInfo.channname);
  301. m_mapChannid2Info.erase(it);
  302. }
  303. return TRUE;
  304. }
  305. BOOL CChannelMgr::IsUsed(DWORD ip, unsigned long param, DWORD channid)
  306. {
  307. DUMMY_AUTOLOCKREAD(m_lockChannel);
  308. CHANNID2INFOMAP::iterator itChannid = m_mapChannid2Info.find(channid);
  309. if (itChannid == m_mapChannid2Info.end())
  310. return FALSE;
  311. CHANNINFO& rChannInfo = (*itChannid).second;
  312. IP2PLAYERSMAP::iterator itIP = rChannInfo.mapIp2Players.find(ip);
  313. if (itIP == rChannInfo.mapIp2Players.end())
  314. return FALSE;
  315. PLAYERSMAP& rPlayers = (*itIP).second;
  316. PLAYERSMAP::iterator itRole = rPlayers.find(param);
  317. return itRole != rPlayers.end();
  318. }
  319. BOOL CChannelMgr::IsGmUsed(DWORD channid)
  320. {
  321. DUMMY_AUTOLOCKREAD(m_lockChannel);
  322. CHANNID2INFOMAP::iterator it = m_mapChannid2Info.find(channid);
  323. if (it == m_mapChannid2Info.end())
  324. return FALSE;
  325. CHANNINFO& rChannInfo = (*it).second;
  326. return rChannInfo.gmuse;
  327. }
  328. std::_tstring CChannelMgr::MakeChannelName(const std::_tstring& chann, DWORD ip)
  329. {
  330. if (chann.empty())
  331. return NULL_STR;
  332. if (chann[0] != m_chChannEsc)
  333. return chann;
  334. if (chann.size() < 2)
  335. return NULL_STR;
  336. if (chann[1] == m_chChannTEAM
  337. || chann[1] == m_chChannFAC
  338. || chann[1] == m_chChannTONG)
  339. {
  340. if (chann.size() <= 2)
  341. return NULL_STR;
  342. if (chann.find_last_not_of(NUMBER_CHARS) > 1)
  343. return NULL_STR;
  344. DWORD id = _ttol(chann.c_str() + 2);
  345. if (chann[1] == m_chChannFAC)
  346. return IsValidFacID(id) ? chann : NULL_STR;
  347. if (chann[1] == m_chChannTONG)
  348. return IsValidTongID(id) ? chann : NULL_STR;
  349. if (ip == 0 || !IsValidTeamID(id))
  350. return NULL_STR;
  351. char buffer[16];
  352. std::_tstring channname(chann);
  353. channname += m_chChannSplt;
  354. channname += _ultot(ip, buffer, 10);
  355. return channname;
  356. }
  357. else if (chann[1] == m_chChannSCRN
  358. || chann[1] == m_chChannBC)
  359. {
  360. if (chann.size() > 2)
  361. return NULL_STR;
  362. char buffer[16];
  363. std::_tstring channname(chann);
  364. channname += _ultot(ip, buffer, 10);
  365. return channname;
  366. }
  367. return NULL_STR;
  368. }
  369. std::_tstring CChannelMgr::ReduceChannelName(const std::_tstring& chann)
  370. {
  371. if (chann.empty())
  372. return NULL_STR;
  373. if (chann[0] != m_chChannEsc)
  374. return chann;
  375. if (chann.size() < 2)
  376. return NULL_STR;
  377. if (chann[1] == m_chChannTEAM)
  378. {
  379. int spltpos = chann.find_last_of(m_chChannSplt);
  380. if (spltpos == -1)
  381. return NULL_STR;
  382. return std::_tstring(chann.c_str(), spltpos);
  383. }
  384. if (chann[1] == m_chChannFAC
  385. || chann[1] == m_chChannTONG)
  386. {
  387. return chann;
  388. }
  389. if (chann[1] == m_chChannSCRN
  390. || chann[1] == m_chChannBC)
  391. {
  392. return std::_tstring(chann.c_str(), 2);
  393. }
  394. assert(FALSE);
  395. return NULL_STR;
  396. }
  397. DWORD CChannelMgr::ParseChannelName(const std::_tstring& chann, DWORD* pIP)
  398. {
  399. if (pIP != NULL)
  400. *pIP = 0;
  401. if (chann.empty())
  402. return -1;
  403. if (chann[0] != m_chChannEsc)
  404. return -1;
  405. if (chann.size() < 2)
  406. return -1;
  407. std::_tstring basechann;
  408. if (chann[1] == m_chChannTEAM)
  409. {
  410. int spltpos = chann.find_last_of(m_chChannSplt);
  411. if (spltpos == -1)
  412. return -1;
  413. if (pIP != NULL)
  414. *pIP = _ttol(chann.c_str() + spltpos + 1);
  415. return _ttol(chann.c_str() + 2);
  416. }
  417. if (chann[1] == m_chChannFAC
  418. || chann[1] == m_chChannTONG)
  419. {
  420. return _ttol(chann.c_str() + 2);
  421. }
  422. if (chann[1] == m_chChannSCRN
  423. || chann[1] == m_chChannBC)
  424. {
  425. if (pIP != NULL)
  426. *pIP = _ttol(chann.c_str() + 2);
  427. return 0;
  428. }
  429. return -1;
  430. }
  431. BYTE CChannelMgr::GainPreCost(const std::_tstring& channel)
  432. {
  433. if (channel.size() >= 2 && channel[0] == m_chChannEsc)
  434. {
  435. if (channel[1] == m_chChannTEAM)
  436. return m_costTeam;
  437. else if (channel[1] == m_chChannFAC)
  438. return m_costFac;
  439. else if (channel[1] == m_chChannTONG)
  440. return m_costTong;
  441. else if (channel[1] == m_chChannSCRN)
  442. return m_costScrn;
  443. else if (channel[1] == m_chChannBC)
  444. return m_costBc;
  445. }
  446. return m_defCost;
  447. }
  448. DWORD CChannelMgr::GetGMChannID()
  449. {
  450. return m_channidGM;
  451. }
  452. BOOL CChannelMgr::IsGodChannel(DWORD channid)
  453. {
  454. DUMMY_AUTOLOCKREAD(m_lockChannel);
  455. CHANNID2INFOMAP::const_iterator it = m_mapChannid2Info.find(channid);
  456. if (it == m_mapChannid2Info.end())
  457. return FALSE;
  458. const CHANNINFO& rChannInfo = (*it).second;
  459. return rChannInfo.god;
  460. }
  461. BOOL CChannelMgr::IsStockChannel(DWORD channid)
  462. {
  463. DUMMY_AUTOLOCKREAD(m_lockChannel);
  464. CHANNID2INFOMAP::const_iterator it = m_mapChannid2Info.find(channid);
  465. if (it == m_mapChannid2Info.end())
  466. return FALSE;
  467. const CHANNINFO& rChannInfo = (*it).second;
  468. return rChannInfo.stock;
  469. }
  470. BOOL CChannelMgr::PassToSpecMan(DWORD ToIP, unsigned long ToRelayID, DWORD ToNameID, const void* pData, size_t size)
  471. {
  472. CNetConnectDup conndup = g_ChatServer.FindChatConnectByIP(ToIP);
  473. if (!conndup.IsValid())
  474. return FALSE;
  475. size_t pckgsize = sizeof(CHAT_SPECMAN) + size;
  476. CHAT_SPECMAN* pCsm = (CHAT_SPECMAN*)_alloca(pckgsize);
  477. pCsm->ProtocolType = chat_specman;
  478. pCsm->wSize = pckgsize - 1;
  479. pCsm->nameid = ToNameID;
  480. pCsm->lnID = ToRelayID;
  481. pCsm->wChatLength = size;
  482. void* pExPckg = pCsm + 1;
  483. memcpy(pExPckg, pData, size);
  484. conndup.SendPackage(pCsm, pckgsize);
  485. return TRUE;
  486. }
  487. BOOL CChannelMgr::PassToGroupMan(DWORD ToIP, BOOL verify, const MANLIST& mans, const void* pData, size_t size)
  488. {
  489. if (mans.empty())
  490. return TRUE;
  491. const size_t playerlen = verify ? sizeof(tagPlusSrcInfo) : sizeof(WORD);
  492. size_t basesize = sizeof(CHAT_GROUPMAN) + size;
  493. if (basesize + playerlen > max_packagesize)
  494. return FALSE;
  495. CNetConnectDup conndup = g_ChatServer.FindChatConnectByIP(ToIP);
  496. if (!conndup.IsValid())
  497. return FALSE;
  498. BYTE buffer[max_packagesize];
  499. CHAT_GROUPMAN* pCgm = (CHAT_GROUPMAN*)buffer;
  500. pCgm->ProtocolType = chat_groupman;
  501. pCgm->wChatLength = size;
  502. pCgm->byHasIdentify = (BYTE)verify;
  503. void* pExPckg = pCgm + 1;
  504. memcpy(pExPckg, pData, size);
  505. size_t cursor = basesize;
  506. for (MANLIST::const_iterator it = mans.begin(); it != mans.end(); it++)
  507. {
  508. if (verify)
  509. *(tagPlusSrcInfo*)(buffer + cursor) = *it;
  510. else
  511. *(WORD*)(buffer + cursor)= (WORD)(*it).lnID;
  512. cursor += playerlen;
  513. if (cursor + playerlen > max_packagesize)
  514. {
  515. assert((cursor - basesize) % playerlen == 0);
  516. pCgm->wSize = cursor - 1;
  517. pCgm->wPlayerCount = (cursor - basesize) / playerlen;
  518. conndup.SendPackage(buffer, cursor);
  519. cursor = basesize;
  520. }
  521. }
  522. if (cursor > basesize)
  523. {
  524. assert((cursor - basesize) % playerlen == 0);
  525. pCgm->wSize = cursor - 1;
  526. pCgm->wPlayerCount = (cursor - basesize) / playerlen;
  527. conndup.SendPackage(buffer, cursor);
  528. }
  529. return TRUE;
  530. }
  531. BOOL CChannelMgr::PassToGM(const void* pData, size_t size)
  532. {
  533. size_t pckgsize = sizeof(RELAY_ASKWAY_DATA) + size;
  534. RELAY_ASKWAY_DATA* pAskWayData = (RELAY_ASKWAY_DATA*)_alloca(pckgsize);
  535. pAskWayData->ProtocolFamily = pf_relay;
  536. pAskWayData->ProtocolID = relay_c2c_askwaydata;
  537. pAskWayData->nFromIP = 0;
  538. pAskWayData->nFromRelayID = 0;
  539. pAskWayData->seekRelayCount = 0;
  540. pAskWayData->seekMethod = rm_gm;
  541. pAskWayData->wMethodDataLength = 0;
  542. pAskWayData->routeDateLength = size;
  543. void* pExPckg = pAskWayData + 1;
  544. memcpy(pExPckg, pData, size);
  545. g_RootClient.SendPackage(pAskWayData, pckgsize);
  546. return TRUE;
  547. }
  548. BOOL CChannelMgr::IsValidTeamID(DWORD idTeam)
  549. {
  550. if (m_minTeamID > m_maxTeamID)
  551. return TRUE;
  552. return idTeam >= m_minTeamID && idTeam <= m_maxTeamID;
  553. }
  554. BOOL CChannelMgr::IsValidFacID(DWORD idFac)
  555. {
  556. if (m_minFacID > m_maxFacID)
  557. return TRUE;
  558. return idFac >= m_minFacID && idFac <= m_maxFacID;
  559. }
  560. BOOL CChannelMgr::IsValidTongID(DWORD idTong)
  561. {
  562. if (m_minTongID > m_maxTongID)
  563. return TRUE;
  564. return idTong >= m_minTongID && idTong <= m_maxTongID;
  565. }
  566. BOOL CChannelMgr::SomeoneChat(DWORD srcIP, const tagPlusSrcInfo& SrcInfo, const CHAT_SOMEONECHAT_CMD* pSomeoneChatCmd)
  567. {
  568. if (pSomeoneChatCmd->sentlen <= 0 || pSomeoneChatCmd->sentlen > MAX_SENTLEN)
  569. return FALSE;
  570. if (!gIsLegalString(pSomeoneChatCmd->someone, 1, _NAME_LEN))
  571. return FALSE;
  572. std::_tstring srcrole;
  573. if (!g_HostServer.FindPlayerByIpParam(NULL, srcIP, SrcInfo.lnID, NULL, NULL, &srcrole, NULL))
  574. return FALSE;
  575. BOOL sent = FALSE;
  576. CNetConnectDup hostconndup;
  577. DWORD nameid = 0;
  578. unsigned long param = 0;
  579. if (g_HostServer.FindPlayerByRole(NULL, std::_tstring(pSomeoneChatCmd->someone), &hostconndup, NULL, &nameid, &param))
  580. {
  581. size_t syncsize = sizeof(CHAT_SOMEONECHAT_SYNC) + pSomeoneChatCmd->sentlen;
  582. CHAT_SOMEONECHAT_SYNC* pCscSync = (CHAT_SOMEONECHAT_SYNC*)_alloca(syncsize);
  583. pCscSync->ProtocolType = chat_someonechat;
  584. pCscSync->wSize = syncsize - 1;
  585. pCscSync->packageID = pSomeoneChatCmd->packageID;
  586. strcpy(pCscSync->someone, srcrole.c_str());
  587. pCscSync->sentlen = pSomeoneChatCmd->sentlen;
  588. memcpy(pCscSync + 1, pSomeoneChatCmd + 1, pSomeoneChatCmd->sentlen);
  589. if (PassToSpecMan(hostconndup.GetIP(), param, nameid, pCscSync, syncsize))
  590. sent = TRUE;
  591. }
  592. {{
  593. size_t _exsize = sizeof(DWORD) + _NAME_LEN + sizeof(BYTE) + pSomeoneChatCmd->sentlen; ////X
  594. size_t feedbacksize = sizeof(CHAT_FEEDBACK) + _exsize;
  595. CHAT_FEEDBACK* pCfb = (CHAT_FEEDBACK*)_alloca(feedbacksize);
  596. pCfb->ProtocolType = chat_feedback;
  597. pCfb->packageID = pSomeoneChatCmd->packageID;
  598. pCfb->code = sent ? codeSucc : codeFail;
  599. ////X
  600. DWORD* pChannelid = (DWORD*)(pCfb + 1);
  601. *pChannelid = -1;
  602. char* pDstName = (char*)(pChannelid + 1);
  603. strcpy(pDstName, pSomeoneChatCmd->someone);
  604. BYTE* pSentlen = (BYTE*)(pDstName + _NAME_LEN);
  605. *pSentlen = pSomeoneChatCmd->sentlen;
  606. void* pSent = pSentlen + 1;
  607. memcpy(pSent, pSomeoneChatCmd + 1, pSomeoneChatCmd->sentlen);
  608. ////X
  609. PassToSpecMan(srcIP, SrcInfo.lnID, SrcInfo.nameid, pCfb, feedbacksize);
  610. }}
  611. // dTRACE("Chat Someone: sentence %u Bs from [%s] to [%s]", pSomeoneChatCmd->sentlen, srcrole.c_str(), pSomeoneChatCmd->someone);
  612. return TRUE;
  613. }
  614. BOOL CChannelMgr::ChannelChat(DWORD srcIP, const tagPlusSrcInfo& SrcInfo, const CHAT_CHANNELCHAT_CMD* pChannelChatCmd)
  615. {
  616. if (pChannelChatCmd->channelid == -1)
  617. return FALSE;
  618. if (pChannelChatCmd->sentlen <= 0 || pChannelChatCmd->sentlen > MAX_SENTLEN)
  619. return FALSE;
  620. std::_tstring srcacc;
  621. std::_tstring srcrole;
  622. if (!g_HostServer.FindPlayerByIpParam(NULL, srcIP, SrcInfo.lnID, NULL, &srcacc, &srcrole, NULL))
  623. return FALSE;
  624. BOOL sent = FALSE;
  625. DUMMY_AUTOLOCKREAD(m_lockChannel);
  626. CHANNID2INFOMAP::iterator itChannid = m_mapChannid2Info.find(pChannelChatCmd->channelid);
  627. if (itChannid == m_mapChannid2Info.end())
  628. return FALSE;
  629. CHANNINFO& rChannInfo = (*itChannid).second;
  630. if (pChannelChatCmd->cost != rChannInfo.cost)
  631. return FALSE;
  632. if (rChannInfo.god)
  633. {
  634. if (g_RootClient.IsReady())
  635. {
  636. size_t pckgsize = sizeof(CHAT_MSG_EX) + pChannelChatCmd->sentlen;
  637. CHAT_MSG_EX* pChatMsgEx = (CHAT_MSG_EX*)_alloca(pckgsize);
  638. pChatMsgEx->ProtocolFamily = pf_playercommunity;
  639. pChatMsgEx->ProtocolID = playercomm_channelchat;
  640. strcpy(pChatMsgEx->m_szSourceName, srcrole.c_str());
  641. strcpy(pChatMsgEx->m_szAccountName, srcacc.c_str());
  642. pChatMsgEx->SentenceLength = pChannelChatCmd->sentlen;
  643. memcpy(pChatMsgEx + 1, pChannelChatCmd + 1, pChannelChatCmd->sentlen);
  644. PassToGM(pChatMsgEx, pckgsize);
  645. sent = TRUE;
  646. }
  647. }
  648. else
  649. {
  650. if (IsNeedRelegate(rChannInfo.channname, pChannelChatCmd->filter))
  651. {//relegate to gamesvr
  652. assert(rChannInfo.channname[0] == m_chChannEsc);
  653. DWORD channIP = 0;
  654. DWORD theID = ParseChannelName(rChannInfo.channname, &channIP);
  655. if (theID == -1 && channIP == 0)
  656. return FALSE;
  657. assert(rChannInfo.channname.size() >= 2);
  658. size_t syncsize = sizeof(CHAT_CHANNELCHAT_SYNC) + pChannelChatCmd->sentlen;
  659. size_t pckgsize = sizeof(CHAT_RELEGATE) + syncsize;
  660. CHAT_RELEGATE* pCr = (CHAT_RELEGATE*)_alloca(pckgsize);
  661. pCr->ProtocolType = chat_relegate;
  662. pCr->wSize = pckgsize - 1;
  663. pCr->nFromIP = srcIP;
  664. pCr->nFromRelayID = SrcInfo.lnID;
  665. pCr->channelid = pChannelChatCmd->channelid;
  666. pCr->routeDateLength = syncsize;
  667. CHAT_CHANNELCHAT_SYNC* pCccSync = (CHAT_CHANNELCHAT_SYNC*)(pCr + 1);
  668. pCccSync->ProtocolType = chat_channelchat;
  669. pCccSync->wSize = syncsize - 1;
  670. pCccSync->packageID = pChannelChatCmd->packageID;
  671. strcpy(pCccSync->someone, srcrole.c_str());
  672. pCccSync->channelid = pChannelChatCmd->channelid;
  673. pCccSync->sentlen = pChannelChatCmd->sentlen;
  674. memcpy(pCccSync + 1, pChannelChatCmd + 1, pChannelChatCmd->sentlen);
  675. if (rChannInfo.channname[1] == m_chChannTEAM)
  676. {
  677. if (theID == -1 || channIP == 0)
  678. return FALSE;
  679. CHANNINFO& rChannInfo = (*itChannid).second;
  680. CNetConnectDup connDup = g_ChatServer.FindChatConnectByIP(channIP);
  681. if (connDup.IsValid())
  682. {
  683. pCr->TargetCls = tgtcls_team;
  684. pCr->TargetID = theID;
  685. connDup.SendPackage(pCr, pckgsize);
  686. sent = TRUE;
  687. }
  688. }
  689. else if (rChannInfo.channname[1] == m_chChannFAC)
  690. {
  691. if (theID == -1)
  692. return FALSE;
  693. pCr->TargetCls = tgtcls_fac;
  694. pCr->TargetID = theID;
  695. g_ChatServer.BroadPackage(pCr, pckgsize);
  696. sent = TRUE;
  697. }
  698. else if (rChannInfo.channname[1] == m_chChannTONG)
  699. {
  700. if (theID == -1)
  701. return FALSE;
  702. pCr->TargetCls = tgtcls_tong;
  703. pCr->TargetID = theID;
  704. g_ChatServer.BroadPackage(pCr, pckgsize);
  705. sent = TRUE;
  706. }
  707. else if (rChannInfo.channname[1] == m_chChannSCRN
  708. || rChannInfo.channname[1] == m_chChannBC)
  709. {
  710. if (channIP == 0)
  711. return FALSE;
  712. assert(channIP != 0 && theID == 0);
  713. CNetConnectDup connDup = g_ChatServer.FindChatConnectByIP(channIP);
  714. if (connDup.IsValid())
  715. {
  716. BOOL isScrn = rChannInfo.channname[1] == m_chChannSCRN;
  717. pCr->TargetCls = isScrn ? tgtcls_scrn : tgtcls_bc;
  718. pCr->TargetID = isScrn ? SrcInfo.lnID : 0;
  719. connDup.SendPackage(pCr, pckgsize);
  720. sent = TRUE;
  721. }
  722. }
  723. else
  724. {
  725. assert(FALSE);
  726. return FALSE;
  727. }
  728. }
  729. else
  730. {//broad on channel
  731. //== PassToPlayer
  732. //do like this for optimize
  733. size_t syncsize = sizeof(CHAT_CHANNELCHAT_SYNC) + pChannelChatCmd->sentlen;
  734. CHAT_CHANNELCHAT_SYNC* pCccSync = (CHAT_CHANNELCHAT_SYNC*)_alloca(syncsize);
  735. pCccSync->ProtocolType = chat_channelchat;
  736. pCccSync->wSize = syncsize - 1;
  737. pCccSync->packageID = pChannelChatCmd->packageID;
  738. strcpy(pCccSync->someone, srcrole.c_str());
  739. pCccSync->channelid = pChannelChatCmd->channelid;
  740. pCccSync->sentlen = pChannelChatCmd->sentlen;
  741. memcpy(pCccSync + 1, pChannelChatCmd + 1, pChannelChatCmd->sentlen);
  742. for (IP2PLAYERSMAP::iterator itIP = rChannInfo.mapIp2Players.begin(); itIP != rChannInfo.mapIp2Players.end(); itIP++)
  743. {
  744. DWORD IP = (*itIP).first;
  745. PLAYERSMAP& rPlayers = (*itIP).second;
  746. MANLIST mans;
  747. for (PLAYERSMAP::iterator itPlayer = rPlayers.begin(); itPlayer != rPlayers.end(); itPlayer++)
  748. {
  749. DWORD param = (*itPlayer).first;
  750. PLAYERINFO& rInfo = (*itPlayer).second;
  751. if (rInfo.subed)
  752. {
  753. tagPlusSrcInfo friendInfo;
  754. friendInfo.nameid = rInfo.nameid;
  755. friendInfo.lnID = param;
  756. mans.push_back(friendInfo);
  757. }
  758. }
  759. if (!mans.empty())
  760. {
  761. PassToGroupMan(IP, FALSE, mans, pCccSync, syncsize);
  762. }
  763. }
  764. sent = TRUE;
  765. }
  766. }
  767. // {{
  768. // size_t _exsize = sizeof(DWORD) + sizeof(BYTE) + pChannelChatCmd->sentlen; ////X
  769. // size_t feedbacksize = sizeof(CHAT_FEEDBACK) + _exsize;
  770. // CHAT_FEEDBACK* pCfb = (CHAT_FEEDBACK*)_alloca(feedbacksize);
  771. // pCfb->ProtocolType = chat_feedback;
  772. // pCfb->packageID = pChannelChatCmd->packageID;
  773. // pCfb->code = sent ? codeSucc : codeFail;
  774. //
  775. // ////X
  776. // DWORD* pChannelid = (DWORD*)(pCfb + 1);
  777. // *pChannelid = pChannelChatCmd->channelid;
  778. // BYTE* pSentlen = (BYTE*)(pChannelid + 1);
  779. // *pSentlen = pChannelChatCmd->sentlen;
  780. // void* pSent = pSentlen + 1;
  781. // memcpy(pSent, pChannelChatCmd + 1, pChannelChatCmd->sentlen);
  782. // ////X
  783. //
  784. // PassToSpecMan(srcIP, SrcInfo.lnID, SrcInfo.nameid, pCfb, feedbacksize);
  785. // }}
  786. // dTRACE("Chat Channel: sentence %u Bs from [%s] on <%08X>", pChannelChatCmd->sentlen, srcrole.c_str(), pChannelChatCmd->channelid);
  787. return TRUE;
  788. }
  789. BOOL CChannelMgr::IsNeedRelegate(const std::_tstring& channname, BOOL filter)
  790. {
  791. if (channname[0] != m_chChannEsc)
  792. return FALSE;
  793. if (channname[1] == m_chChannSCRN)
  794. return TRUE;
  795. return !filter;
  796. }
  797. BOOL CChannelMgr::QueryChannelID(const std::_tstring& channel, DWORD ip, unsigned long param, DWORD nameid)
  798. {
  799. assert(FALSE);
  800. return FALSE;
  801. BLOCKCHANNELOP_QID* pOp = m_allcQID.allocate(1, NULL);
  802. pOp->opr = _BLOCKCHANNELOP::op_querychannelid;
  803. pOp->param = param;
  804. pOp->channelname = channel;
  805. pOp->nameid = nameid;
  806. DUMMY_AUTOLOCKWRITE(m_lockBlockOp);
  807. BLOCKOPLIST& rOps = m_mapIp2Ops[ip];
  808. rOps.push_back(pOp);
  809. return TRUE;
  810. }
  811. BOOL CChannelMgr::Subscribe(DWORD ip, unsigned long param, DWORD channelid)
  812. {
  813. assert(FALSE);
  814. return FALSE;
  815. BLOCKCHANNELOP_CMN* pOp = m_allcCMN.allocate(1, NULL);
  816. pOp->opr = _BLOCKCHANNELOP::op_subscribe;
  817. pOp->param = param;
  818. pOp->channelid = channelid;
  819. DUMMY_AUTOLOCKWRITE(m_lockBlockOp);
  820. BLOCKOPLIST& rOps = m_mapIp2Ops[ip];
  821. rOps.push_back(pOp);
  822. return TRUE;
  823. }
  824. BOOL CChannelMgr::Unsubscribe(DWORD ip, unsigned long param, DWORD channelid)
  825. {
  826. assert(FALSE);
  827. return FALSE;
  828. BLOCKCHANNELOP_CMN* pOp = m_allcCMN.allocate(1, NULL);
  829. pOp->opr = _BLOCKCHANNELOP::op_unsubscribe;
  830. pOp->param = param;
  831. pOp->channelid = channelid;
  832. DUMMY_AUTOLOCKWRITE(m_lockBlockOp);
  833. BLOCKOPLIST& rOps = m_mapIp2Ops[ip];
  834. rOps.push_back(pOp);
  835. return TRUE;
  836. }
  837. BOOL CChannelMgr::FreeChannID(DWORD channid, DWORD ip, unsigned long param)
  838. {
  839. assert(FALSE);
  840. return FALSE;
  841. BLOCKCHANNELOP_CMN* pOp = m_allcCMN.allocate(1, NULL);
  842. pOp->opr = _BLOCKCHANNELOP::op_freechannelid;
  843. pOp->param = param;
  844. pOp->channelid = channid;
  845. DUMMY_AUTOLOCKWRITE(m_lockBlockOp);
  846. BLOCKOPLIST& rOps = m_mapIp2Ops[ip];
  847. rOps.push_back(pOp);
  848. return TRUE;
  849. }
  850. BOOL CChannelMgr::ClearPlayer(DWORD ip, unsigned long param)
  851. {
  852. assert(FALSE);
  853. return FALSE;
  854. BLOCKCHANNELOP_CLR* pOp = m_allcCLR.allocate(1, NULL);
  855. pOp->opr = _BLOCKCHANNELOP::op_clearplayer;
  856. pOp->param = param;
  857. DUMMY_AUTOLOCKWRITE(m_lockBlockOp);
  858. BLOCKOPLIST& rOps = m_mapIp2Ops[ip];
  859. rOps.push_back(pOp);
  860. return TRUE;
  861. }
  862. DWORD CChannelMgr::DoBlockOp(DWORD lmt)
  863. {
  864. assert(FALSE);
  865. return FALSE;
  866. DUMMY_AUTOLOCKWRITE(m_lockBlockOp);
  867. for (IP2OPSMAP::iterator itIP = m_mapIp2Ops.begin(); itIP != m_mapIp2Ops.end(); itIP++)
  868. {
  869. DWORD ip = (*itIP).first;
  870. BLOCKOPLIST& rOps = (*itIP).second;
  871. for (BLOCKOPLIST::iterator itOp = rOps.begin(); itOp != rOps.end(); itOp++)
  872. {
  873. _BLOCKCHANNELOP* pOp = *itOp;
  874. assert(pOp);
  875. switch (pOp->opr)
  876. {
  877. case _BLOCKCHANNELOP::op_querychannelid:
  878. {{
  879. BLOCKCHANNELOP_QID* pTheOp = (BLOCKCHANNELOP_QID*)pOp;
  880. Block_QueryChannelID(pTheOp->channelname, ip, pTheOp->param, pTheOp->nameid);
  881. m_allcQID.deallocate(pTheOp, 1);
  882. }}
  883. break;
  884. case _BLOCKCHANNELOP::op_subscribe:
  885. {{
  886. BLOCKCHANNELOP_CMN* pTheOp = (BLOCKCHANNELOP_CMN*)pOp;
  887. Block_Subscribe(ip, pTheOp->param, pTheOp->channelid);
  888. m_allcCMN.deallocate(pTheOp, 1);
  889. }}
  890. break;
  891. case _BLOCKCHANNELOP::op_unsubscribe:
  892. {{
  893. BLOCKCHANNELOP_CMN* pTheOp = (BLOCKCHANNELOP_CMN*)pOp;
  894. Block_Unsubscribe(ip, pTheOp->param, pTheOp->channelid);
  895. m_allcCMN.deallocate(pTheOp, 1);
  896. }}
  897. break;
  898. case _BLOCKCHANNELOP::op_freechannelid:
  899. {{
  900. BLOCKCHANNELOP_CMN* pTheOp = (BLOCKCHANNELOP_CMN*)pOp;
  901. Block_FreeChannID(ip, pTheOp->param, pTheOp->channelid);
  902. m_allcCMN.deallocate(pTheOp, 1);
  903. }}
  904. break;
  905. case _BLOCKCHANNELOP::op_clearplayer:
  906. {{
  907. BLOCKCHANNELOP_CLR* pTheOp = (BLOCKCHANNELOP_CLR*)pOp;
  908. Block_ClearPlayer(ip, pTheOp->param);
  909. m_allcCLR.deallocate(pTheOp, 1);
  910. }}
  911. break;
  912. default:
  913. assert(FALSE);
  914. }
  915. }
  916. }
  917. m_mapIp2Ops.clear();
  918. return 0;
  919. }
  920. BOOL CChannelMgr::Block_QueryChannelID(const std::_tstring& channel, DWORD ip, unsigned long param, DWORD nameid)
  921. {
  922. std::_tstring channname = MakeChannelName(channel, ip);
  923. if (channname.empty())
  924. return FALSE;
  925. CNetConnectDup conndup;
  926. std::_tstring rolename;
  927. if (!g_HostServer.FindPlayerByIpParam(NULL, ip, param, &conndup, NULL, &rolename, NULL))
  928. return FALSE;
  929. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  930. DWORD channid = -1;
  931. BYTE cost = 0;
  932. IP2PLAYERSMAP* pMapI2P = NULL;
  933. dTRACE("Query ChannelID: %s from (%08X, %08X)", channel.c_str(), ip, param);
  934. CHANN2IDMAP::iterator it = m_mapChann2ID.find(channname);
  935. if (it != m_mapChann2ID.end())
  936. {//channel exist
  937. channid = (*it).second;
  938. CHANNINFO& rChannInfo = m_mapChannid2Info[channid];
  939. cost = rChannInfo.cost;
  940. if (channid != m_channidGM)
  941. pMapI2P = &rChannInfo.mapIp2Players;
  942. }
  943. else
  944. {
  945. if (channname[0] != m_chChannEsc)
  946. return FALSE;
  947. //create the channel
  948. channid = GenChannID();
  949. if (channid != DWORD(-1))
  950. {
  951. m_mapChann2ID[channname] = channid;
  952. CHANNINFO& rChannInfo = m_mapChannid2Info[channid];
  953. rChannInfo.god = FALSE;
  954. rChannInfo.stock = FALSE;
  955. rChannInfo.channname = channname;
  956. rChannInfo.gmuse = FALSE;
  957. rChannInfo.gmsub = FALSE;
  958. rChannInfo.cost = GainPreCost(channel);
  959. rTRACE("Create Channel: <%08X> %s", channid, channname.c_str());
  960. cost = rChannInfo.cost;
  961. pMapI2P = &rChannInfo.mapIp2Players;
  962. }
  963. }
  964. if (channid != DWORD(-1))
  965. {
  966. if (pMapI2P)
  967. {
  968. PLAYERSMAP& rPlayers = (*pMapI2P)[ip];
  969. PLAYERINFO& rInfo = rPlayers[param];
  970. rInfo.nameid = nameid;
  971. rInfo.subed = FALSE;
  972. }
  973. }
  974. {{
  975. //notify channelid
  976. size_t methodsize = _NAME_LEN + sizeof(DWORD) * 2;
  977. size_t pckgsize = sizeof(RELAY_ASKWAY_DATA) + methodsize + sizeof(PLAYERCOMM_NOTIFYCHANNELID);
  978. RELAY_ASKWAY_DATA* pAskWayData = (RELAY_ASKWAY_DATA*)_alloca(pckgsize);
  979. pAskWayData->ProtocolFamily = pf_relay;
  980. pAskWayData->ProtocolID = relay_c2c_askwaydata;
  981. pAskWayData->nFromIP = 0;
  982. pAskWayData->nFromRelayID = 0;
  983. pAskWayData->seekRelayCount = 0;
  984. pAskWayData->seekMethod = rm_role_id;
  985. pAskWayData->wMethodDataLength = methodsize;
  986. pAskWayData->routeDateLength = sizeof(PLAYERCOMM_NOTIFYCHANNELID);
  987. char* pRoleName = (char*)(pAskWayData + 1);
  988. strcpy(pRoleName, rolename.c_str());
  989. DWORD* pRoleInfo = (DWORD*)(pRoleName + _NAME_LEN);
  990. pRoleInfo[0] = nameid;
  991. pRoleInfo[1] = param;
  992. PLAYERCOMM_NOTIFYCHANNELID* pPlayerCommNID = (PLAYERCOMM_NOTIFYCHANNELID*)(pRoleInfo + 2);
  993. pPlayerCommNID->ProtocolFamily = pf_playercommunity;
  994. pPlayerCommNID->ProtocolID = playercomm_s2c_notifychannelid;
  995. strcpy(pPlayerCommNID->channel, channel.c_str());
  996. pPlayerCommNID->channelid = channid;
  997. pPlayerCommNID->cost = cost;
  998. conndup.SendPackage(pAskWayData, pckgsize);
  999. }}
  1000. return TRUE;
  1001. }
  1002. BOOL CChannelMgr::Block_Subscribe(DWORD ip, unsigned long param, DWORD channelid)
  1003. {
  1004. if (channelid == -1)
  1005. return FALSE;
  1006. if (channelid == m_channidGM)
  1007. {
  1008. dTRACE("Subscribe Channel: GM <%08X> by (%08X,%08X)", channelid, ip, param);
  1009. return TRUE;
  1010. }
  1011. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  1012. CHANNID2INFOMAP::iterator it = m_mapChannid2Info.find(channelid);
  1013. if (it == m_mapChannid2Info.end())
  1014. return FALSE;
  1015. CHANNINFO& rChannInfo = (*it).second;
  1016. PLAYERSMAP& rPlayers = rChannInfo.mapIp2Players[ip];
  1017. PLAYERSMAP::iterator itRole = rPlayers.find(param);
  1018. if (itRole == rPlayers.end())
  1019. return FALSE;
  1020. PLAYERINFO& rPlayerInfo = (*itRole).second;
  1021. rPlayerInfo.subed = TRUE;
  1022. dTRACE("Subscribe Channel: %08X by (%08X,%08X)", channelid, ip, param);
  1023. return TRUE;
  1024. }
  1025. BOOL CChannelMgr::Block_Unsubscribe(DWORD ip, unsigned long param, DWORD channelid)
  1026. {
  1027. if (channelid == m_channidGM)
  1028. return FALSE;
  1029. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  1030. CHANNID2INFOMAP::iterator itChannid = m_mapChannid2Info.find(channelid);
  1031. if (itChannid == m_mapChannid2Info.end())
  1032. return FALSE;
  1033. CHANNINFO& rChannInfo = (*itChannid).second;
  1034. IP2PLAYERSMAP::iterator itPlayers = rChannInfo.mapIp2Players.find(ip);
  1035. if (itPlayers == rChannInfo.mapIp2Players.end())
  1036. return FALSE;
  1037. PLAYERSMAP& rPlayers = (*itPlayers).second;
  1038. PLAYERSMAP::iterator itRole = rPlayers.find(param);
  1039. if (itRole == rPlayers.end())
  1040. return FALSE;
  1041. PLAYERINFO& rInfo = (*itRole).second;
  1042. rInfo.subed = FALSE;
  1043. dTRACE("Unsubscribe Channel: %08X by (%08X,%08X)", channelid, ip, param);
  1044. return TRUE;
  1045. }
  1046. BOOL CChannelMgr::Block_FreeChannID(DWORD channid, DWORD ip, unsigned long param)
  1047. {
  1048. if (channid == -1)
  1049. return FALSE;
  1050. dTRACE("Free ChannelID: <%08X> from (%08X, %08X)", channid, ip, param);
  1051. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  1052. if (channid == m_channidGM)
  1053. return TRUE;
  1054. CHANNID2INFOMAP::iterator it = m_mapChannid2Info.find(channid);
  1055. if (it == m_mapChannid2Info.end())
  1056. return FALSE;
  1057. CHANNINFO& rChannInfo = (*it).second;
  1058. if (rChannInfo.god)
  1059. return TRUE;
  1060. IP2PLAYERSMAP::iterator itPlayers = rChannInfo.mapIp2Players.find(ip);
  1061. if (itPlayers == rChannInfo.mapIp2Players.end())
  1062. return FALSE;
  1063. PLAYERSMAP& rPlayers = (*itPlayers).second;
  1064. rPlayers.erase(param);
  1065. if (rPlayers.empty())
  1066. {
  1067. rChannInfo.mapIp2Players.erase(itPlayers);
  1068. if (!rChannInfo.stock && !rChannInfo.gmuse
  1069. && rChannInfo.mapIp2Players.empty())
  1070. {
  1071. rTRACE("Destroy Channel: <%08X> %s", channid, rChannInfo.channname.c_str());
  1072. m_mapChann2ID.erase(rChannInfo.channname);
  1073. m_mapChannid2Info.erase(it);
  1074. }
  1075. }
  1076. return TRUE;
  1077. }
  1078. BOOL CChannelMgr::Block_ClearPlayer(DWORD ip, unsigned long param)
  1079. {
  1080. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  1081. CHANNID2INFOMAP::iterator itChann = m_mapChannid2Info.begin();
  1082. while (itChann != m_mapChannid2Info.end())
  1083. {
  1084. CHANNID2INFOMAP::iterator itChannMe = itChann++;
  1085. DWORD channid = (*itChannMe).first;
  1086. CHANNINFO& rChannInfo = (*itChannMe).second;
  1087. if (channid == m_channidGM)
  1088. continue;
  1089. IP2PLAYERSMAP::iterator itIP = rChannInfo.mapIp2Players.find(ip);
  1090. if (itIP == rChannInfo.mapIp2Players.end()) //没找到此GS
  1091. continue;
  1092. IP2PLAYERSMAP::iterator itIPMe = itIP++;
  1093. PLAYERSMAP& rPlayers = (*itIPMe).second;
  1094. //删除此人
  1095. rPlayers.erase(param);
  1096. if (!rPlayers.empty()) //此GS上还有人
  1097. continue;
  1098. //GS上无人,删除此GS
  1099. rChannInfo.mapIp2Players.erase(itIPMe);
  1100. if (rChannInfo.stock || rChannInfo.gmuse) //频道不可删
  1101. continue;
  1102. if (!rChannInfo.mapIp2Players.empty()) //如果此频道还有GS
  1103. continue;
  1104. rTRACE("Destroy Channel: <%08X> %s", channid, rChannInfo.channname.c_str());
  1105. //删除频道
  1106. m_mapChann2ID.erase(rChannInfo.channname);
  1107. m_mapChannid2Info.erase(itChannMe);
  1108. }
  1109. return TRUE;
  1110. }
  1111. BOOL CChannelMgr::B_QueryChannelID(const std::_tstring& channel, DWORD ip, unsigned long param, DWORD nameid)
  1112. {
  1113. return Block_QueryChannelID(channel, ip, param, nameid);
  1114. }
  1115. BOOL CChannelMgr::B_Subscribe(DWORD ip, unsigned long param, DWORD channelid)
  1116. {
  1117. return Block_Subscribe(ip, param, channelid);
  1118. }
  1119. BOOL CChannelMgr::B_Unsubscribe(DWORD ip, unsigned long param, DWORD channelid)
  1120. {
  1121. return Block_Unsubscribe(ip, param, channelid);
  1122. }
  1123. BOOL CChannelMgr::B_FreeChannID(DWORD channid, DWORD ip, unsigned long param)
  1124. {
  1125. return Block_FreeChannID(channid, ip, param);
  1126. }
  1127. BOOL CChannelMgr::B_ClearPlayer(DWORD ip, unsigned long param)
  1128. {
  1129. return Block_ClearPlayer(ip, param);
  1130. }
  1131. size_t CChannelMgr::GetChannelCount()
  1132. {
  1133. DUMMY_AUTOLOCKWRITE(m_lockChannel);
  1134. return m_mapChannid2Info.size();
  1135. }
  1136. BOOL CChannelMgr::SayOnSomeone(DWORD ip, unsigned long param, DWORD nameid, const std::_tstring& name, const std::_tstring& sent)
  1137. {
  1138. CNetConnectDup hostconndup;
  1139. if (!g_HostServer.FindPlayerByIpParam(NULL, ip, param, &hostconndup, NULL, NULL, NULL))
  1140. return FALSE;
  1141. size_t syncsize = sizeof(CHAT_SOMEONECHAT_SYNC) + sent.size();
  1142. CHAT_SOMEONECHAT_SYNC* pCscSync = (CHAT_SOMEONECHAT_SYNC*)_alloca(syncsize);
  1143. pCscSync->ProtocolType = chat_someonechat;
  1144. pCscSync->wSize = syncsize - 1;
  1145. pCscSync->packageID = -1;
  1146. strcpy(pCscSync->someone, name.c_str());
  1147. pCscSync->sentlen = sent.size();
  1148. memcpy(pCscSync + 1, sent.data(), sent.size());
  1149. if (!PassToSpecMan(hostconndup.GetIP(), param, nameid, pCscSync, syncsize))
  1150. return FALSE;
  1151. return TRUE;
  1152. }
  1153. BOOL CChannelMgr::SayOnChannel(DWORD channid, BOOL filter, const std::_tstring& ids, const std::_tstring& name, const std::_tstring& sent)
  1154. {
  1155. DUMMY_AUTOLOCKREAD(m_lockChannel);
  1156. CHANNID2INFOMAP::iterator itChannid = m_mapChannid2Info.find(channid);
  1157. if (itChannid == m_mapChannid2Info.end())
  1158. return FALSE;
  1159. CHANNINFO& rChannInfo = (*itChannid).second;
  1160. if (rChannInfo.god)
  1161. {
  1162. if (!g_RootClient.IsReady())
  1163. return FALSE;
  1164. size_t pckgsize = sizeof(CHAT_MSG_EX) + sent.size();
  1165. CHAT_MSG_EX* pChatMsgEx = (CHAT_MSG_EX*)_alloca(pckgsize);
  1166. pChatMsgEx->ProtocolFamily = pf_playercommunity;
  1167. pChatMsgEx->ProtocolID = playercomm_channelchat;
  1168. strcpy(pChatMsgEx->m_szSourceName, name.c_str());
  1169. strcpy(pChatMsgEx->m_szAccountName, ids.c_str());
  1170. pChatMsgEx->SentenceLength = sent.size();
  1171. memcpy(pChatMsgEx + 1, sent.data(), sent.size());
  1172. PassToGM(pChatMsgEx, pckgsize);
  1173. }
  1174. else
  1175. {
  1176. if (IsNeedRelegate(rChannInfo.channname, filter))
  1177. {//relegate to gamesvr
  1178. assert(rChannInfo.channname[0] == m_chChannEsc);
  1179. DWORD channIP = 0;
  1180. DWORD theID = ParseChannelName(rChannInfo.channname, &channIP);
  1181. if (theID == -1 && channIP == 0)
  1182. return FALSE;
  1183. assert(rChannInfo.channname.size() >= 2);
  1184. size_t syncsize = sizeof(CHAT_CHANNELCHAT_SYNC) + sent.size();
  1185. size_t pckgsize = sizeof(CHAT_RELEGATE) + syncsize;
  1186. CHAT_RELEGATE* pCr = (CHAT_RELEGATE*)_alloca(pckgsize);
  1187. pCr->ProtocolType = chat_relegate;
  1188. pCr->wSize = pckgsize - 1;
  1189. pCr->nFromIP = 0;
  1190. pCr->nFromRelayID = -1;
  1191. pCr->channelid = channid;
  1192. pCr->routeDateLength = syncsize;
  1193. CHAT_CHANNELCHAT_SYNC* pCccSync = (CHAT_CHANNELCHAT_SYNC*)(pCr + 1);
  1194. pCccSync->ProtocolType = chat_channelchat;
  1195. pCccSync->wSize = syncsize - 1;
  1196. pCccSync->packageID = -1;
  1197. strcpy(pCccSync->someone, name.c_str());
  1198. pCccSync->channelid = channid;
  1199. pCccSync->sentlen = sent.size();
  1200. memcpy(pCccSync + 1, sent.data(), sent.size());
  1201. if (rChannInfo.channname[1] == m_chChannTEAM)
  1202. {
  1203. if (theID == -1 || channIP == 0)
  1204. return FALSE;
  1205. CHANNINFO& rChannInfo = (*itChannid).second;
  1206. CNetConnectDup connDup = g_ChatServer.FindChatConnectByIP(channIP);
  1207. if (!connDup.IsValid())
  1208. return FALSE;
  1209. pCr->TargetCls = tgtcls_team;
  1210. pCr->TargetID = theID;
  1211. connDup.SendPackage(pCr, pckgsize);
  1212. }
  1213. else if (rChannInfo.channname[1] == m_chChannFAC)
  1214. {
  1215. if (theID == -1)
  1216. return FALSE;
  1217. pCr->TargetCls = tgtcls_fac;
  1218. pCr->TargetID = theID;
  1219. g_ChatServer.BroadPackage(pCr, pckgsize);
  1220. }
  1221. else if (rChannInfo.channname[1] == m_chChannTONG)
  1222. {
  1223. if (theID == -1)
  1224. return FALSE;
  1225. pCr->TargetCls = tgtcls_tong;
  1226. pCr->TargetID = theID;
  1227. g_ChatServer.BroadPackage(pCr, pckgsize);
  1228. }
  1229. else if (rChannInfo.channname[1] == m_chChannSCRN)
  1230. {
  1231. //screen
  1232. assert(FALSE);
  1233. return FALSE;
  1234. }
  1235. else if (rChannInfo.channname[1] == m_chChannBC)
  1236. {
  1237. if (channIP == 0)
  1238. return FALSE;
  1239. assert(channIP != 0 && theID == 0);
  1240. CNetConnectDup connDup = g_ChatServer.FindChatConnectByIP(channIP);
  1241. if (!connDup.IsValid())
  1242. return FALSE;
  1243. pCr->TargetCls = tgtcls_bc;
  1244. pCr->TargetID = 0;
  1245. connDup.SendPackage(pCr, pckgsize);
  1246. }
  1247. else
  1248. {
  1249. assert(FALSE);
  1250. return FALSE;
  1251. }
  1252. }
  1253. else
  1254. {//broad on channel
  1255. //== PassToPlayer
  1256. //do like this for optimize
  1257. size_t syncsize = sizeof(CHAT_CHANNELCHAT_SYNC) + sent.size();
  1258. CHAT_CHANNELCHAT_SYNC* pCccSync = (CHAT_CHANNELCHAT_SYNC*)_alloca(syncsize);
  1259. pCccSync->ProtocolType = chat_channelchat;
  1260. pCccSync->wSize = syncsize - 1;
  1261. pCccSync->packageID = -1;
  1262. strcpy(pCccSync->someone, name.c_str());
  1263. pCccSync->channelid = channid;
  1264. pCccSync->sentlen = sent.size();
  1265. memcpy(pCccSync + 1, sent.data(), sent.size());
  1266. for (IP2PLAYERSMAP::iterator itIP = rChannInfo.mapIp2Players.begin(); itIP != rChannInfo.mapIp2Players.end(); itIP++)
  1267. {
  1268. DWORD IP = (*itIP).first;
  1269. PLAYERSMAP& rPlayers = (*itIP).second;
  1270. MANLIST mans;
  1271. for (PLAYERSMAP::iterator itPlayer = rPlayers.begin(); itPlayer != rPlayers.end(); itPlayer++)
  1272. {
  1273. DWORD param = (*itPlayer).first;
  1274. PLAYERINFO& rInfo = (*itPlayer).second;
  1275. if (rInfo.subed)
  1276. {
  1277. tagPlusSrcInfo friendInfo;
  1278. friendInfo.nameid = rInfo.nameid;
  1279. friendInfo.lnID = param;
  1280. mans.push_back(friendInfo);
  1281. }
  1282. }
  1283. if (!mans.empty())
  1284. {
  1285. PassToGroupMan(IP, FALSE, mans, pCccSync, syncsize);
  1286. }
  1287. }
  1288. }
  1289. }
  1290. return TRUE;
  1291. }