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

模拟服务器

开发平台:

C/C++

  1. // RootClient.cpp: implementation of the CRootClient class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Global.h"
  6. #include "RootClient.h"
  7. #include "RootCenter.h"
  8. #include "S3Relay.h"
  9. #include "DealRelay.h"
  10. #include "../../../Headers/KGmProtocol.h"
  11. #include "malloc.h"
  12. #include "crtdbg.h"
  13. #include "../../Engine/Src/KWin32.h"
  14. #include "../../Engine/Src/KSG_MD5_String.h"
  15. #include "../../Sword3PaySys/S3AccServer/AccountLoginDef.h"
  16. #include "DoScript.h"
  17. //////////////////////////////////////////////////////////////////////
  18. // Construction/Destruction
  19. //////////////////////////////////////////////////////////////////////
  20. CRootClient::CRootClient(CRootCenter* pRootCenter, BOOL bAutoFree)
  21. : CNetClient(pRootCenter, bAutoFree)
  22. {
  23. m_LastRevPingTime = 0;
  24. m_LastSendPingTime = 0;
  25. m_isStartAutoTime = FALSE;
  26. }
  27. CRootClient::~CRootClient()
  28. {
  29. }
  30. void CRootClient::OnServerEventCreate()
  31. {
  32. gOnOneClientCreate(oneclient_root);
  33. extern std::_tstring g_rootloginname;
  34. extern std::_tstring g_rootloginpswd;
  35. rTRACE("root client create: %s", _ip2a(GetSvrIP()));
  36. KServerAccountUserLoginInfo serlogin;
  37. serlogin.Size = sizeof(KServerAccountUserLoginInfo);
  38. serlogin.Type = ServerAccountUserLoginInfo;
  39. serlogin.Version = ACCOUNT_CURRENT_VERSION;
  40. strncpy(serlogin.Account, g_rootloginname.c_str(), LOGIN_USER_ACCOUNT_MAX_LEN);
  41.     serlogin.Account[LOGIN_USER_ACCOUNT_MAX_LEN - 1] = '';
  42.     //#ifdef SWORDONLINE_USE_MD5_PASSWORD
  43.     KSG_StringToMD5String(serlogin.Password, g_rootloginpswd.c_str());
  44.     //#else
  45.     //
  46.     //#pragma message (KSG_ATTENTION("Add Password to MD5 string"))
  47. //strncpy(serlogin.Password, g_rootloginpswd.c_str(), LOGIN_USER_PASSWORD_MAX_LEN);
  48.     //serlogin.Password[LOGIN_USER_PASSWORD_MAX_LEN - 1] = '';
  49.     //#endif
  50.     
  51. memcpy(serlogin.MacAddress, gGetHostMac(global_adapt), 6);
  52. char send[MAX_PATH + 1];
  53. send[0] = pf_normal;
  54. send[1] = c2s_gatewayverify;
  55. memcpy(send + 2, &serlogin, sizeof(serlogin));
  56. SendPackage(send, sizeof(serlogin) + 2);
  57. }
  58. void CRootClient::OnServerEventClose()
  59. {
  60. StopAutoTime();
  61. rTRACE("root client close: %s", _ip2a(GetSvrIP()));
  62. gOnOneClientClose(oneclient_root);
  63. }
  64. BOOL CRootClient::StartAutoTime()
  65. {
  66. if (!m_isStartAutoTime)
  67. {
  68. m_LastRevPingTime = m_LastSendPingTime = GetTickCount();
  69. m_isStartAutoTime = TRUE;
  70. rTRACE("start autotimer for Ping: %s", _ip2a(GetSvrIP()));
  71. }
  72. return TRUE;
  73. }
  74. BOOL CRootClient::StopAutoTime()
  75. {
  76. if (m_isStartAutoTime)
  77. {
  78. m_isStartAutoTime = FALSE;
  79. m_LastRevPingTime = m_LastSendPingTime = 0;
  80. rTRACE("stop autotimer for Ping: %s", _ip2a(GetSvrIP()));
  81. }
  82. return TRUE;
  83. }
  84. BOOL CRootClient::IsStartAutoTime()
  85. {
  86. return m_isStartAutoTime;
  87. }
  88. void CRootClient::AutoTime()
  89. {
  90. if (!IsStartAutoTime())
  91. return;
  92. DWORD tick = GetTickCount();
  93. if (tick - m_LastRevPingTime >= 600000) //十分钟没有收到Ping
  94. {
  95. rTRACE("warning: root client timeout: %s", _ip2a(GetSvrIP()));
  96. InterShutdown();
  97. return;
  98. }
  99. if (tick - m_LastSendPingTime >= 120000) //两分钟没有发出Ping
  100. {
  101. m_LastSendPingTime = tick;
  102. char buffer[sizeof(EXTEND_HEADER) + sizeof(DWORD)];
  103. EXTEND_HEADER* pHeader = (EXTEND_HEADER*)buffer;
  104. pHeader->ProtocolFamily = pf_normal;
  105. pHeader->ProtocolID = c2s_ping;
  106. DWORD* pPingTick = (DWORD*)(pHeader + 1);
  107. *pPingTick = m_LastSendPingTime;
  108. SendPackage(buffer, sizeof(buffer));
  109. dTRACE("root client ping: %s", _ip2a(GetSvrIP()));
  110. }
  111. }
  112. void CRootClient::BeginRoute()
  113. {
  114. }
  115. void CRootClient::EndRoute()
  116. {
  117. AutoTime();
  118. }
  119. void CRootClient::RecvPackage(const void* pData, size_t size)
  120. {
  121. EXTEND_HEADER* pHeader = (EXTEND_HEADER*)pData;
  122. if (pHeader->ProtocolFamily == pf_normal)
  123. {
  124. Proc0_Normal(pData, size);
  125. }
  126. else if (pHeader->ProtocolFamily == pf_relay)
  127. {
  128. Proc0_Relay(pData, size);
  129. }
  130. else if (pHeader->ProtocolFamily == pf_playercommunity)
  131. {
  132. Proc0_PlayerCommunity(pData, size);
  133. }
  134. }
  135. void CRootClient::Proc0_Normal(const void* pData, size_t size)
  136. {
  137. EXTEND_HEADER* pHeader = (EXTEND_HEADER*)pData;
  138. if (pHeader->ProtocolID == s2c_ping)
  139. {
  140. m_LastRevPingTime = GetTickCount();
  141. }
  142. else if (pHeader->ProtocolID == s2c_gatewayinfo)
  143. {
  144. KServerInfo* pServer = (KServerInfo*)(((char*)pData) + 2);
  145. if (size == sizeof(KServerInfo) + 2)
  146. {
  147. if (pServer->nServerType == server_Login)
  148. {
  149. std::_tstring addr(_ip2a(pServer->nValue));
  150. CNetSockDupEx sockdup = dealrelay::FindRelaySockByIP(pServer->nValue);
  151. if (!sockdup.IsValid())
  152. {
  153. rTRACE("warning: relay client exist: %s", addr.c_str());
  154. return;
  155. }
  156. rTRACE("relay client attempt: %s", addr.c_str());
  157. if (!gConnectToSibling(addr.c_str()))
  158. {
  159. rTRACE("error: relay client error: %s", addr.c_str());
  160. return;
  161. }
  162. return;
  163. }
  164. }
  165. }
  166. else if (pHeader->ProtocolID == s2c_gatewayverify)
  167. {
  168. KAccountUserReturn* pReturn = (KAccountUserReturn*)(((char*)pData) + 2);
  169. if (size == sizeof(KAccountUserReturn) + 2)
  170. {
  171. if (pReturn->nReturn == ACTION_SUCCESS)
  172. {
  173. StartAutoTime();
  174. }
  175. }
  176. }
  177. }
  178. void CRootClient::Proc0_Relay(const void* pData, size_t size)
  179. {
  180. EXTEND_HEADER* pHeader = (EXTEND_HEADER*)pData;
  181. if (pHeader->ProtocolID == relay_c2c_data)
  182. {
  183. Proc1_Relay_Data(pData, size);
  184. }
  185. else if (pHeader->ProtocolID == relay_c2c_askwaydata)
  186. {
  187. Proc1_Relay_AskWay(pData, size);
  188. }
  189. else if (pHeader->ProtocolID == relay_s2c_loseway)
  190. {
  191. Proc1_Relay_LoseWay(pData, size);
  192. }
  193. }
  194. // [wxb 2003-7-19]
  195. void CRootClient::Proc2_Relay_Data_Here(const void* pData, size_t size)
  196. {
  197. RELAY_DATA* pRelayData = (RELAY_DATA*)pData;
  198. EXTEND_HEADER* pHeader = (EXTEND_HEADER*)(pRelayData + 1);
  199. switch (*((WORD*)pHeader))
  200. {
  201. case (MAKEWORD(pf_relay, relay_c2c_askwaydata)):
  202. Proc1_Relay_AskWay((void*)pHeader, size - sizeof(RELAY_DATA));
  203. break;
  204. case (MAKEWORD(pf_gamemaster, gm_c2s_execute)):
  205. {
  206. GM_EXECUTE_COMMAND* pGMData = (GM_EXECUTE_COMMAND*)(pHeader);
  207. char szScriptAction[MAX_PATH];
  208. memcpy(szScriptAction, ((const char*)pGMData) + sizeof(GM_EXECUTE_COMMAND), min(MAX_PATH - 1, pGMData->wLength));
  209. szScriptAction[min(MAX_PATH, pGMData->wLength)] = 0;
  210. ExcuteScript(pRelayData->nFromIP, pRelayData->nFromRelayID, szScriptAction);
  211. }
  212. break;
  213. case (MAKEWORD(pf_gamemaster, gm_c2s_getrolelist)):
  214. _ASSERT(pRelayData->routeDateLength == sizeof(GM_GET_ROLE_LIST_CMD));
  215. {
  216. //用老协议向角色数据库查询
  217. GM_GET_ROLE_LIST_CMD* pGMData = (GM_GET_ROLE_LIST_CMD*)pHeader;
  218. int nNewDataLen = sizeof(TProcessData) + strlen(pGMData->AccountName) + 1;
  219. TProcessData* pNewData = (TProcessData*)_alloca(nNewDataLen);
  220. pNewData->nProtoId = c2s_roleserver_getrolelist;
  221. pNewData->nDataLen = strlen(pGMData->AccountName) + 1;
  222. pNewData->ulIdentity = 0;
  223. pNewData->pDataBuffer[0] = MAX_PLAYER_PER_ACCOUNT;
  224. strncpy((char*)(pNewData + 1), pGMData->AccountName, sizeof(pGMData->AccountName));
  225. g_DBClient.SendPackage(pNewData, nNewDataLen);
  226. }
  227. break;
  228. case (MAKEWORD(pf_gamemaster, gm_c2s_broadcast_chat)):
  229. {{
  230. GM_BROADCAST_CHAT_CMD* pGMData = (GM_BROADCAST_CHAT_CMD*)pHeader;
  231. size_t pckgsize = sizeof(CHAT_EVERYONE) + pGMData->wSentenceLen;
  232. CHAT_EVERYONE* pCeo = (CHAT_EVERYONE*)_alloca(pckgsize);
  233. pCeo->ProtocolType = chat_everyone;
  234. pCeo->wSize = pckgsize - 1;
  235. pCeo->wChatLength = pGMData->wSentenceLen;
  236. memcpy(pCeo + 1, pGMData + 1, pGMData->wSentenceLen);
  237. g_ChatServer.BroadPackage(pCeo, pckgsize);
  238. }}
  239. break;
  240. case (MAKEWORD(pf_gamemaster, gm_c2s_getrole)):
  241. case (MAKEWORD(pf_gamemaster, gm_c2s_setrole)):
  242. {
  243. char* pDBAskBuffer = (char*)_alloca(pRelayData->routeDateLength + 1);
  244. memcpy(pDBAskBuffer + 1, pHeader, pRelayData->routeDateLength);
  245. *pDBAskBuffer = (char)c2s_extend;
  246. g_DBClient.SendPackage(pDBAskBuffer, pRelayData->routeDateLength + 1);
  247. }
  248. break;
  249. default:
  250. _ASSERT(0);
  251. break;
  252. }
  253. }
  254. void CRootClient::Proc1_Relay_Data(const void* pData, size_t size)
  255. {
  256. RELAY_DATA* pRelayData = (RELAY_DATA*)pData;
  257. if (pRelayData->nToIP == 0)
  258. {
  259. Proc2_Relay_Data_Here(pData, size);
  260. return;
  261. }
  262. else if (pRelayData->nToIP == INADDR_BROADCAST)
  263. {//broadcast to gamesvrs
  264. pRelayData->nToIP = 0;
  265. g_HostServer.BroadPackage(pRelayData, size);
  266. return;
  267. }
  268. else if (pRelayData->nToIP == gGetHostIP(global_adapt))
  269. {//relay to host
  270. pRelayData->nToIP = 0;
  271. if (g_HostServer.IsConnectReady(pRelayData->nToRelayID))
  272. {
  273. CNetConnectDup conndup = g_HostServer.FindNetConnect(pRelayData->nToRelayID);
  274. if (conndup.IsValid())
  275. {
  276. conndup.SendPackage(pRelayData, size);
  277. return;
  278. }
  279. }
  280. }
  281. assert (pRelayData->nFromIP != 0);
  282. //lose way
  283. size_t sizeLoseData = sizeof(RELAY_DATA) + size;
  284. RELAY_DATA* pLoseDataDup = (RELAY_DATA*)_alloca(sizeLoseData);
  285. gFillLosewayPckg(pRelayData->nFromIP, pRelayData->nFromRelayID, 
  286. pRelayData, size, pLoseDataDup, sizeLoseData);
  287. SendPackage(pLoseDataDup, sizeLoseData);
  288. }
  289. void CRootClient::Proc1_Relay_AskWay(const void* pData, size_t size)
  290. {
  291. RELAY_ASKWAY_DATA* pAskWayData = (RELAY_ASKWAY_DATA*)pData;
  292. if (pAskWayData->seekMethod == rm_account_id)
  293. {
  294. Proc2_Relay_AskWay_AccountRoleID(pData, size, TRUE);
  295. }
  296. else if (pAskWayData->seekMethod == rm_role_id)
  297. {
  298. Proc2_Relay_AskWay_AccountRoleID(pData, size, FALSE);
  299. }
  300. }
  301. void CRootClient::Proc1_Relay_LoseWay(const void* pData, size_t size)
  302. {
  303. RELAY_DATA* pLoseData = (RELAY_DATA*)pData;
  304. if (pLoseData->nFromIP == 0)
  305. {
  306. pLoseData->nFromIP = GetSvrIP();
  307. pLoseData->nFromRelayID = -1;
  308. }
  309. if (pLoseData->nToIP == 0)
  310. {//my data
  311. //...
  312. return;
  313. }
  314. else if (pLoseData->nToIP == INADDR_BROADCAST)
  315. {//broadcast to gamesvrs
  316. assert(FALSE);
  317. return;
  318. }
  319. else if (pLoseData->nToIP == gGetHostIP(global_adapt))
  320. {//relay to host
  321. pLoseData->nToIP = 0;
  322. if (g_HostServer.IsConnectReady(pLoseData->nToRelayID))
  323. {
  324. CNetConnectDup conndup = g_HostServer.FindNetConnect(pLoseData->nToRelayID);
  325. if (conndup.IsValid())
  326. {
  327. conndup.SendPackage(pLoseData, size);
  328. return;
  329. }
  330. }
  331. }
  332. //lose way
  333. //don't more lose
  334. }
  335. void CRootClient::Proc2_Relay_AskWay_AccountRoleID(const void* pData, size_t size, BOOL acc)
  336. {
  337. RELAY_ASKWAY_DATA* pAskWayData = (RELAY_ASKWAY_DATA*)pData;
  338. std::_tstring strName = (char*)(pAskWayData + 1);
  339. assert(!strName.empty());
  340. DWORD nameid = -1;
  341. unsigned long param = -1;
  342. CNetConnectDup conndup;
  343. BOOL find = FALSE;
  344. if (acc ? g_HostServer.FindPlayerByAcc(NULL, strName, &conndup, NULL, &nameid, &param)
  345.  : g_HostServer.FindPlayerByRole(NULL, strName, &conndup, NULL, &nameid, &param))
  346. {//send to target
  347. assert(conndup.IsValid());
  348. size_t pckgsize = sizeof(DWORD)*2 + size;
  349. RELAY_ASKWAY_DATA* pClntWayData = (RELAY_ASKWAY_DATA*)_alloca(pckgsize);
  350. gFillClntwayPckg(nameid, param, pAskWayData, size, pClntWayData, pckgsize);
  351. conndup.SendPackage(pClntWayData, pckgsize);
  352. return;
  353. }
  354. //lose way
  355. size_t sizeLoseData = sizeof(RELAY_DATA) + size;
  356. RELAY_DATA* pLoseDataDup = (RELAY_DATA*)_alloca(sizeLoseData);
  357. gFillLosewayPckg(pAskWayData->nFromIP, pAskWayData->nFromRelayID, 
  358. pAskWayData, size, pLoseDataDup, sizeLoseData);
  359. SendPackage(pLoseDataDup, sizeLoseData);
  360. }
  361. void CRootClient::Proc0_PlayerCommunity(const void* pData, size_t size)
  362. {
  363. EXTEND_HEADER* pHeader = (EXTEND_HEADER*)pData;
  364. if (pHeader->ProtocolID == playercomm_s2c_gmquerychannelid)
  365. {
  366. PLAYERCOMM_GMQUERYCHANNELID* pPlayerCommGmQID = (PLAYERCOMM_GMQUERYCHANNELID*)pData;
  367. g_ChannelMgr.GmQueryChannelID(pPlayerCommGmQID->channel, pPlayerCommGmQID->force);
  368. }
  369. else if (pHeader->ProtocolID == playercomm_s2c_gmfreechannelid)
  370. {
  371. PLAYERCOMM_GMFREECHANNELID* pPlayerCommGmFID = (PLAYERCOMM_GMFREECHANNELID*)pData;
  372. g_ChannelMgr.GmFreeChannID(pPlayerCommGmFID->channelid);
  373. }
  374. else if (pHeader->ProtocolID == playercomm_s2c_gmsubscribe)
  375. {
  376. PLAYERCOMM_GMSUBSCRIBE* pPlayerCommGmSub = (PLAYERCOMM_GMSUBSCRIBE*)pData;
  377. if (pPlayerCommGmSub->subscribe)
  378. g_ChannelMgr.GmSubscribe(pPlayerCommGmSub->channelid);
  379. else
  380. g_ChannelMgr.GmUnsubscribe(pPlayerCommGmSub->channelid);
  381. }
  382. }