CoreServerShell.cpp
Upload User: dzyhzl
Upload Date: 2019-04-29
Package Size: 56270k
Code Size: 33k
Development Platform:

C/C++

  1. /*****************************************************************************************
  2. // 外界访问Core server 接口方法
  3. // Copyright : Kingsoft 2002
  4. // Author :   Wooy (Wu yue)
  5. // CreateTime: 2002-12-20
  6. ------------------------------------------------------------------------------------------
  7. *****************************************************************************************/
  8. #include "KCore.h"
  9. #include "CoreServerShell.h"
  10. #include "KThread.h"
  11. #include "KPlayer.h"
  12. #include "KItemList.h"
  13. #include "KSubWorldSet.h"
  14. #include "KProtocolProcess.h"
  15. #include "KNewProtocolProcess.h"
  16. #include "KPlayerSet.h"
  17. #include "KLadder.h"
  18. #ifdef _STANDALONE
  19. #include "KLadder.cpp"
  20. #endif
  21. //#include "KNetServer.h"
  22. //#include "../MultiServer/Heaven/Interface/iServer.h"
  23. #ifdef _STANDALONE
  24. #include "IClient.h"
  25. #else
  26. #include "../../lib/S3DBInterface.h"
  27. #include "../../Headers/IClient.h"
  28. #include "../../../Headers/IClient.h"
  29. #include "../../../Headers/KGmProtocol.h"
  30. #endif
  31. #include "LuaFuns.h"
  32. #include "KSortScript.h"
  33. #include "KSubWorld.h"
  34. #include "malloc.h"
  35. class CoreServerShell : public iCoreServerShell
  36. {
  37. public:
  38. int  GetLoopRate();
  39. void GetGuid(int nIndex, void* pGuid);
  40. DWORD GetExchangeMap(int nIndex);
  41. bool IsPlayerLoginTimeOut(int nIndex);
  42. void RemovePlayerLoginTimeOut(int nIndex);
  43. bool IsPlayerExchangingServer(int nIndex);
  44. void ProcessClientMessage(int nIndex, const char* pChar, int nSize);
  45. void ProcessNewClientMessage(IClient*, DWORD, DWORD, int nIndex, const char* pChar, int nSize);
  46. void SendNetMsgToTransfer(IClient* pClient);
  47. void SendNetMsgToChat(IClient* pClient);
  48. void SendNetMsgToTong(IClient* pClient);
  49. void ProcessBroadcastMessage(const char* pChar, int nSize);
  50. void ProcessExecuteMessage(const char* pChar, int nSize);
  51. void ClientDisconnect(int nIndex);
  52. void RemoveQuitingPlayer(int nIndex);
  53. void* SavePlayerDataAtOnce(int nIndex);
  54. bool IsCharacterQuiting(int nIndex);
  55. bool CheckProtocolSize(const char* pChar, int nSize);
  56. bool PlayerDbLoading(int nPlayerIndex, int bSyncEnd, int& nStep, unsigned int& nParam);
  57. int  AttachPlayer(const unsigned long lnID, GUID* pGuid);
  58. void GetPlayerIndexByGuid(GUID* pGuid, int* pnIndex, int* plnID);
  59. void AddPlayerToWorld(int nIndex);
  60. void* PreparePlayerForExchange(int nIndex);
  61. void PreparePlayerForLoginFailed(int nIndex);
  62. void RemovePlayerForExchange(int nIndex);
  63. void RecoverPlayerExchange(int nIndex);
  64. int  AddCharacter(int nExtPoint, int nChangeExtPoint, void* pBuffer, GUID* pGuid);
  65. int  AddTempTaskValue(int nIndex, const char* pData);
  66. //向游戏发送操作
  67. int  OperationRequest(unsigned int uOper, unsigned int uParam, int nParam);
  68. //获取连接状况
  69. int  GetConnectInfo(KCoreConnectInfo* pInfo);
  70. //BOOL ValidPingTime(int nIndex);
  71. //从游戏世界获取数据
  72. int  GetGameData(unsigned int uDataId, unsigned int uParam, int nParam);
  73. //日常活动,core如果要寿终正寝则返回0,否则返回非0值
  74. int  Breathe();
  75. //释放接口对象
  76. void Release();
  77. void SetSaveStatus(int nIndex, UINT uStatus);
  78. UINT GetSaveStatus(int nIndex);
  79. BOOL GroupChat(IClient* pClient, DWORD FromIP, unsigned long FromRelayID, DWORD channid, BYTE tgtcls, DWORD tgtid, const void* pData, size_t size);
  80. void SetLadder(void* pData, size_t uSize);
  81. BOOL PayForSpeech(int nIndex, int nType);
  82. private:
  83. int  OnLunch(LPVOID pServer);
  84. int  OnShutdown();
  85. };
  86. static CoreServerShell g_CoreServerShell;
  87. CORE_API void g_InitCore();
  88. #ifndef _STANDALONE
  89. extern "C" __declspec(dllexport)
  90. #endif
  91. iCoreServerShell* CoreGetServerShell()
  92. {
  93. g_InitCore();
  94. return &g_CoreServerShell;
  95. }
  96. void CoreServerShell::Release()
  97. {
  98. g_ReleaseCore();
  99. }
  100. int CoreServerShell::GetLoopRate()
  101. {
  102. return g_SubWorldSet.m_nLoopRate;
  103. }
  104. //获取连接状况
  105. int  CoreServerShell::GetConnectInfo(KCoreConnectInfo* pInfo)
  106. {
  107. if (pInfo)
  108. pInfo->nNumPlayer = PlayerSet.GetPlayerNumber();
  109. return 1;
  110. }
  111. int CoreServerShell::AddCharacter(int nExtPoint, int nChangeExtPoint, void* pBuffer, GUID* pGuid)
  112. {
  113. int nIdx = 0;
  114. const TRoleData* pData = (const TRoleData*)pBuffer;
  115. if (pData && pData->BaseInfo.szName[0])
  116. {
  117. nIdx = PlayerSet.Add((char*)pData->BaseInfo.szName, pGuid);
  118. if (nIdx <= 0 || nIdx >= MAX_PLAYER)
  119. return 0;
  120. strcpy(Player[nIdx].m_AccoutName, pData->BaseInfo.caccname);
  121. strcpy(Player[nIdx].m_PlayerName, pData->BaseInfo.szName);
  122. DWORD dwLen = pData->dwDataLen;
  123. // _ASSERT(dwLen < 64 * 1024);
  124. ZeroMemory(Player[nIdx].m_SaveBuffer, sizeof(Player[nIdx].m_SaveBuffer));
  125. memcpy(Player[nIdx].m_SaveBuffer, pBuffer, dwLen);
  126. Player[nIdx].m_pStatusLoadPlayerInfo = Player[nIdx].m_SaveBuffer;
  127. // 扩展点,用于活动
  128. Player[nIdx].SetExtPoint(nExtPoint, nChangeExtPoint);
  129. return nIdx;
  130. }
  131. return 0;
  132. }
  133. bool CoreServerShell::PlayerDbLoading(int nPlayerIndex, int bSyncEnd, int& nStep, unsigned int& nParam)
  134. {
  135. TRoleData* pData = (TRoleData *)Player[nPlayerIndex].m_pStatusLoadPlayerInfo;
  136. if (bSyncEnd)
  137. {
  138. Player[nPlayerIndex].m_pStatusLoadPlayerInfo = NULL;
  139. nStep = 0;
  140. nParam = 0;
  141. return true;
  142. }
  143. else if (pData)
  144. {
  145. // if (0 == Player[nPlayerIndex].LoadDBPlayerInfo((BYTE *)pData, nStep, nParam))
  146. // {
  147. // // 把玩家的登入状态设置为未登入,等待时延自动清除
  148. // Player[nPlayerIndex].m_nNetConnectIdx = -1;
  149. // Player[nPlayerIndex].m_dwLoginTime = -1;
  150. // return false;
  151. // }
  152. // else
  153. // return true;
  154. return Player[nPlayerIndex].LoadDBPlayerInfo((BYTE *)pData, nStep, nParam);
  155. }
  156. return false;
  157. }
  158. void CoreServerShell::AddPlayerToWorld(int nIndex)
  159. {
  160. // int nIndex = PlayerSet.FindClient(lnID);
  161. Player[nIndex].LaunchPlayer();
  162. }
  163. void CoreServerShell::ProcessClientMessage(int nIndex, const char* pChar, int nSize)
  164. {
  165. PlayerSet.ProcessClientMessage(nIndex, pChar, nSize);
  166. }
  167. void CoreServerShell::ProcessNewClientMessage(IClient* pTransfer,
  168.    DWORD dwFromIP, DWORD dwFromRelayID,
  169.    int nPlayerIndex,
  170.    const char* pChar, int nSize)
  171. {
  172. g_NewProtocolProcess.ProcessNetMsg(pTransfer, dwFromIP, dwFromRelayID,
  173. nPlayerIndex, (BYTE*)pChar, nSize);
  174. }
  175. void CoreServerShell::SendNetMsgToTransfer(IClient* pClient)
  176. {
  177. g_NewProtocolProcess.SendNetMsgToTransfer(pClient);
  178. }
  179. void CoreServerShell::SendNetMsgToChat(IClient* pClient)
  180. {
  181. g_NewProtocolProcess.SendNetMsgToChat(pClient);
  182. }
  183. void CoreServerShell::SendNetMsgToTong(IClient* pClient)
  184. {
  185. g_NewProtocolProcess.SendNetMsgToTong(pClient);
  186. }
  187. void CoreServerShell::ProcessBroadcastMessage(const char* pChar, int nSize)
  188. {
  189. g_NewProtocolProcess.BroadcastLocalServer(pChar, nSize);
  190. }
  191. void CoreServerShell::ProcessExecuteMessage(const char* pChar, int nSize)
  192. {
  193. g_NewProtocolProcess.ExecuteLocalServer(pChar, nSize);
  194. }
  195. void CoreServerShell::ClientDisconnect(int nIndex)
  196. {
  197. // PlayerSet.Remove(nClient);
  198. PlayerSet.PrepareRemove(nIndex);
  199. }
  200. void CoreServerShell::RemoveQuitingPlayer(int nIndex)
  201. {
  202. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  203. return;
  204. if (Player[nIndex].IsWaitingRemove())
  205. {
  206. PlayerSet.RemoveQuiting(nIndex);
  207. }
  208. }
  209. //--------------------------------------------------------------------------
  210. // 功能:从游戏世界获取数据
  211. // 参数:unsigned int uDataId --> 表示获取游戏数据的数据项内容索引,其值为梅举类型
  212. // GAMEDATA_INDEX的取值之一。
  213. //   unsigned int uParam  --> 依据uDataId的取值情况而定
  214. //   int nParam --> 依据uDataId的取值情况而定
  215. // 返回:依据uDataId的取值情况而定。
  216. //--------------------------------------------------------------------------
  217. int CoreServerShell::GetGameData(unsigned int uDataId, unsigned int uParam, int nParam)
  218. {
  219. int nRet = 0;
  220. switch(uDataId)
  221. {
  222. case SGDI_CHARACTER_ACCOUNT:
  223. if (uParam)
  224. {
  225. nRet = PlayerSet.GetPlayerAccount(nParam, (char *)uParam);
  226. if (nRet == FALSE)
  227. ((char *)uParam)[0] = 0;
  228. }
  229. break;
  230. case SGDI_CHARACTER_NAME:
  231. if (uParam)
  232. {
  233. nRet = PlayerSet.GetPlayerName(nParam, (char*)uParam);
  234. if (nRet == FALSE)
  235. ((char *)uParam)[0] = 0;
  236. }
  237. break;
  238. case SGDI_CHARACTER_EXTPOINTCHANGED:
  239. if (uParam)
  240. {
  241. if (uParam >= MAX_PLAYER)
  242. {
  243. nRet = 0;
  244. break;
  245. }
  246. nRet = Player[uParam].GetExtPointChanged();
  247. }
  248. break;
  249. case SGDI_CHARACTER_EXTPOINT:
  250. if (uParam)
  251. {
  252. if (uParam >= MAX_PLAYER)
  253. {
  254. nRet = 0;
  255. break;
  256. }
  257. nRet = Player[uParam].GetExtPoint();
  258. }
  259. break;
  260. case SGDI_LOADEDMAP_ID:
  261. if (uParam)
  262. {
  263. int i;
  264. int nMax = nParam;
  265. if(nMax < MAX_SUBWORLD) nMax = MAX_SUBWORLD;
  266. for (i = 0; i < nMax; i++)
  267. {
  268. if (SubWorld[i].m_SubWorldID != -1)
  269. {
  270. ((char *)uParam)[i] = (char)SubWorld[i].m_SubWorldID;
  271. }
  272. else
  273. {
  274. nRet = i;
  275. break;
  276. }
  277. }
  278. }
  279. break;
  280. case SGDI_CHARACTER_ID:
  281. if (uParam)
  282. {
  283. if (uParam >= MAX_PLAYER)
  284. {
  285. nRet = 0;
  286. break;
  287. }
  288. nRet = Player[uParam].m_dwID;
  289. break;
  290. }
  291. break;
  292. case SGDI_CHARACTER_NETID:
  293. if (uParam)
  294. {
  295. if (uParam >= MAX_PLAYER)
  296. {
  297. nRet = -1;
  298. break;
  299. }
  300. nRet = Player[uParam].m_nNetConnectIdx;
  301. }
  302. break;
  303. // 传入帮会建立参数,返回条件是否成立
  304. // uParam : struct STONG_SERVER_TO_CORE_APPLY_CREATE point
  305. // return : 条件是否成立
  306. case SGDI_TONG_APPLY_CREATE:
  307. if (uParam)
  308. {
  309. STONG_SERVER_TO_CORE_APPLY_CREATE *pApply = (STONG_SERVER_TO_CORE_APPLY_CREATE*)uParam;
  310. int nPlayerIdx;
  311. int nCamp;
  312. char szTongName[defTONG_NAME_MAX_LENGTH + 2];
  313. szTongName[sizeof(szTongName) - 1] = 0;
  314. memcpy(szTongName, pApply->m_szTongName, sizeof(szTongName));
  315. nPlayerIdx = pApply->m_nPlayerIdx;
  316. nCamp = pApply->m_nCamp;
  317. if (nPlayerIdx <= 0 || nPlayerIdx >= MAX_PLAYER)
  318. {
  319. nRet = FALSE;
  320. break;
  321. }
  322. nRet = Player[nPlayerIdx].m_cTong.CheckCreateCondition(nCamp, szTongName);
  323. }
  324. break;
  325. // 申请加入帮会
  326. // uParam : struct STONG_SERVER_TO_CORE_APPLY_ADD point
  327. case SGDI_TONG_APPLY_ADD:
  328. if (uParam)
  329. {
  330. STONG_SERVER_TO_CORE_APPLY_ADD *pAdd = (STONG_SERVER_TO_CORE_APPLY_ADD*)uParam;
  331. if (pAdd->m_nPlayerIdx <= 0 || pAdd->m_nPlayerIdx >= MAX_PLAYER)
  332. break;
  333. Player[pAdd->m_nPlayerIdx].m_cTong.TransferAddApply(pAdd->m_dwNpcID);
  334. }
  335. break;
  336. // 判断加入帮会条件是否合适
  337. // uParam : 传入得 char point ,用于接收帮会名称
  338. // nParam : struct STONG_SERVER_TO_CORE_CHECK_ADD_CONDITION point
  339. case SGDI_TONG_CHECK_ADD_CONDITION:
  340. {
  341. nRet = 0;
  342. STONG_SERVER_TO_CORE_CHECK_ADD_CONDITION *pAdd;
  343. pAdd = (STONG_SERVER_TO_CORE_CHECK_ADD_CONDITION*)nParam;
  344. if (pAdd->m_nSelfIdx <= 0 || pAdd->m_nSelfIdx >= MAX_PLAYER)
  345. break;
  346. if (pAdd->m_nTargetIdx <= 0 || pAdd->m_nTargetIdx >= MAX_PLAYER || g_FileName2Id(Npc[Player[pAdd->m_nTargetIdx].m_nIndex].Name) != pAdd->m_dwNameID)
  347. break;
  348. if (Player[pAdd->m_nSelfIdx].m_cTong.CheckAddCondition(pAdd->m_nTargetIdx))
  349. {
  350. Player[pAdd->m_nSelfIdx].m_cTong.GetTongName((char*)uParam);
  351. nRet = 1;
  352. }
  353. }
  354. break;
  355. // 获得帮会信息
  356. // uParam : 传入的 STONG_SERVER_TO_CORE_GET_INFO point
  357. case SGDI_TONG_GET_INFO:
  358. {
  359. STONG_SERVER_TO_CORE_GET_INFO *pInfo = (STONG_SERVER_TO_CORE_GET_INFO*)uParam;
  360. switch (pInfo->m_nInfoID)
  361. {
  362. case enumTONG_APPLY_INFO_ID_SELF:
  363. {
  364. if (pInfo->m_nSelfIdx <= 0 || pInfo->m_nSelfIdx >= MAX_PLAYER)
  365. break;
  366. Player[pInfo->m_nSelfIdx].m_cTong.SendSelfInfo();
  367. }
  368. break;
  369. case enumTONG_APPLY_INFO_ID_MASTER:
  370. break;
  371. case enumTONG_APPLY_INFO_ID_DIRECTOR:
  372. break;
  373. case enumTONG_APPLY_INFO_ID_MANAGER:
  374. {
  375. nRet = 0;
  376. if (pInfo->m_nSelfIdx <= 0 || pInfo->m_nSelfIdx >= MAX_PLAYER)
  377. break;
  378. if (Player[pInfo->m_nSelfIdx].m_cTong.CanGetManagerInfo((DWORD)pInfo->m_nParam1))
  379. nRet = 1;
  380. }
  381. break;
  382. case enumTONG_APPLY_INFO_ID_MEMBER:
  383. {
  384. nRet = 0;
  385. if (pInfo->m_nSelfIdx <= 0 || pInfo->m_nSelfIdx >= MAX_PLAYER)
  386. break;
  387. if (Player[pInfo->m_nSelfIdx].m_cTong.CanGetMemberInfo((DWORD)pInfo->m_nParam1))
  388. nRet = 1;
  389. }
  390. break;
  391. case enumTONG_APPLY_INFO_ID_ONE:
  392. break;
  393. case enumTONG_APPLY_INFO_ID_TONG_HEAD:
  394. {
  395. nRet = 0;
  396. if (pInfo->m_nSelfIdx <= 0 || pInfo->m_nSelfIdx >= MAX_PLAYER)
  397. break;
  398. int nPlayer;
  399. if (Npc[Player[pInfo->m_nSelfIdx].m_nIndex].m_dwID == (DWORD)pInfo->m_nParam1)
  400. nPlayer = pInfo->m_nSelfIdx;
  401. else
  402. nPlayer = Player[pInfo->m_nSelfIdx].FindAroundPlayer((DWORD)pInfo->m_nParam1);
  403. if (nPlayer == -1)
  404. break;
  405. nRet = Player[nPlayer].m_cTong.GetTongNameID();
  406. }
  407. break;
  408. }
  409. }
  410. break;
  411. // 判断是否有任命权利
  412. // uParam : 传入的 TONG_APPLY_INSTATE_COMMAND point
  413. // nParam : PlayerIndex
  414. case SGDI_TONG_INSTATE_POWER:
  415. if (uParam)
  416. {
  417. nRet = 0;
  418. TONG_APPLY_INSTATE_COMMAND *pApply = (TONG_APPLY_INSTATE_COMMAND*)uParam;
  419. if (nParam <= 0 || nParam >= MAX_PLAYER)
  420. break;
  421. if (Player[nParam].m_nIndex <= 0)
  422. break;
  423. nRet = Player[nParam].m_cTong.CheckInstatePower(pApply);
  424. }
  425. break;
  426. // 被任命,帮会数据变化
  427. // uParam : 传入的 STONG_SERVER_TO_CORE_BE_INSTATED point
  428. case SGDI_TONG_BE_INSTATED:
  429. if (uParam)
  430. {
  431. STONG_SERVER_TO_CORE_BE_INSTATED *pInstated = (STONG_SERVER_TO_CORE_BE_INSTATED*)uParam;
  432. if (pInstated->m_nPlayerIdx <= 0 || pInstated->m_nPlayerIdx >= MAX_PLAYER)
  433. break;
  434. if (Player[pInstated->m_nPlayerIdx].m_nIndex <= 0)
  435. break;
  436. Player[pInstated->m_nPlayerIdx].m_cTong.BeInstated(pInstated);
  437. }
  438. break;
  439. // 判断是否有踢人权利
  440. // uParam : 传入的 TONG_APPLY_KICK_COMMAND point
  441. // nParam : PlayerIndex
  442. case SGDI_TONG_KICK_POWER:
  443. if (uParam)
  444. {
  445. nRet = 0;
  446. TONG_APPLY_KICK_COMMAND *pKick = (TONG_APPLY_KICK_COMMAND*)uParam;
  447. if (nParam <= 0 || nParam >= MAX_PLAYER)
  448. break;
  449. if (Player[nParam].m_nIndex <= 0)
  450. break;
  451. nRet = Player[nParam].m_cTong.CheckKickPower(pKick);
  452. }
  453. break;
  454. // 被踢出帮会
  455. // uParam : 传入的 STONG_SERVER_TO_CORE_BE_KICKED point
  456. case SGDI_TONG_BE_KICKED:
  457. if (uParam)
  458. {
  459. STONG_SERVER_TO_CORE_BE_KICKED *pKicked = (STONG_SERVER_TO_CORE_BE_KICKED*)uParam;
  460. if (pKicked->m_nPlayerIdx <= 0 || pKicked->m_nPlayerIdx >= MAX_PLAYER)
  461. break;
  462. if (Player[pKicked->m_nPlayerIdx].m_nIndex <= 0)
  463. break;
  464. Player[pKicked->m_nPlayerIdx].m_cTong.BeKicked(pKicked);
  465. }
  466. break;
  467. // 离开帮会
  468. // uParam : 传入的 TONG_APPLY_LEAVE_COMMAND point
  469. // nParam : PlayerIndex
  470. case SGDI_TONG_LEAVE_POWER:
  471. if (uParam)
  472. {
  473. nRet = 0;
  474. TONG_APPLY_LEAVE_COMMAND *pLeave = (TONG_APPLY_LEAVE_COMMAND*)uParam;
  475. if (nParam <= 0 || nParam >= MAX_PLAYER)
  476. break;
  477. if (Player[nParam].m_nIndex <= 0)
  478. break;
  479. nRet = Player[nParam].m_cTong.CheckLeavePower(pLeave);
  480. }
  481. break;
  482. // 离开帮会
  483. // uParam : 传入的 STONG_SERVER_TO_CORE_LEAVE point
  484. case SGDI_TONG_LEAVE:
  485. if (uParam)
  486. {
  487. STONG_SERVER_TO_CORE_LEAVE *pLeave = (STONG_SERVER_TO_CORE_LEAVE*)uParam;
  488. if (pLeave->m_nPlayerIdx <= 0 || pLeave->m_nPlayerIdx >= MAX_PLAYER)
  489. break;
  490. if (Player[pLeave->m_nPlayerIdx].m_nIndex <= 0)
  491. break;
  492. Player[pLeave->m_nPlayerIdx].m_cTong.Leave(pLeave);
  493. }
  494. break;
  495. // 离开帮会判断
  496. // uParam : 传入的 TONG_APPLY_CHANGE_MASTER_COMMAND point
  497. // nParam : PlayerIndex
  498. case SGDI_TONG_CHANGE_MASTER_POWER:
  499. if (uParam)
  500. {
  501. nRet = 0;
  502. TONG_APPLY_CHANGE_MASTER_COMMAND *pChange = (TONG_APPLY_CHANGE_MASTER_COMMAND*)uParam;
  503. if (nParam <= 0 || nParam >= MAX_PLAYER)
  504. break;
  505. if (Player[nParam].m_nIndex <= 0)
  506. break;
  507. nRet = Player[nParam].m_cTong.CheckChangeMasterPower(pChange);
  508. }
  509. break;
  510. // 能否接受传位判断
  511. // uParam : 传入的 STONG_SERVER_TO_CORE_CHECK_GET_MASTER_POWER point
  512. case SGDI_TONG_GET_MASTER_POWER:
  513. if (uParam)
  514. {
  515. nRet = 0;
  516. STONG_SERVER_TO_CORE_CHECK_GET_MASTER_POWER *pCheck = (STONG_SERVER_TO_CORE_CHECK_GET_MASTER_POWER*)uParam;
  517. if (pCheck->m_nPlayerIdx <= 0 || pCheck->m_nPlayerIdx >= MAX_PLAYER)
  518. break;
  519. if (Player[pCheck->m_nPlayerIdx].m_nIndex <= 0)
  520. break;
  521. nRet = Player[pCheck->m_nPlayerIdx].m_cTong.CheckGetMasterPower(pCheck);
  522. }
  523. break;
  524. // 传位导致身份改变
  525. // uParam : 传入的 STONG_SERVER_TO_CORE_CHANGE_AS point
  526. case SGDI_TONG_CHANGE_AS:
  527. if (uParam)
  528. {
  529. STONG_SERVER_TO_CORE_CHANGE_AS *pAs = (STONG_SERVER_TO_CORE_CHANGE_AS*)uParam;
  530. if (pAs->m_nPlayerIdx <= 0 || pAs->m_nPlayerIdx >= MAX_PLAYER)
  531. break;
  532. if (Player[pAs->m_nPlayerIdx].m_nIndex <= 0)
  533. break;
  534. Player[pAs->m_nPlayerIdx].m_cTong.ChangeAs(pAs);
  535. }
  536. break;
  537. // 帮主换了
  538. // uParam : 传入的 STONG_SERVER_TO_CORE_CHANGE_MASTER point
  539. case SGDI_TONG_CHANGE_MASTER:
  540. if (uParam)
  541. {
  542. STONG_SERVER_TO_CORE_CHANGE_MASTER *pChange = (STONG_SERVER_TO_CORE_CHANGE_MASTER*)uParam;
  543. int nIdx;
  544. nIdx = PlayerSet.GetFirstPlayer();
  545. while (nIdx)
  546. {
  547. if (Player[nIdx].m_cTong.GetTongNameID() == pChange->m_dwTongNameID)
  548. {
  549. Player[nIdx].m_cTong.ChangeMaster(pChange->m_szName);
  550. }
  551. nIdx = PlayerSet.GetNextPlayer();
  552. }
  553. }
  554. break;
  555. // 获得帮会名字符串转换成的 dword
  556. // nParam : PlayerIndex
  557. case SGDI_TONG_GET_TONG_NAMEID:
  558. {
  559. if (nParam <= 0 || nParam >= MAX_PLAYER)
  560. break;
  561. if (Player[nParam].m_nIndex <= 0)
  562. break;
  563. nRet = Player[nParam].m_cTong.GetTongNameID();
  564. }
  565. break;
  566. // 登陆时候获得帮会信息
  567. // uParam : 传入的 STONG_SERVER_TO_CORE_LOGIN point
  568. case SGDI_TONG_LOGIN:
  569. if (uParam)
  570. {
  571. STONG_SERVER_TO_CORE_LOGIN *pLogin = (STONG_SERVER_TO_CORE_LOGIN*)uParam;
  572. if (pLogin->m_dwParam <= 0 || pLogin->m_dwParam >= MAX_PLAYER)
  573. break;
  574. if (Player[pLogin->m_dwParam].m_nIndex <= 0)
  575. break;
  576. Player[pLogin->m_dwParam].m_cTong.Login(pLogin);
  577. }
  578. break;
  579. // 通知core发送某玩家的帮会信息
  580. // nParam : player index
  581. case SGDI_TONG_SEND_SELF_INFO:
  582. {
  583. if (nParam <= 0 || nParam >= MAX_PLAYER)
  584. break;
  585. if (Player[nParam].m_nIndex <= 0)
  586. break;
  587. Player[nParam].m_cTong.SendSelfInfo();
  588. }
  589. break;
  590. default:
  591. break;
  592. }
  593. return nRet;
  594. }
  595. //--------------------------------------------------------------------------
  596. // 功能:向游戏发送操作
  597. // 参数:unsigned int uDataId --> Core外部客户对core的操作请求的索引定义
  598. // 其值为梅举类型GAMEOPERATION_INDEX的取值之一。
  599. //   unsigned int uParam  --> 依据uOperId的取值情况而定
  600. //   int nParam --> 依据uOperId的取值情况而定
  601. // 返回:如果成功发送操作请求,函数返回非0值,否则返回0值。
  602. //--------------------------------------------------------------------------
  603. int CoreServerShell::OperationRequest(unsigned int uOper, unsigned int uParam, int nParam)
  604. {
  605. int nRet = 1;
  606. switch(uOper)
  607. {
  608. case SSOI_BROADCASTING:
  609. nRet = PlayerSet.Broadcasting((char*)uParam, nParam);
  610. break;
  611. case SSOI_LAUNCH: //启动服务
  612. nRet = OnLunch((LPVOID)uParam);
  613. break;
  614. case SSOI_SHUTDOWN: //关闭服务
  615. nRet = OnShutdown();
  616. break;
  617. case SSOI_RELOAD_WELCOME_MSG:
  618. PlayerSet.ReloadWelcomeMsg();
  619. break;
  620. // relay 帮会创建成功,通知 core 进行相应的处理
  621. case SSOI_TONG_CREATE:
  622. {
  623. STONG_SERVER_TO_CORE_CREATE_SUCCESS *pCreate = (STONG_SERVER_TO_CORE_CREATE_SUCCESS*)uParam;
  624. if (pCreate->m_nPlayerIdx <= 0 || pCreate->m_nPlayerIdx >= MAX_PLAYER)
  625. {
  626. nRet = 0;
  627. break;
  628. }
  629. if (Player[pCreate->m_nPlayerIdx].m_nIndex)
  630. {
  631. DWORD dwID = g_FileName2Id(Npc[Player[pCreate->m_nPlayerIdx].m_nIndex].Name);
  632. if (dwID != pCreate->m_dwPlayerNameID)
  633. {
  634. nRet = 0;
  635. break;
  636. }
  637. }
  638. else
  639. {
  640. nRet = 0;
  641. break;
  642. }
  643. nRet = Player[pCreate->m_nPlayerIdx].CreateTong(pCreate->m_nCamp, pCreate->m_szTongName);
  644. }
  645. break;
  646. case SSOI_TONG_REFUSE_ADD:
  647. if (uParam)
  648. {
  649. STONG_SERVER_TO_CORE_REFUSE_ADD *pRefuse = (STONG_SERVER_TO_CORE_REFUSE_ADD*)uParam;
  650. if (pRefuse->m_nSelfIdx > 0 && pRefuse->m_nSelfIdx <= MAX_PLAYER)
  651. {
  652. Player[pRefuse->m_nSelfIdx].m_cTong.SendRefuseMessage(pRefuse->m_nTargetIdx, pRefuse->m_dwNameID);
  653. }
  654. }
  655. break;
  656. case SSOI_TONG_ADD:
  657. if (uParam)
  658. {
  659. nRet = 0;
  660. STONG_SERVER_TO_CORE_ADD_SUCCESS *pAdd = (STONG_SERVER_TO_CORE_ADD_SUCCESS*)uParam;
  661. if (pAdd->m_nPlayerIdx <= 0 || pAdd->m_nPlayerIdx >= MAX_PLAYER)
  662. break;
  663. if (Player[pAdd->m_nPlayerIdx].m_nIndex <= 0)
  664. break;
  665. if (g_FileName2Id(Npc[Player[pAdd->m_nPlayerIdx].m_nIndex].Name) != pAdd->m_dwPlayerNameID)
  666. break;
  667. Player[pAdd->m_nPlayerIdx].m_cTong.AddTong(
  668. pAdd->m_nCamp,
  669. pAdd->m_szTongName,
  670. pAdd->m_szMasterName,
  671. pAdd->m_szTitleName);
  672. }
  673. break;
  674. default:
  675. nRet = 0;
  676. break;
  677. }
  678. return nRet;
  679. }
  680. int CoreServerShell::OnLunch(LPVOID pServer)
  681. {
  682. g_SetServer(pServer);
  683. // g_SetFilePath("\script");
  684. KLuaScript * pStartScript =(KLuaScript*) g_GetScript("\script\ServerScript.lua");
  685. int i = 0;
  686. if (!pStartScript)
  687. g_DebugLog("Load ServerScript failed!");
  688. else
  689. {
  690. pStartScript->CallFunction("StartGame",0,"");
  691. }
  692. PlayerSet.ReloadWelcomeMsg();
  693. return true;
  694. }
  695. int CoreServerShell::OnShutdown()
  696. {
  697. return true;
  698. }
  699. //日常活动,core如果要寿终正寝则返回0,否则返回非0值
  700. int CoreServerShell::Breathe()
  701. {
  702. g_SubWorldSet.MessageLoop();
  703. g_SubWorldSet.MainLoop();
  704. return true;
  705. }
  706. bool CoreServerShell::CheckProtocolSize(const char* pChar, int nSize)
  707. {
  708. WORD wCheckSize;
  709. BYTE nProtocol = (BYTE)pChar[0];
  710. if (nProtocol >= c2s_end || nProtocol <= c2s_gameserverbegin)
  711. {
  712. g_DebugLog("[error]NetServer:Invalid Protocol!");
  713. return false;
  714. }
  715. if (g_nProtocolSize[nProtocol - c2s_gameserverbegin - 1] == -1)
  716. {
  717. wCheckSize = *(WORD*)&pChar[1] + PROTOCOL_MSG_SIZE;
  718. }
  719. else
  720. {
  721. wCheckSize = g_nProtocolSize[nProtocol - c2s_gameserverbegin - 1];
  722. }
  723. if (wCheckSize != nSize)
  724. {
  725. g_DebugLog("[error]网络接收协议大小不匹配");
  726. #ifndef _WIN32
  727. printf("[error]网络接收协议大小不匹配<%d>, should %d, but %dn", nProtocol, wCheckSize, nSize);
  728. #endif
  729. return false;
  730. }
  731. return true;
  732. }
  733. int CoreServerShell::AttachPlayer(const unsigned long lnID, GUID* pGuid)
  734. {
  735. return PlayerSet.AttachPlayer(lnID, pGuid);
  736. }
  737. void* CoreServerShell::SavePlayerDataAtOnce(int nIndex)
  738. {
  739. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  740. {
  741. return NULL;
  742. }
  743. if (Player[nIndex].Save())
  744. {
  745. Player[nIndex].m_uMustSave = SAVE_REQUEST;
  746. return &Player[nIndex].m_SaveBuffer;
  747. }
  748. else
  749. {
  750. return NULL;
  751. }
  752. }
  753. bool CoreServerShell::IsCharacterQuiting(int nIndex)
  754. {
  755. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  756. {
  757. return FALSE;
  758. }
  759. return Player[nIndex].IsWaitingRemove();
  760. }
  761. bool CoreServerShell::IsPlayerLoginTimeOut(int nIndex)
  762. {
  763. return Player[nIndex].IsLoginTimeOut();
  764. }
  765. void CoreServerShell::RemovePlayerLoginTimeOut(int nIndex)
  766. {
  767. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  768. return;
  769. if (Player[nIndex].IsLoginTimeOut())
  770. {
  771. PlayerSet.RemoveLoginTimeOut(nIndex);
  772. }
  773. }
  774. int CoreServerShell::AddTempTaskValue(int nIndex, const char* pData)
  775. {
  776. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  777. return 0;
  778. return Player[nIndex].AddTempTaskValue((void *)pData);
  779. }
  780. void CoreServerShell::GetPlayerIndexByGuid(GUID* pGuid, int* pnIndex, int* plnID)
  781. {
  782. *pnIndex = PlayerSet.GetPlayerIndexByGuid(pGuid);
  783. if (*pnIndex)
  784. {
  785. *plnID = Player[*pnIndex].m_nNetConnectIdx;
  786. }
  787. else
  788. {
  789. *plnID = -1;
  790. }
  791. if (*plnID == -1)
  792. {
  793. *pnIndex = 0;
  794. }
  795. }
  796. void* CoreServerShell::PreparePlayerForExchange(int nIndex)
  797. {
  798. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  799. return NULL;
  800. PlayerSet.PrepareExchange(nIndex);
  801. return &Player[nIndex].m_SaveBuffer;
  802. }
  803. bool CoreServerShell::IsPlayerExchangingServer(int nIndex)
  804. {
  805. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  806. return false;
  807. return Player[nIndex].IsExchangingServer();
  808. }
  809. void CoreServerShell::RemovePlayerForExchange(int nIndex)
  810. {
  811. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  812. return;
  813. PlayerSet.RemoveExchanging(nIndex);
  814. }
  815. void CoreServerShell::GetGuid(int nIndex, void* pGuid)
  816. {
  817. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  818. return;
  819. memcpy(pGuid, &Player[nIndex].m_Guid, sizeof(GUID));
  820. }
  821. DWORD CoreServerShell::GetExchangeMap(int nIndex)
  822. {
  823. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  824. return -1;
  825. return Player[nIndex].m_sExchangePos.m_dwMapID;
  826. }
  827. void CoreServerShell::RecoverPlayerExchange(int nIndex)
  828. {
  829. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  830. return;
  831. Player[nIndex].m_bExchangeServer = FALSE;
  832. if (Player[nIndex].m_nIndex > 0)
  833. {
  834. KNpc* pNpc = &Npc[Player[nIndex].m_nIndex];
  835. pNpc->m_bExchangeServer = FALSE;
  836. pNpc->m_FightMode = pNpc->m_OldFightMode;
  837. }
  838. Player[nIndex].Earn(Player[nIndex].m_nPrePayMoney);
  839. Player[nIndex].m_nPrePayMoney = 0;
  840. }
  841. void CoreServerShell::SetSaveStatus(int nIndex, UINT uStatus)
  842. {
  843. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  844. return;
  845. Player[nIndex].m_uMustSave = uStatus;
  846. }
  847. UINT CoreServerShell::GetSaveStatus(int nIndex)
  848. {
  849. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  850. return SAVE_IDLE;
  851. return Player[nIndex].m_uMustSave;
  852. }
  853. void CoreServerShell::PreparePlayerForLoginFailed(int nIndex)
  854. {
  855. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  856. return;
  857. PlayerSet.PrepareLoginFailed(nIndex);
  858. }
  859. //BOOL CoreServerShell::ValidPingTime(int nIndex)
  860. //{
  861. // if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  862. // return FALSE;
  863. //
  864. // if (Player[nIndex].m_uLastPingTime == -1)
  865. // return TRUE;
  866. //
  867. //#define MAX_PING_TIME (60 * 20) // 1min
  868. // if (g_SubWorldSet.GetGameTime() - Player[nIndex].m_uLastPingTime > MAX_PING_TIME)
  869. // {
  870. // return FALSE;
  871. // }
  872. // return TRUE;
  873. //}
  874. BOOL CoreServerShell::GroupChat(IClient* pClient, DWORD FromIP, unsigned long FromRelayID, DWORD channid, BYTE tgtcls, DWORD tgtid, const void* pData, size_t size)
  875. {
  876. switch(tgtcls)
  877. {
  878. case tgtcls_team:
  879. {{
  880. if (tgtid < 0 || tgtid >= MAX_TEAM)
  881. return FALSE;
  882. size_t pckgsize = sizeof(tagExtendProtoHeader) + size;
  883. #ifdef WIN32
  884. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)_alloca(pckgsize);
  885. #else
  886. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)(new char[pckgsize]);
  887. #endif
  888. pExHeader->ProtocolType = s2c_extendchat;
  889. pExHeader->wLength = pckgsize - 1;
  890. memcpy(pExHeader + 1, pData, size);
  891. int nTargetIdx;
  892. // 给队长发
  893. nTargetIdx = g_Team[tgtid].m_nCaptain;
  894. // if (FromRelayID != Player[nTargetIdx].m_nNetConnectIdx)
  895. g_pServer->SendData(Player[nTargetIdx].m_nNetConnectIdx, pData, size);
  896. // 给队员发
  897. for (int i = 0; i < MAX_TEAM_MEMBER; i++)
  898. {
  899. nTargetIdx = g_Team[tgtid].m_nMember[i];
  900. if (nTargetIdx < 0)
  901. continue;
  902. // if (FromRelayID != Player[nTargetIdx].m_nNetConnectIdx)
  903. g_pServer->PackDataToClient(Player[nTargetIdx].m_nNetConnectIdx, pExHeader, pckgsize);
  904. }
  905. #ifndef WIN32
  906. delete ((char*)pExHeader);
  907. #endif
  908. }}
  909. break;
  910. case tgtcls_fac:
  911. {{
  912. size_t pckgsize = sizeof(tagExtendProtoHeader) + size;
  913. #ifdef WIN32
  914. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)_alloca(pckgsize);
  915. #else
  916. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)(new char[pckgsize]);
  917. #endif
  918. pExHeader->ProtocolType = s2c_extendchat;
  919. pExHeader->wLength = pckgsize - 1;
  920. memcpy(pExHeader + 1, pData, size);
  921. int nTargetIdx;
  922. nTargetIdx = PlayerSet.GetFirstPlayer();
  923. while (nTargetIdx)
  924. {
  925. if (Player[nTargetIdx].m_cFaction.m_nCurFaction == tgtid
  926. )// && FromRelayID != Player[nTargetIdx].m_nNetConnectIdx)
  927. g_pServer->PackDataToClient(Player[nTargetIdx].m_nNetConnectIdx, pExHeader, pckgsize);
  928. nTargetIdx = PlayerSet.GetNextPlayer();
  929. }
  930. #ifndef WIN32
  931. delete ((char*)pExHeader);
  932. #endif
  933. }}
  934. break;
  935. case tgtcls_tong:
  936. {{
  937. size_t pckgsize = sizeof(tagExtendProtoHeader) + size;
  938. #ifdef WIN32
  939. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)_alloca(pckgsize);
  940. #else
  941. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)(new char[pckgsize]);
  942. #endif
  943. pExHeader->ProtocolType = s2c_extendchat;
  944. pExHeader->wLength = pckgsize - 1;
  945. memcpy(pExHeader + 1, pData, size);
  946. int nTargetIdx;
  947. nTargetIdx = PlayerSet.GetFirstPlayer();
  948. while (nTargetIdx)
  949. {
  950. if (Player[nTargetIdx].m_cTong.GetTongNameID() == tgtid
  951. )// && FromRelayID != Player[nTargetIdx].m_nNetConnectIdx)
  952. g_pServer->PackDataToClient(Player[nTargetIdx].m_nNetConnectIdx, pExHeader, pckgsize);
  953. nTargetIdx = PlayerSet.GetNextPlayer();
  954. }
  955. #ifndef WIN32
  956. delete ((char*)pExHeader);
  957. #endif
  958. }}
  959. break;
  960. case tgtcls_scrn:
  961. {{
  962. // int nMaxRelayPlayer = (1024 - 32 - sizeof(CHAT_GROUPMAN) - size) / sizeof(WORD);
  963. // if (nMaxRelayPlayer <= 0)
  964. // return FALSE;
  965. int idxNPC = Player[tgtid].m_nIndex;
  966. int idxSubWorld = Npc[idxNPC].m_SubWorldIndex;
  967. int idxRegion = Npc[idxNPC].m_RegionIndex;
  968. // _ASSERT(idxSubWorld >= 0 && idxRegion >= 0);
  969. int nOX = Npc[idxNPC].m_MapX;
  970. int nOY = Npc[idxNPC].m_MapY;
  971. int nTX = 0;
  972. int nTY = 0;
  973. if (idxSubWorld < 0 || idxRegion < 0)
  974. return FALSE;
  975. // size_t basesize = sizeof(CHAT_GROUPMAN) + size;
  976. // BYTE buffer[1024];
  977. //
  978. // CHAT_GROUPMAN* pCgc = (CHAT_GROUPMAN*)buffer;
  979. // pCgc->ProtocolType = chat_groupman;
  980. // pCgc->wChatLength = size;
  981. // pCgc->byHasIdentify = false;
  982. //
  983. // void* pExPckg = pCgc + 1;
  984. // memcpy(pExPckg, pData, size);
  985. //
  986. // WORD* pPlayers = (WORD*)((BYTE*)pExPckg + size);
  987. //
  988. //
  989. // pCgc->wPlayerCount = 0;
  990. size_t pckgsize = sizeof(tagExtendProtoHeader) + size;
  991. #ifdef WIN32
  992. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)_alloca(pckgsize);
  993. #else
  994. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)(new char[pckgsize]);
  995. #endif
  996. pExHeader->ProtocolType = s2c_extendchat;
  997. pExHeader->wLength = pckgsize - 1;
  998. memcpy(pExHeader + 1, pData, size);
  999. #define MAX_SYNC_RANGE 23
  1000. static POINT POff[9] = 
  1001. {
  1002. {0, 0},
  1003. {0, 32},
  1004. {-16, 32},
  1005. {-16, 0},
  1006. {-16, -32},
  1007. {0, -32},
  1008. {16, -32},
  1009. {16, 0},
  1010. {16, 32},
  1011. };
  1012. KRegion* pRegionBase = &SubWorld[idxSubWorld].m_Region[idxRegion];
  1013. for (int i = -1; i < 8; i++)
  1014. {
  1015. KRegion* pRegion = NULL;
  1016. if (i < 0)
  1017. pRegion = pRegionBase;
  1018. else
  1019. {
  1020. if (pRegionBase->m_nConnectRegion[i] < 0)
  1021. continue;
  1022. pRegion = &SubWorld[idxSubWorld].m_Region[pRegionBase->m_nConnectRegion[i]];
  1023. }
  1024. if (pRegion == NULL)
  1025. continue;
  1026. KIndexNode *pNode = (KIndexNode *)pRegion->m_PlayerList.GetHead();
  1027. while(pNode)
  1028. {
  1029. // _ASSERT(pNode->m_nIndex > 0 && pNode->m_nIndex < MAX_PLAYER);
  1030. //if (FromRelayID != Player[pNode->m_nIndex].m_nNetConnectIdx)
  1031. {
  1032. int nTargetNpc = Player[pNode->m_nIndex].m_nIndex;
  1033. if (nTargetNpc > 0)
  1034. {
  1035. nTX = Npc[nTargetNpc].m_MapX + POff[i + 1].x;
  1036. nTY = Npc[nTargetNpc].m_MapY + POff[i + 1].y;
  1037. if ((nTX - nOX) * (nTX - nOX) + (nTY - nOY) * (nTY - nOY) < MAX_SYNC_RANGE * MAX_SYNC_RANGE)
  1038. g_pServer->PackDataToClient(Player[pNode->m_nIndex].m_nNetConnectIdx, pExHeader, pckgsize);
  1039. }
  1040. // pPlayers[pCgc->wPlayerCount] = (WORD)Player[pNode->m_nIndex].m_nNetConnectIdx;
  1041. // ++ pCgc->wPlayerCount;
  1042. //
  1043. // if (pCgc->wPlayerCount >= nMaxRelayPlayer)
  1044. // {
  1045. // size_t pckgsize = basesize + sizeof(WORD) * pCgc->wPlayerCount;
  1046. // pCgc->wSize = pckgsize - 1;
  1047. //
  1048. // pClient->SendPackToServer(pCgc, pckgsize);
  1049. //
  1050. // pCgc->wPlayerCount = 0;
  1051. // }
  1052. }
  1053. pNode = (KIndexNode *)pNode->GetNext();
  1054. }
  1055. }
  1056. // if (pCgc->wPlayerCount > 0)
  1057. // {
  1058. // size_t pckgsize = basesize + sizeof(WORD) * pCgc->wPlayerCount;
  1059. // pCgc->wSize = pckgsize - 1;
  1060. //
  1061. // pClient->SendPackToServer(pCgc, pckgsize);
  1062. // }
  1063. #ifndef WIN32
  1064. delete (char*)pExHeader;
  1065. #endif
  1066. }}
  1067. break;
  1068. case tgtcls_bc:
  1069. {{
  1070. size_t pckgsize = sizeof(tagExtendProtoHeader) + size;
  1071. #ifdef WIN32
  1072. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)_alloca(pckgsize);
  1073. #else
  1074. tagExtendProtoHeader* pExHeader = (tagExtendProtoHeader*)(new char[pckgsize]);
  1075. #endif
  1076. pExHeader->ProtocolType = s2c_extendchat;
  1077. pExHeader->wLength = pckgsize - 1;
  1078. memcpy(pExHeader + 1, pData, size);
  1079. int nTargetIdx;
  1080. nTargetIdx = PlayerSet.GetFirstPlayer();
  1081. while (nTargetIdx)
  1082. {
  1083. g_pServer->PackDataToClient(Player[nTargetIdx].m_nNetConnectIdx, pExHeader, pckgsize);
  1084. nTargetIdx = PlayerSet.GetNextPlayer();
  1085. }
  1086. #ifndef WIN32
  1087. delete ((char*)pExHeader);
  1088. #endif
  1089. }}
  1090. break;
  1091. default:
  1092. break;
  1093. }
  1094. return TRUE;
  1095. }
  1096. void CoreServerShell::SetLadder(void* pData, size_t uSize)
  1097. {
  1098. Ladder.Init(pData, uSize);
  1099. }
  1100. BOOL CoreServerShell::PayForSpeech(int nIndex, int nType)
  1101. {
  1102. if (nIndex <= 0 || nIndex >= MAX_PLAYER)
  1103. return FALSE;
  1104. int nMoney = 0;
  1105. int nNpcIdx = Player[nIndex].m_nIndex;
  1106. if (nNpcIdx <= 0)
  1107. return FALSE;
  1108. if (Player[nIndex].m_nForbiddenFlag & KPlayer::FF_CHAT) //被禁言
  1109. return FALSE;
  1110. int nLevel = Npc[nNpcIdx].m_Level;
  1111. int nMaxMana = Npc[nNpcIdx].m_CurrentManaMax;
  1112. switch (nType)
  1113. {
  1114. case 0: //免费
  1115. return TRUE;
  1116. break;
  1117. case 1: //10元每句
  1118. {
  1119. nMoney = 10;
  1120. return Player[nIndex].Pay(nMoney);
  1121. }
  1122. break;
  1123. case 2: //2: <10Lv ? 不能说 : MaxMana/2/句
  1124. {
  1125. if (nLevel < 10)
  1126. return FALSE;
  1127. return Npc[nNpcIdx].Cost(attrib_mana, nMaxMana / 2);
  1128. }
  1129. break;
  1130. case 3: //3: MaxMana/10/句
  1131. {
  1132. return Npc[nNpcIdx].Cost(attrib_mana, nMaxMana / 10);
  1133. }
  1134. break;
  1135. case 4: //4: <20Lv ? 不能说 : MaxMana*4/5/句
  1136. {
  1137. if (nLevel < 20)
  1138. return FALSE;
  1139. return Npc[nNpcIdx].Cost(attrib_mana, nMaxMana * 4 / 5);
  1140. }
  1141. break;
  1142. default:
  1143. return FALSE; //不认识的类别不发送
  1144. }
  1145. }